You are on page 1of 132

THE ULTIMATE BEGINNERS’ GUIDE TO CODING!

CODING
NE

MADE
SIMPLE
Learn how to program the easy and fun way
NEW
SKILLS
MASTER
SCRATCH &
PYTHON
Edition
Digital
EDITION
EIGHTH
CODING
MADE
SIMPLE
With the internet driving a new world of information exchange, business
start-ups and online gaming, coders have suddenly become the gatekeepers
to these new realms. Combine the huge interest in learning how to create
and control these worlds with the surge of cool devices, such as the
Raspberry Pi, and you’ve got a head of technological steam the world hasn’t
seen since the coding craze of the early 1980s. So no matter if you’re looking
to relive those heady ’80s coding days or are a newbie looking to take your
first steps into the coding world, you hold in your hands the ideal guide to
start coding. Thanks to a new generation of open free software, we all can
access operating systems, development tools, compilers and the
programming languages needed to create professional programs, apps and
tools. We’ll show you how to get up and running with a Linux system, then
access everything you need freely online. Coding is easy, exciting and fun.
We’ll explain the basics, move on to more advanced topics, explain how you
can use the Raspberry Pi, and provide you with fully updated exciting and
easy-to-follow projects. So what are you waiting for? Get coding!
This bookazine is printed on recycled paper. It’s important that
we care about our planet and make a difference where we can,
for us and every generation that follows.
CODING
MADE
SIMPLE
Future PLC Richmond House, 33 Richmond Hill,
Bournemouth, Dorset, BH2 6EZ

Bookazine Editorial
Editor Alex Cox
Art Editor Efrain Hernandez-Mendoza
Compiled by April Madden, Katharine Marsh
& Adam Markiewicz
Editorial Director Jon White
Senior Art Editor Andy Downes
Linux Format Editorial
Editor Neil Mohr
Art Editor Efrain Hernandez-Mendoza
Group Editor in Chief Graham Barlow
Senior Art Editor Jo Gulliver
Cover images
Shutterstock
Photography
All copyrights and trademarks are recognised and respected
Advertising
Media packs are available on request
Commercial Director Clare Dove
clare.dove@futurenet.com
International
Head of Print Licensing Rachel Shaw
licensing@futurenet.com
Circulation
Head of Newstrade Tim Mathers
Production
Head of Production Mark Constance
Production Project Manager Clare Scott
Advertising Production Manager Joanne Crosby
Digital Editions Controller Jason Hudson
Production Managers Keely Miller, Nola Cokely,
Vivienne Calvert, Fran Twentyman
Management
Chief Content Officer Aaron Asadi
Commercial Finance Director Dan Jotcham
Head of Art & Design Greg Whitaker
Printed by William Gibbons, 26 Planetary Road,
Willenhall, West Midlands, WV13 3XT
Distributed by Marketforce, 5 Churchill Place, Canary Wharf, London, E14 5HU
www.marketforce.co.uk Tel: 0203 787 9001
Coding Made Simple Eighth Edition
© 2019 Future Publishing Limited

All content previously appeared in


this edition of Coding Made Simple
We are committed to only using magazine paper which is derived from responsibly managed,
certified forestry and chlorine-free manufacture. The paper in this magazine was sourced
and produced from sustainable managed forests, conforming to strict environmental and
socioeconomic standards. The manufacturing paper mill and printer hold full FSC and PEFC
certification and accreditation.
All contents © 2019 Future Publishing Limited or published under licence. All rights reserved.
No part of this magazine may be used, stored, transmitted or reproduced in any way without
the prior written permission of the publisher. Future Publishing Limited (company number
2008885) is registered in England and Wales. Registered office: Quay House, The Ambury,
Bath BA1 1UA. All information contained in this publication is for information only and is, as far
as we are aware, correct at the time of going to press. Future cannot accept any responsibility
for errors or inaccuracies in such information. You are advised to contact manufacturers and
retailers directly with regard to the price of products/services referred to in this publication. Apps
and websites mentioned in this publication are not under our control. We are not responsible for
their contents or any other changes or updates to them. This magazine is fully independent
and not affiliated in any way with the companies mentioned herein.

Future plc is a public Chief executive Zillah Byng-Thorne


company quoted on the Non-executive chairman Richard Huntingford
London Stock Exchange Chief financial officer Penny Ladkin-Brand
(symbol: FUTR)
www.futureplc.com Tel +44 (0)1225 442 244
CODING
Contents

MADE DOWNLOAD
THE CODE AT

SIMPLE http://bit.ly/
codingmadesimple19

Contents
Scratch
Getting started with Scratch ������������������������������������������������������������������������ 10
Using variables in Scratch ���������������������������������������������������������������������������������� 12
Learn about Loops ������������������������������������������������������������������������������������������������������������������� 14
Using lists in Scratch ���������������������������������������������������������������������������������������������������������� 16
Build a game with Scratch ���������������������������������������������������������������������������������� 18
Scratch: Hack it �������������������������������������������������������������������������������������������������������������������������������� 22

Coding on Pi
Welcome to Pi �������������������������������������������������������������������������������������������������������������������������������������� 26
Coding in IDLE ������������������������������������������������������������������������������������������������������������������������������������� 28
Minecraft: Start hacking ���������������������������������������������������������������������������������������� 30
Minecraft: Image walls ������������������������������������������������������������������������������������������������� 32
Sonic Pi: Make some noise! ��������������������������������������������������������������������������� 36
Ruby: Compose music ���������������������������������������������������������������������������������������������� 40
Sonic Pi hardware control ���������������������������������������������������������������������������������� 42

Coding basics
Get started with Linux �������������������������������������������������������������������������������������������������� 46
Mint and Python ��������������������������������������������������������������������������������������������������������������������������� 50

6 | Coding Made Simple


Get started with IDEs 52

Contents
�������������������������������������������������������������������������������������������������������

Python lists ������������������������������������������������������������������������������������������������������������������������������������������������� 54


Functions & objects ������������������������������������������������������������������������������������������������������������� 56
Conditionals ���������������������������������������������������������������������������������������������������������������������������������������������� 58
Variables������������������������������������������������������������������������������������������������������������������������������������������������������������ 60
Building proper programs ���������������������������������������������������������������������������������� 62
Recursion �������������������������������������������������������������������������������������������������������������������������������������������������������� 64
Sorting algorithms ������������������������������������������������������������������������������������������������������������������ 66
Hidden secrets of numbers ��������������������������������������������������������������������������� 68
Using loops �������������������������������������������������������������������������������������������������������������������������������������������������� 70
The magic of compilers ���������������������������������������������������������������������������������������������� 72
Common coding mistakes �������������������������������������������������������������������������������� 74

Python
Types of Python data �������������������������������������������������������������������������������������������������������78
More Python data types ���������������������������������������������������������������������������������������� 80
Reliability by abstraction 82
�����������������������������������������������������������������������������������������

Files and modules �������������������������������������������������������������������������������������������������������������������� 84


Neater code with modules �������������������������������������������������������������������������������86
Storage and persistence ��������������������������������������������������������������������������������������� 88
Data organisation ����������������������������������������������������������������������������������������������������������������������90

Coding projects
Plot beautiful images �������������������������������������������������������������������������������������������������������94
Functionality of find ������������������������������������������������������������������������������������������������������������� 98
Programming wc in Python ���������������������������������������������������������������������� 102
MicroPython: Light glove ��������������������������������������������������������������������������������� 106
MicroPython: Robot wars �������������������������������������������������������������������������������� 110
Python: Build an Enigma box ����������������������������������������������������������������� 114
UPS: Power loss protection ������������������������������������������������������������������������ 118
Practical Python 3 modules �������������������������������������������������������������������� 120
Tkinter: Build a money app ������������������������������������������������������������������������ 124

Coding Made Simple | 7


erubyracer”, “~> 0.11.4” group :development, :test do gem “rspec-rails”, “~> 2.13.0” $ gem install bundler $ gem install rails --version=3.2.12 $ rbenv rehash $ rails
ate_attributes(params[:task]) format.html { redirect_to @task, notice: ‘...’ } format.json { head :no_content } else format.html { render action: “edit” } format.json { ren
xec rails generate migration add_priority_to_tasks priority:integer $ bundle exec rake db:migrate $ bundle exec rake db:migrate $ bundle exec rails server validate
_at, ‘is in the past!’) if due_at < Time.zone.now #!/usr/bin/en python import pygame from random import randrange MAX_STARS = 100 pygame.init() screen = py
tars = for i in range(MAX_STARS): star = [randrange(0, 639), randrange(0, 479), randrange(1, 16)] stars.append(star) while True: clock.tick(30) for event in pygame.
$numstars = 100; use Time::HiRes qw(usleep); use Curses; $screen = new Curses; noecho; curs_set(0); for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] = rand(80); $s
>clear; for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] -= $star_s[$i]; if ($star_x[$i] < 0) { $star_x[$i] = 80; } $screen->addch($star_y[$i], $star_x[$i], “.”); } $screen->refre
ment, :test do gem “rspec-rails”, “~> 2.13.0” $ gem install bundler $ gem install rails --version=3.2.12 $ rbenv rehash $ rails new todolist --skip-test-unit respond
tml { redirect_to @task, notice: ‘...’ } format.json { head :no_content } else format.html { render action: “edit” } format.json { render json: @task.errors, status: :unpro
rity_to_tasks priority:integer $ bundle exec rake db:migrate $ bundle exec rake db:migrate $ bundle exec rails server validate :due_at_is_in_the_past def due_at_is_
one.now #!/usr/bin/en python import pygame from random import randrange MAX_STARS = 100 pygame.init() screen = pygame.display.set_mode((640, 480)) c
star = [randrange(0, 639), randrange(0, 479), randrange(1, 16)] stars.append(star) while True: clock.tick(30) for event in pygame.event.get(): if event.type == pyg
Res qw(usleep); use Curses; $screen = new Curses; noecho; curs_set(0); for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] = rand(80); $star_y[$i] = rand(24); $star_s[$i]
rs ; $i++) { $star_x[$i] -= $star_s[$i]; if ($star_x[$i] < 0) { $star_x[$i] = 80; } $screen->addch($star_y[$i], $star_x[$i], “.”); } $screen->refresh; usleep 50000; gem “theru
ails”, “~> 2.13.0” $ gem install bundler $ gem install rails --version=3.2.12 $ rbenv rehash $ rails new todolist --skip-test-unit respond_to do |format| if @task.update_
.’ } format.json { head :no_content } else format.html { render action: “edit” } format.json { render json: @task.errors, status: :unprocessable_entity } $ bundle exec rails
exec rake db:migrate $ bundle exec rake db:migrate $ bundle exec rails server validate :due_at_is_in_the_past def due_at_is_in_the_past errors.add(:due_at, ‘is in th
ygame from random import randrange MAX_STARS = 100 pygame.init() screen = pygame.display.set_mode((640, 480)) clock = pygame.time.Clock() stars =
ge(0, 479), randrange(1, 16)] stars.append(star) while True: clock.tick(30) for event in pygame.event.get(): if event.type == pygame.QUIT: exit(0) #!/usr/bin/perl $nu
= new Curses; noecho; curs_set(0); for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] = rand(80); $star_y[$i] = rand(24); $star_s[$i] = rand(4) + 1; } while (1) { $screen-
$i]; if ($star_x[$i] < 0) { $star_x[$i] = 80; } $screen->addch($star_y[$i], $star_x[$i], “.”); } $screen->refresh; usleep 50000; gem “therubyracer”, “~> 0.11.4” group :dev
undler $ gem install rails --version=3.2.12 $ rbenv rehash $ rails new todolist --skip-test-unit respond_to do |format| if @task.update_attributes(params[:task]) forma

CODING
ent } else format.html { render action: “edit” } format.json { render json: @task.errors, status: :unprocessable_entity } $ bundle exec rails generate migration add_priori
exec rake db:migrate $ bundle exec rails server validate :due_at_is_in_the_past def due_at_is_in_the_past errors.add(:due_at, ‘is in the past!’) if due_at < Time.zon
andrange MAX_STARS = 100 pygame.init() screen = pygame.display.set_mode((640, 480)) clock = pygame.time.Clock() stars = for i in range(MAX_STARS): star =
pend(star) while True: clock.tick(30) for event in pygame.event.get(): if event.type == pygame.QUIT: exit(0) #!/usr/bin/perl $numstars = 100; use Time::HiRes qw(us
r ($i = 0; $i < $numstars ; $i++) { $star_x[$i] = rand(80); $star_y[$i] = rand(24); $star_s[$i] = rand(4) + 1; } while (1) { $screen->clear; for ($i = 0; $i < $numstars ; $i++)
creen->addch($star_y[$i], $star_x[$i], “.”); } $screen->refresh; usleep 50000; gem “therubyracer”, “~> 0.11.4” group :development, :test do gem “rspec-rails”, “~> 2.13.0
ehash $ rails new todolist --skip-test-unit respond_to do |format| if @task.update_attributes(params[:task]) format.html { redirect_to @task, notice: ‘...’ } format.json { h

MADE
son { render json: @task.errors, status: :unprocessable_entity } $ bundle exec rails generate migration add_priority_to_tasks priority:integer $ bundle exec rake db:m
alidate :due_at_is_in_the_past def due_at_is_in_the_past errors.add(:due_at, ‘is in the past!’) if due_at < Time.zone.now #!/usr/bin/en python import pygame from
een = pygame.display.set_mode((640, 480)) clock = pygame.time.Clock() stars = for i in range(MAX_STARS): star = [randrange(0, 639), randrange(0, 479), randrang
pygame.event.get(): if event.type == pygame.QUIT: exit(0) #!/usr/bin/perl $numstars = 100; use Time::HiRes qw(usleep); use Curses; $screen = new Curses; noecho;
0); $star_y[$i] = rand(24); $star_s[$i] = rand(4) + 1; } while (1) { $screen->clear; for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] -= $star_s[$i]; if ($star_x[$i] < 0) { $star_
>refresh; usleep 50000; gem “therubyracer”, “~> 0.11.4” group :development, :test do gem “rspec-rails”, “~> 2.13.0” $ gem install bundler $ gem install rails --versi

SIMPLE
ond_to do |format| if @task.update_attributes(params[:task]) format.html { redirect_to @task, notice: ‘...’ } format.json { head :no_content } else format.html { rende
unprocessable_entity } $ bundle exec rails generate migration add_priority_to_tasks priority:integer $ bundle exec rake db:migrate $ bundle exec rake db:migrate $
at_is_in_the_past errors.add(:due_at, ‘is in the past!’) if due_at < Time.zone.now #!/usr/bin/en python import pygame from random import randrange MAX_ST
40, 480)) clock = pygame.time.Clock() stars = for i in range(MAX_STARS): star = [randrange(0, 639), randrange(0, 479), randrange(1, 16)] stars.append(star) while Tru
pygame.QUIT: exit(0) #!/usr/bin/perl $numstars = 100; use Time::HiRes qw(usleep); use Curses; $screen = new Curses; noecho; curs_set(0); for ($i = 0; $i < $nums
$i] = rand(4) + 1; } while (1) { $screen->clear; for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] -= $star_s[$i]; if ($star_x[$i] < 0) { $star_x[$i] = 80; } $screen->addch($sta
erubyracer”, “~> 0.11.4” group :development, :test do gem “rspec-rails”, “~> 2.13.0” $ gem install bundler $ gem install rails --version=3.2.12 $ rbenv rehash $ rails
ate_attributes(params[:task]) format.html { redirect_to @task, notice: ‘...’ } format.json { head :no_content } else format.html { render action: “edit” } format.json { ren
xec rails generate migration add_priority_to_tasks priority:integer $ bundle exec rake db:migrate $ bundle exec rake db:migrate $ bundle exec rails server validate
_at, ‘is in the past!’) if due_at < Time.zone.now #!/usr/bin/en python import pygame from random import randrange MAX_STARS = 100 pygame.init() screen = py
tars = for i in range(MAX_STARS): star = [randrange(0, 639), randrange(0, 479), randrange(1, 16)] stars.append(star) while True: clock.tick(30) for event in pygame.
$numstars = 100; use Time::HiRes qw(usleep); use Curses; $screen = new Curses; noecho; curs_set(0); for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] = rand(80); $s
>clear; for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] -= $star_s[$i]; if ($star_x[$i] < 0) { $star_x[$i] = 80; } $screen->addch($star_y[$i], $star_x[$i], “.”); } $screen->refre
ment, :test do gem “rspec-rails”, “~> 2.13.0” $ gem install bundler $ gem install rails --version=3.2.12 $ rbenv rehash $ rails new todolist --skip-test-unit respond
tml { redirect_to @task, notice: ‘...’ } format.json { head :no_content } else format.html { render action: “edit” } format.json { render json: @task.errors, status: :unpro
rity_to_tasks priority:integer $ bundle exec rake db:migrate $ bundle exec rake db:migrate $ bundle exec rails server validate :due_at_is_in_the_past def due_at_is_
one.now #!/usr/bin/en python import pygame from random import randrange MAX_STARS = 100 pygame.init() screen = pygame.display.set_mode((640, 480)) c
star = [randrange(0, 639), randrange(0, 479), randrange(1, 16)] stars.append(star) while True: clock.tick(30) for event in pygame.event.get(): if event.type == pyg
Res qw(usleep); use Curses; $screen = new Curses; noecho; curs_set(0); for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] = rand(80); $star_y[$i] = rand(24); $star_s[$i]
rs ; $i++) { $star_x[$i] -= $star_s[$i]; if ($star_x[$i] < 0) { $star_x[$i] = 80; } $screen->addch($star_y[$i], $star_x[$i], “.”); } $screen->refresh; usleep 50000; gem “theru
ails”, “~> 2.13.0” $ gem install bundler $ gem install rails --version=3.2.12 $ rbenv rehash $ rails new todolist --skip-test-unit respond_to do |format| if @task.update_
.’ } format.json { head :no_content } else format.html { render action: “edit” } format.json { render json: @task.errors, status: :unprocessable_entity } $ bundle exec rails
exec rake db:migrate $ bundle exec rake db:migrate $ bundle exec rails server validate :due_at_is_in_the_past def due_at_is_in_the_past errors.add(:due_at, ‘is in th
ygame from random import randrange MAX_STARS = 100 pygame.init() screen = pygame.display.set_mode((640, 480)) clock = pygame.time.Clock() stars =
ge(0, 479), randrange(1, 16)] stars.append(star) while True: clock.tick(30) for event in pygame.event.get(): if event.type == pygame.QUIT: exit(0) #!/usr/bin/perl $nu
= new Curses; noecho; curs_set(0); for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] = rand(80); $star_y[$i] = rand(24); $star_s[$i] = rand(4) + 1; } while (1) { $screen-
$i]; if ($star_x[$i] < 0) { $star_x[$i] = 80; } $screen->addch($star_y[$i], $star_x[$i], “.”); } $screen->refresh; usleep 50000; gem “therubyracer”, “~> 0.11.4” group :dev
undler $ gem install rails --version=3.2.12 $ rbenv rehash $ rails new todolist --skip-test-unit respond_to do |format| if @task.update_attributes(params[:task]) forma
ent } else format.html { render action: “edit” } format.json { render json: @task.errors, status: :unprocessable_entity } $ bundle exec rails generate migration add_priori
exec rake db:migrate $ bundle exec rails server validate :due_at_is_in_the_past def due_at_is_in_the_past errors.add(:due_at, ‘is in the past!’) if due_at < Time.zon
andrange MAX_STARS = 100 pygame.init() screen = pygame.display.set_mode((640, 480)) clock = pygame.time.Clock() stars = for i in range(MAX_STARS): star =
pend(star) while True: clock.tick(30) for event in pygame.event.get(): if event.type == pygame.QUIT: exit(0) #!/usr/bin/perl $numstars = 100; use Time::HiRes qw(us
r ($i = 0; $i < $numstars ; $i++) { $star_x[$i] = rand(80); $star_y[$i] = rand(24); $star_s[$i] = rand(4) + 1; } while (1) { $screen->clear; for ($i = 0; $i < $numstars ; $i++)
creen->addch($star_y[$i], $star_x[$i], “.”); } $screen->refresh; usleep 50000; gem “therubyracer”, “~> 0.11.4” group :development, :test do gem “rspec-rails”, “~> 2.13.0
s new todolist --skip-test-unit respond_to do |format| if @
nder json: @task.errors, status: :unprocessable_entity } $
:due_at_is_in_the_past def due_at_is_in_the_past errors.

Scratch | Contents
ygame.display.set_mode((640, 480)) clock = pygame.time.
e.event.get(): if event.type == pygame.QUIT: exit(0) #!/usr/
star_y[$i] = rand(24); $star_s[$i] = rand(4) + 1; } while (1) {
esh; usleep 50000; gem “therubyracer”, “~> 0.11.4” group
d_to do |format| if @task.update_attributes(params[:task])
ocessable_entity } $ bundle exec rails generate migration
_in_the_past errors.add(:due_at, ‘is in the past!’) if due_at
clock = pygame.time.Clock() stars = for i in range(MAX_

Scratch
game.QUIT: exit(0) #!/usr/bin/perl $numstars = 100; use
= rand(4) + 1; } while (1) { $screen->clear; for ($i = 0; $i <
rubyracer”, “~> 0.11.4” group :development, :test do gem
_attributes(params[:task]) format.html { redirect_to @task,
s generate migration add_priority_to_tasks priority:integer
he past!’) if due_at < Time.zone.now #!/usr/bin/en python
for i in range(MAX_STARS): star = [randrange(0, 639),
Learn the basics of coding with
umstars = 100; use Time::HiRes qw(usleep); use Curses; the visual programming language
->clear; for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] -=
velopment, :test do gem “rspec-rails”, “~> 2.13.0” $ gem
at.html { redirect_to @task, notice: ‘...’ } format.json { head Getting started with Scratch 10
������������

ity_to_tasks priority:integer $ bundle exec rake db:migrate


ne.now #!/usr/bin/en python import pygame from random Using variables in Scratch 12
���������������������

= [randrange(0, 639), randrange(0, 479), randrange(1, 16)]


sleep); use Curses; $screen = new Curses; noecho; curs_
Learn about Loops 14
�������������������������������������������������������

) { $star_x[$i] -= $star_s[$i]; if ($star_x[$i] < 0) { $star_x[$i]


0” $ gem install bundler $ gem install rails --version=3.2.12
Using lists in Scratch 16
����������������������������������������������

head :no_content } else format.html { render action: “edit” Build a game with Scratch 18
����������������������
migrate $ bundle exec rake db:migrate $ bundle exec rails
m random import randrange MAX_STARS = 100 pygame. Scratch: Hack it 22
��������������������������������������������������������������������
ge(1, 16)] stars.append(star) while True: clock.tick(30) for
; curs_set(0); for ($i = 0; $i < $numstars ; $i++) { $star_x[$i]
_x[$i] = 80; } $screen->addch($star_y[$i], $star_x[$i], “.”); }
ion=3.2.12 $ rbenv rehash $ rails new todolist --skip-test-
er action: “edit” } format.json { render json: @task.errors,
$ bundle exec rails server validate :due_at_is_in_the_past
TARS = 100 pygame.init() screen = pygame.display.set_
ue: clock.tick(30) for event in pygame.event.get(): if event.
stars ; $i++) { $star_x[$i] = rand(80); $star_y[$i] = rand(24);
ar_y[$i], $star_x[$i], “.”); } $screen->refresh; usleep 50000;
s new todolist --skip-test-unit respond_to do |format| if @
nder json: @task.errors, status: :unprocessable_entity } $
:due_at_is_in_the_past def due_at_is_in_the_past errors.
ygame.display.set_mode((640, 480)) clock = pygame.time.
e.event.get(): if event.type == pygame.QUIT: exit(0) #!/usr/
star_y[$i] = rand(24); $star_s[$i] = rand(4) + 1; } while (1) {
esh; usleep 50000; gem “therubyracer”, “~> 0.11.4” group
d_to do |format| if @task.update_attributes(params[:task])
ocessable_entity } $ bundle exec rails generate migration
_in_the_past errors.add(:due_at, ‘is in the past!’) if due_at
clock = pygame.time.Clock() stars = for i in range(MAX_
game.QUIT: exit(0) #!/usr/bin/perl $numstars = 100; use
= rand(4) + 1; } while (1) { $screen->clear; for ($i = 0; $i <
rubyracer”, “~> 0.11.4” group :development, :test do gem
_attributes(params[:task]) format.html { redirect_to @task,
s generate migration add_priority_to_tasks priority:integer
he past!’) if due_at < Time.zone.now #!/usr/bin/en python
for i in range(MAX_STARS): star = [randrange(0, 639),
umstars = 100; use Time::HiRes qw(usleep); use Curses;
->clear; for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] -=
velopment, :test do gem “rspec-rails”, “~> 2.13.0” $ gem
at.html { redirect_to @task, notice: ‘...’ } format.json { head
ity_to_tasks priority:integer $ bundle exec rake db:migrate
ne.now #!/usr/bin/en python import pygame from random
= [randrange(0, 639), randrange(0, 479), randrange(1, 16)]
sleep); use Curses; $screen = new Curses; noecho; curs_ Coding Made Simple | 9
) { $star_x[$i] -= $star_s[$i]; if ($star_x[$i] < 0) { $star_x[$i]
0” $ gem install bundler $ gem install rails --version=3.2.12
Scratch | Getting started

Getting started
with Scratch
New to coding? Scratch is the ideal language to begin with, and in this guide
we show you how to get started and learn some basic coding principles.

L
earning to code can be tough but thanks to Scratch it such as a key press. Hat blocks will only accept blocks
is now much easier to build your own games and underneath them, as an event typically triggers a sequence of
projects. Scratch was created by MIT in 2002 and later code. Other blocks are C blocks, used for loops and
released to the public in 2005. It has since become the first conditional tests, such as “If..Else”. C blocks enable the coder
coding language many children around the world learn. In the to place blocks inside them, and these blocks will run based
UK Scratch was made popular via Code Clubs, after school upon the type of C block used. So, any code contained in a
clubs for children lead by volunteers in the tech community. It forever loop will run forever, while any code in a conditional
soon entered the school curriculum and children as young as test will run if the condition is true. Other types of blocks
six are taught how to construct simple sequences of code by include the hexagonal Sensing blocks which are used to give
using metaphors such as making a sandwich or sprites basic collision detection and respond to sensor inputs
programming a simple robot toy known as a Bee Bot. This such as cameras and microphones.
practical knowledge is then put into practice using Scratch as All of these give us the basic building blocks of
a foundation. Children learn the basics of computer science computer science, such as sequence, iteration and selection,
by building their own games, applications and animations and we can build quite complex projects using them. Thanks
using this simple language made of blocks. to Scratch’s easy to use interface and the ability to
Scratch uses a block interface to build sequences of code deconstruct larger problems into small, easy to manage,
for objects, known as sprites, that can be controlled in many portions we have a tool perfect for children who want to just
different ways using these blocks of code. These sprites are “get on” with making something fun, rather than explicitly
visible upon a ‘Stage’ where interactions with the user learn how to code.
happen. A sprite can be moved, rotated, made to change In this first tutorial we shall get to grips with creating a
colour, or resized. Sprites are actors that we can tell what to simple project that enables us to learn how to work with the
do on the stage and they do it all using simple blocks of code. Scratch interface and understand how some of the common
Coding with Scratch is really simple. Blocks are dragged blocks work to produce a project that greets the player based
from the palette and are placed into a large coding area on on their name which can be used in future games to identify
the right of the screen. There are many different types of the players in a multi player game.
blocks. For example there are hat blocks, commonly used for So to begin open a web browser to http://scratch.mit.edu
events such as starting the programme or reacting to input and click on Try it Out to begin a new Scratch session.

The Scratch
interface is
designed for
children to just
get going with
their creations.
The colour coded
blocks and clear
interface enable
children to focus
on building their
ideas.

10 | Coding Made Simple


Scratch | Getting started
Building our project

1 Learning the layout 2 Building the code


Scratch has three main sections. First we see the Stage, which is Our code is based upon coloured blocks that are organised into a
where our projects will come to life. In the screenshot above we can series of sections, based upon their function. To write a programme
see the default Cat sprite. Under the Stage we see a list of sprites, we select the correct block and drag it into the large grey coding area.
which are the objects that we can programme. Next to here we can We can then build a sequence of code by attaching the blocks
see our palettes of blocks that make up the language. These can be together. This sequence is commonly referred to as an algorithm and
dragged to the large grey coding area. is being taught to children as young as 7.

3 Building our first programme. 4 Inside the loop


Let’s get used to Scratch by creating a simple project that asks for Our forever loop runs the code contained within it until the end of
our name and then reacts according to the name of the person. Our time (or you stop the program). Our next block is in Sensing and is
first block is found in Events and is called When Green Flag Clicked. called ask ______ and wait. Drag this inside the loop and type the
This is a hat block and only allows blocks to attach underneath it. Our question. Next, grab an If block from Control. This block checks a
next block is in Control and is called forever. This is a C block, condition, in this case the name stored in a variable called answer,
otherwise known as a loop. which is a block in the Sensing palette.

5 Conditionals 6 More Conditions


To check that the name of the person is known, we need to use the To add more names to our project we need to add more conditions to
_=_ block from Operators. This checks the name entered against a test. Here we use an If..Else block from Control to check for another
known name. Next we go to the Looks palette and select the Say name. We use the Else condition to respond to any unknown names.
hello for 2 secs block and place it inside the If condition. We then use Once you have completed the code, click on the Green flag, in the top
join from Operators to greet the user by name. right of the Stage, to launch the code. ■

Coding Made Simple | 11


Scratch | Using variables

Using variables
in Scratch
Learning about variables and data storage is easy in Scratch, and it
can help you build a simple number guessing game.

O
ver the course of computer history, data storage
has seen many forms, from the humble tape, to
magnetic disks, to CD/ DVD discs. But data storage
doesn’t just mean hard disks, flash drives or The Cloud.
Rather data storage means storing different data types in
many different ways. When it comes to coding, data types are
primarily organised into three groups: strings, integers and
floats. A string is a line of text, which can also contain
numbers, which cannot be used for any mathematical
operations. In Scratch we use strings to communicate with
the user, for example we use say to ask the user a question.
Integers are numbers that have no decimal place and
Floats are numbers with a decimal place. But in relation to
variables why are these important? Well, variables are used to
store these data types, as they are boxes in to which we can
place objects (such as our data). We then name the box so
that every time we say the name of the box, its contents
are revealed.
Comparing In this tutorial we use one data type, integers, with two
variables, one variables. Firstly we create a variable called Rand_Number
generated by a
which is used to store a randomly generated integer between
user, the other
1 and 100. We then use the ask block to ask the user to try Scratch code can get a little complicated, but remember
by a computer
is a great way to
and guess the number. Each guess is stored as a variable that you can take your code apart and examine each block
demonstrate how called answer which is part of the Sensing palette blocks.
they can be used Then, using a conditional test we check the value of the two is too high. If their answer is lower than the Rand_Number
in games and variables against one another. If the answer given is higher then they are told it is too low.
their logic than the Rand_Number then the user is told that their guess Variables are a key skill to learn in computer science as
they have far reaching applications. We see variables all
around us: timers, scores, player names in video games, timer
durations for digital cameras and user names when logging
into websites. Variables can be used to replace hard values in
projects. For example, rather than change the values of 10 or
more lines that repeat the same information, we can just refer
to a variable that we change once, and that change is
reflected across all 10 (or more) lines of code.
Scratch introduces variables using the Data palette, and
here we can create variables for individual sprites. For
example, individual scores for each team in a football game.
Or we can create a variable for all sprites such as a simple
timer for a game. We can alter the contents of a variable using
the set and change blocks. Set is used to change a value to a
specific value, such as going from 1 to 9. Change is used to
increase or decrease a variable by a numerical value, such as
changing the value of a variable from 9 to 8 by subtracting 1
from the variable.
So let’s start our project by opening http://scratch.mit.
edu and clicking ‘Try It Out’ to start a new Scratch window. If
you get anything wrong, pull the code apart and try again.

12 | Coding Made Simple


Scratch | Using variables
Creating a number game

1 Starting the project 2 Random Number Generation


We start the code with a When space key pressed block from Our Rand_Number variable needs a random number generator.
Events. This will trigger our code to run. Under this block we add say Thankfully Scratch has one of those in Operators. Drag pick random
from the Looks palette. Replace hello with the correct question. Next 1 to 10 and place it in the set Rand_Number block, and change the
we create a variable in the Data palette called Rand_Number and values to 1 to 100. Next go to the Control palette and drag repeat 10
then drag the set Rand_Number block and connect it to the bottom so that it connects under our previous blocks. Change repeat 10 to
of the last block. repeat 3.

3 Inside the loop. 4 Conditions for all


We now need to grab an ask block from the Sensing palette and Our first condition to test is If the answer given by the user matches
change the question to ‘ask for a guess’. This will create a special our Rand_Number. If it is correct then we move to the loop inside,
variable called answer that resides in Sensing. We now need to drag which is run if a correct answer is given. In this case it uses another
If..Else from Control and place it inside the repeat 3 loop. Next drag say block from Looks, to tell the user that they’ve won. The next block
the = block from Operators and place it in the hexagon shape. stop all, from Control, will stop all of the code running.

5 More conditions 6 Final Steps


We now need to go back to Control and drag two If blocks and place For our final step we add a say block to each if condition which will tell
them inside the else condition. This will give us two more conditions the user if their guess is too high or low. With the code complete,
to test. We shall use two new operators, one for each condition. The press your spacebar and your code will now run, and Scratch the cat
first is > and the other is < both from the operators palette. We will ask you to guess a number. You can also see the number in the
repeat the same input test but check if the guess is higher or lower top left of the stage, to turn this off go to Data and remove the tick
than the Rand_Number. next to Rand_Number. ■

Coding Made Simple | 13


Scratch | Learn about loops

Learn about
Loops
Loops are a fundamental part of coding, and Scratch can show you how they
work and why they are so important.

L
oops are one of the most basic pieces of logic in Bass instrument to produce four notes in rapid succession.
programming. They enable our projects to run Scratch calls this loop a repeat loop and it can be edited so
autonomously, iterate and check the condition of an that the loop only goes round a certain number of times. In
object such as a variable. In this tutorial we shall create our Python this loop is achieved using a for loop.
own musical showcase using three forms of loops, and some Our last loop is known as repeat until and this loop
secret keyboard accompaniment from the user, using the iterates in much the same way as repeat but it can be used
Scratch coding language. Our stage has a concert backdrop to check the status of an object such as a variable or
and three instruments upon it. condition. While the condition is False, the loop continues to
Our first instrument is a drum which provides a beat for our repeat. But as soon as the condition is True, the loop will end.
music. This beat is controlled using a forever loop. As its We use it to check the status of a variable called counter and
name implies, this is a loop that will run its contents forever. A while the value of this variable does not equal 4, the contents
forever loop is primarily used to constantly run a sequence of of the loop will be executed. But one of the blocks inside the
blocks, such as checking the value of a sensor or to drive a loop adds 1 to the value of the counter variable, essentially
robot onwards. This type of loop is the most basic yet iterating the loop until it reaches 4. This loop is also useful
fundamental loop to learn. It’s used throughout industries to when we are working with text, say the name of a user. We
constantly repeat a sequence. For example a car production can repeat questions to the user until they provide us with the
line is one giant forever loop: raw materials go in, they are correct name.
processed in a sequence (consider it an algorithm), and then Scratch visualises loops as C blocks and the code that
at the end a new car comes out. The loop then repeats itself, runs in a loop actually resides inside the loop, giving us a
producing more cars. Moving forward this loop is also present clear view of what we expect to happen when a loop is run.
in another programming language: Python. In Python the This is ideal for children as their expectations rarely match
loop goes by the name while true but it works in the same the actual results.
manner as forever. When using Scratch to introduce loops we can help
There are other types of loops. For example, say we only children to match their expectations to the actual results and
wanted four cars. This is where an iterative loop becomes adapt their code accordingly.
useful. These loops will iterate by running for a set number of So lets start our tutorial by opening http://scratch.mit.
times, before finally ending. We use this type of loop with our edu in our web browser and click on Try It Out.

There are so
many blocks
of code in this
tutorial that even
the stage has six
secret sequences
of code that
react to the
player typing on
the keyboard.

14 | Coding Made Simple


Scratch | Learn about loops
Going loopy!

1 Dressing the stage 2 New Sprites


Our stage can have many backdrops, click on the New Backdrop icon We now add a new sprite. Click on the New Sprite icon, and from the
under the Stage to change. A new menu will appear showing all of the list of sprites click on the Music theme and select Drum1. Repeat this
backdrops, select Indoors and spotlight-stage followed by OK. The step for two more sprites: Bass and Trumpet.
coding area will now change to show an image editor. Click on Scripts, Now delete the Cat sprite by right-clicking on the sprite icon in the
in the top centre of the screen to return. Now using blocks from Sprites area and select Delete. Next click on Drum1 to highlight the
Events create the code shown above for keyboard input. sprite ready for our code.

3 Looping Forever 4 Repeats...Repeats


Triggered by the When this sprite clicked code block from the We now focus on our Bass sprite. Scratch has a Repeat 10 loop that
Control section, our first loop for Drum1 is a simple Forever loop, also will repeat the contents 10 times. Drag this block from Control and
found in the Control palette. We shall now go to the Sound palette add when this sprite clicked from Events on top. Change the repeat
and look for the play sound ___ code block. It contains an incorrect to 4 and inside the loop introduce play sound. Using the dropdown
sound, so look to the Sounds tab and click on the speaker icon. Select change the pitch of the note. Next add rest for 0.25 beats to cause a
drum bass1 then return to Scripts and drag the block across. short delay between notes.

5 Repeat until... 6 Final Steps


Now we can work on our Trumpet sprite. First we need when this We now add play sound from Sound inside the loop, and add a rest
sprite clicked from Events. Next we click on Data then Make a for 0.25 beats to create a short delay.
Variable, and call the variable counter. Now grab set counter to 0 Lastly we add change counter by 1 from Data. This will add 1 to
and connect it to our code. Then go to Control and drag repeat until the variable each time it is run. When we reach four loops of the
and place it under the blocks. Now drag = from Operators and sequence it will automatically stop. Now click on the Green Flag icon
counter from Data and make the sequence shown above. to play your music. ■

Coding Made Simple | 15


Scratch | Using lists

Using lists in
Scratch
In this guide we’ll learn about lists by creating a simple shopping list program
using the visual Scratch language.

T
he world is full of lists. In school we had a register
taken every morning to ensure that we were present.
At work we use to do lists to ensure we are working at
peak efficiency. At NASA they use a checklist to ensure that
the launch goes smoothly.
Lists are powerful tools in the hands of a computer
scientist. But how can we understand them and then
introduce them into our coding projects without them
becoming scary? Well with the Scratch coding language we
can create lists and alter them at will, all while seeing their
contents in real time.
This will help us get a better understanding of what lists
do, and why they can be so important when we build our own
programs and games.
A list is a data storage tool that can store multiple items of
data. Each data item is given a position in the list, just like
children in a school register are sorted alphabetically by their
surname. This is called an index, and each item in a list can
be referred to by its index number, starting at zero. A simple shopping list is used to demonstrate the power
Data in a list can be manipulated in a number of ways. of lists and how they can be harnessed to create data.
First we can add items to a list, and typically we append those
items to the end of a list, growing the list each time we add it enters and leaves the list. Using Scratch to demonstrate
Editing sprites
another. We can also insert or replace data in a particular lists is a great primer for those just starting with languages
is a quick and
place in the list by stating the index number. such as Python, as they can see the list and learn how to
easy way to add
interest to your
So, we can add items to a list, but we can also delete items manipulate it using Scratch’s coding blocks and then apply
project. You can from a list, either individually or by deleting the entire that knowledge with a more traditional typed language.
resize, recolour contents of a list in one action. For our tutorial we have created a simple shopping list that
and edit any Scratch introduces lists in a simple and easy-to- demonstrates how data is entered and deleted from a list.
sprite to fit in understand manner, as we can see the contents of the list as Our green button triggers a question to the user:“What do we
with your project. a graphic in the top left of the Stage, letting us see the data as need?”. This is then saved as a special variable called answer
which is then added to our shopping list. For a bit of user
feedback and fun we add a sound to indicate that the button
has been pressed. Our blue button is a little more complex. It
reacts to a user click and creates a variable called z. We next
say to the user “So we need” before entering into a repeat
until loop. This loop will check the value of z against the
length of shopping list. Once the value of z is greater than the
length of shopping the loop will exit. Inside of the loop we play
a sound to grab the attention of the user. Then we read each
item in the list, one by one. Our last step in the loop is to
iterate, by adding 1, to our z variable so that our loop only
iterates a set number of times.
Our final button is the red button. This is a simple
sequence of code that is kicked off by clicking the button. We
play a quick sound as feedback to the user before deleting all
of the items in the shopping list.
So let’s begin our project, open your web browser to
http://scratch.mit.edu and click on Try it Out.

16 | Coding Made Simple


Scratch | Using lists
Writing our shopping list

1 Creating buttons 2 Creating a list using the green button


We need three buttons for our project. The green button can be Our first step is to create a list. Click on Data and then Make a List.
found as a sprite in the Sprite Library. Once you have the button, right Call the list Shopping. Now with the Green button selected we need
click on the sprite and select Duplicate twice. For each of the to use the when this sprite clicked code blockfrom Events, then use
duplicates click on Costumes and change their colours. We used Red, Play Sound from Sounds and give it a sound to grab the user’s
Green and Blue. We also created three more sprites that are simple attention. Add an ask block from Sensing, then use add thing to
text boxes to identify button functions. shopping from Data and replace thing with answer from Sensing.

3 Reading a list using the blue button 4 Reading items in a list


We start with when this sprite clicked from Events. Then we create With our blue button still highlighted we now write the code that sits
a variable called z using the Data blocks. Then using a say block we inside the repeat until loop. This code starts by playing a sound from
talk to the user. Now we use a repeat until block from Control. The Sounds. Then we use say from Looks along with item 1 of the
condition that we wish to test is constructed using > from Operators shopping block from Data. Then we drag our z variable into the space
and then checking to see if the value of z is greater than the length of where 1 is displayed. Next we add change z by 1 to iterate the loop.
our shopping list Lastly outside of the loop we add the stop all sound playback block.

5 Deleting the list with the red button 6 Testing our list
Deleting a list is rather easy. Our red button is used to delete every With our list completed we now need to click on the green button to
item in a list. So we need when this sprite clicked from Events. We add items to our shopping list. Blue enables us to read the list, and
then play a sound from Sounds to indicate that the button is red deletes the list. All the time we can see the contents of the list in
activated. Then we use delete all of shopping from Data to remove the top left of the screen. This can be turned on and off by using the
every item from our shopping list. tick next to shopping block in the Data palette. ■

Coding Made Simple | 17


Scratch | Create a game

Build a game
with Scratch
We now combine what we’ve learnt in the previous tutorials and use Scratch
to create a game that encompasses lots of computer science.

M
aking games is something that Scratch excels at the value of change score by 1 so that it changes the value
and we can learn lots about computer science from by 10. Our next block is called switch costume to. A costume
creating one. In this project we shall learn how to can change the appearance of a sprite. It can be used for
build a sci-fi shooting game controlled by the mouse. Our goal animation, such as a simple walking animation, or it can be
is to score lots of points to defeat the evil aliens. While we used to alter a sprite after an event has happened. In our
build the game we shall revisit the skills learnt over the project we shall use a different costume for our spaceship to
previous tutorials. represent an explosion. Click on the Costumes tab in the top
We start the project by visiting http://scratch.mit.edu centre of the screen. Next click on the “Choose costume from
in our web browser and clicking on Try it Out to load the library” and select the Holiday theme to reduce the number
Scratch editor. of options. Now look for the star3 sprite, select it and click Ok
to close the library. The screen will now show an editor, and a
Coding our spaceship list of three costumes in the centre of the screen. We only
Our project begins by adding a few new sprites. You can easily need costumes for spaceship-a and star-3a so right-click on
identify the New Sprite icon, as it looks like a small cartoon the remaining costume and select delete to remove it. Once
character, just underneath the Stage. We’ll use a Spaceship complete click on Scripts to return to the coding area. Now in
sprite, which can be found in the Sprite Library under the our code we need to edit switch costume to so that it
theme Space. Naturally our spaceship faces upwards, but we switches to star3-a. We then use a wait 1 secs block from
need to rotate our spaceship 90 degrees clockwise. To do this Control to show the costume change, before we use another
look to the sprite box underneath the Stage. Click on our switch costume to and revert back to spaceship-a. So our
spaceship sprite and you will see an “i” in the top left of the code for this sequence should looks as follows:
sprite. Click on this “i” and a new list of options appears. We When this sprite clicked
need to change the direction of the spaceship so that it faces Change score by 10
180 degrees. When done, click on the blue arrow icon to Switch costume to star3-a
return to the Sprite box. We now need to import three more Wait 1 secs
Quick sprites. They are robot,Tera and Button2. Repeat the import Switch costume to spaceship-a
tip process for these sprites and then click on Spaceship to Our last section of code for this sprite handles the basic
Writing lots of ensure that we are writing code for this sprite. movement of our spaceship. It glides across the screen at
code can be time With our Spaceship sprite selected we can now start various speeds and to random co-ordinates. But if it collides
consuming. But
writing the code that will control this sprite. Our first task is to
in Scratch we can
duplicate code create a variable called score. To create a variable click on the
and sprites by Data palette and select Make a Variable. Name the variable as
right clicking on score and click Ok. Now Drag change score to 0 from the
them and selecting
Data palette onto the coding area. Now go to Events and drag
duplicate. We can
also copy code when green flag clicked and place on top of set score to 0.
sequences across So now your blocks should look like this
sprites by dragging When Green Flag Clicked
the code over the Set score to 0
sprite.
We now create a new sequence of code, but we are still
working on the Spaceship. This sequence is a reaction to the
spaceship being clicked, in other words we are shooting at it!
We start with when this sprite clicked which can be found in
the Events palette. Now that we have a trigger we need to
write the code that will execute when that happens. Go to
Data and drag the change score by 1 code block and attach Our stage has three blocks of code that handle
it underneath when this sprite clicked. We need to update background music and control a timer for our game.

18 | Coding Made Simple


Scratch | Create a game
with another sprite, in this case a robot, it reduces in size,
making it harder to hit. This section of code has an unusual
trigger. In this sequence we use broadcast which is a means
of communicating to multiple sprites using one message. Go
to the Events palette and click on the dropdown arrow for the
when I receive block and select New Message. Call the new
message start and then click Ok. We now have a block that
reads When I receive start. drag this block to the coding
area to start our third and final section of code. The next block
that we need is switch costume to from Looks, and we need
to change the costume using the dropdown option so that it
shows spaceship-a. Drag this block so that it connects
underneath our when I receive block. We now drag a forever
block from Control and place it underneath the other blocks.
Our next block is called If and we can find it inside the Control
palette. Place this block inside the forever loop.
We now have a sequence that once triggered by the
broadcast will check to see if a condition has been met. But
what is the condition? For this we go to Sensing and drag
touching ___ and place it inside the hexagon shaped space in
our If block. For this new block we need to change the
dropdown so that it says touching robot. Inside the first
action, which is what will happen if the spaceship is touching This sprite has two sections of code: one to react to being Our Space
the robot, we drag the set size to __% block from Looks. shot at, and the other to control where and how the robot War game sees
Change the value so that it shrinks the spaceship to 10% of moves. So let’s start with the reaction code. us do battle
with evil space
its normal size. We now move to the Else portion of the Our robot sprite has a similar when the sprite clicked
alien robots and
conditional test. Here we use a glide 1 secs to x:__ y:__ block sequence that reacts to being clicked (shot) at by the player.
their infernal
from Motion, but rather than have fixed values for the x,y So in order to have this functionality for the robot we need to
spaceships inside
coordinates, we use two pick random blocks from Operators. recreate the blocks. But our score block will only change the a time tunnel!
Drag these into the spaces for our glide block and enter the value of our score variable by 5 points, as our robot will be
values x: -240 to 240 y: -180 to 180. This will cover every easier to hit. We also use costume star3-a to signify that the
position on the stage. Now we add our last block for this robot has been destroyed. The rest of the code for this
sequence and for this sprite. Our last block is another set sequence matches our spaceship. Here’s the code in full:
size to % from Looks but this time set it to 35%. So right When this sprite clicked
now our third and final sequence of code for the spaceship Change score by 5
sprite looks like this: Switch costume to star3-a
When I receive start Wait 1 secs
Switch costume to spaceship-a Switch costume to robot1
Forever Our second and last section of code for the robot controls
If touching robot ? then its movement. This is essentially the same code as that used
Set size to 10% on the spaceship, but there is no conditional test to check if
Else the robot has touched any sprites. So we start the sequence
Glide 1 secs to x: pick random -240 to 240 y: pick by using when I receive start from Events before we then
random-180 to 180 use the switch costume to block from Looks. We need to
Set size to 35% ensure that the costume change reverts the robot to robot1.
Our next block iintroduces a forever loop under the other
Coding our robot blocks in the sequence. Inside this loop we reuse the glide
Earlier we imported a robot sprite into our game and now the block that we used to animate the spaceship previously. This
time has come to give our robot intelligence! includes our random coordinates system to enable the robot
In the Sprites box, ensure that your robot sprite is selected. to glide to random points around the stage.

The Cloud
Scratch has come a long way and now it offers a By posting your work online to the Scratch Crossy Road or Pac Man? Well, fellow
method for “Scratchers” (that’s Scratch coders) cloud, you have the choice of keeping your work Scratchers have and you can see their code and
to create their own projects and store them secret and continuing your project, But once the incorporate it into your own projects. This great
online. The service is free of charge and enables time is right, you can unleash your projects to feature means that we can all remix and
users to access their work from any computer. the world by making them public. So now republish games and projects with new and
This is really handy for schools where children players around the world can sample your game, exciting features.
can be set homework using Scratch, which is but they can also see the code that makes your So now you and your friends can make cool
then autosaved as the child works. So no more game, and this is the exciting bit! Have you ever games and share, learn and remix to make the
“the dog ate my homework” situations. wanted to make your own version of Flappy Bird, ultimate video game!

Coding Made Simple | 19


Scratch | Create a game
short piece of text to the variable score, and this will give us a
more refined way of presenting the score. So we need to use
join hello world from Operators and place it inside the text of
the say block. Change the first section of text so that it reads
“Your score was “. For the second space we will go to the Data
palette and select the score block and place it into the space.
Our last block for this sequence and sprite is to go to Sounds
and use a play sound ___ until done. Remember that we
can import sounds using the Sounds tab in the top centre of
the screen. Choose an appropriate sound to play after your
score is read. We chose to play an applause sound.
Here is the complete code for this sequence.
When I receive scoreboard
Show
Say [join (Your score was) (score)] for 2 secs
Play sound clapping until done

Start Button
Our final sprite is the simplest of all. Our start button is used
Our spaceship Here is the complete code for this sequence: to trigger the game, so at the start of the game it is visible,
has lots of code, When I receive start only disappearing once the user clicks upon it.
but it is broken
Switch costume to robot1 This sprite has two sequences of code. The first is a simple
down into three
Forever reveal once we start Scratch. To trigger this code into action
sequences.
Glide 2 secs to x: pick random -240 to 240 y: pick we need to use when green flag clicked from Events. Drag
One handles
movement and random-180 to 180 this into the coding area. Next go to Looks and drag a show
reaction to code block to connect to our previous code block. This is the
hitting our robot, Tera Sprite end of this sequence of code, which should look like this when
another resets Our third sprite is called Tera, and it is a character unique to you’ve finished editing it:
your score, the Scratch. In our game Tera provides the score once the game When green flag clicked
final reacts to has completed. Tera will hide when we start the game, and Show
being fired upon! then it will wait to receive a broadcast which will trigger Tera The final sequence of code for this sprite is a trigger to
to appear and report the score. So Tera has two sequences of hide the sprite when clicked, and to start the game using a
code that we need to write. Our first is to hide Tera. We start broadcast. So we use the when this sprite clicked code
by using when green flag clicked from Events. We then block from Events to trigger the sequence, and then we
connect hide from Looks to complete this sequence of code. attach a hide code block from the Looks menu. For our last
Here is that code: block of code in this section, go to Events and drag
When green flag clicked
Hide
Our second sequence of code for Tera is to show the
scoreboard once the game has ended. For this we will need to
create another broadcast which will be triggered at the end
of the game. So in the Events look for the when I receive
block. Click on the dropdown for this block and select New
Message to create a new broadcast and call it scoreboard.
We can now drag when I receive scoreboard onto the
coding area. Underneath this block we need to add show
from Looks as Tera is currently hidden. We now need to
enable Tera to communicate the score, and for this we shall
use a say __ for 2 secs block from Looks. Drag this under the Our robot has the same basic code as our spaceship, but
previous block. Now to announce the score we need to join a does not react when crashing into our spaceship.

Sprites, backgrounds and other inputs


A major step forward for Scratch 2 (the latest version of the Scratch using the built in audio editing suite. Scratch 2 can now work with
programming language) is the ability to design and edit vector graphics. microphones to record audio, and as a basic input device. For example
Vectors differ from bitmaps as they are easily resized without any shouting can trigger a sprite to run faster. If your computer has a webcam
pixelation or distortion. Vectors also look sharper and more refined than then this can also be used with Scratch 2 as a basic form of input. It can be
pixels. So by using Scratch 2 we can now edit and create sprites based on programmed to trigger a sprite to dance, or you and a friend can play
vectors. We can also upload images from our computer and edit them virtual tennis, football or hockey using your bodies!
using Scratch. Now we can add custom images as sprites and The blocks for working with the microphone and webcam can be found
backgrounds for our games. in the Sensing palette and require that the user enables access to the
But Scratch is not just about sprites and backgrounds. Using our devices in order for them to work. In schools these features are typically
microphones we can also record our own custom audio and edit them disabled for safety, but they are quite safe for home use.

20 | Coding Made Simple


Scratch | Create a game
When green flag clicked
Set countdown to 30 Quick
Forever tip
Play sound hip hop until done Scratch 2 also
Our second sequence of code is triggered by our start has installation
broadcast. It stops playback of other audio loops, and then candidates for
starts playback of another music loop inside of a forever loop. Windows, Mac
and Linux so you
So our first block is when I receive start which can be found can take your
in the Events palette. Under this block we add stop all projects offline
sounds from the Sounds palette. We then repeat the forever and work on them
loop play sound sequence that we created in the previous with no Internet
connection. You can
sequence. For this second sequence, your code should look
then upload and
like this: sync your work to
When I receive start the Scratch website
Our Tera sprite acts as a scoreboard announcer. It hides Stop all sounds to share with
until the end of game and then jumps out to read our score Forever others.

Play sound dance funky until done


broadcast start and place it under the previous block of Our final sequence of code is a simple countdown timer
code. If you cannot see broadcast start remember that you that uses an iterative loop to change the value of our
can use the dropdown to select it, as we created this countdown variable by -1 every second. Once the loop has
broadcast right at the start with our spaceship sprite. gone round 30 times, it then broadcasts a message before
Here is the code for this sequence: stopping the game.
When this sprite is clicked Our first block for this sequence is when I receive start
Hide from the Events palette. Next we build the loop, and use a
Broadcast start repeat 10 from Control, and remember to change the 10 to
30 to ensure correct timing. Inside the loop we use change
Coding the stage countdown by 1 from Data. But we need to change the value
Our final section of code involves creating code that will run in of 1 to -1 so that it takes 1 from the value of the countdown
the background to control a timer that will countdown in our variable, reducing its value with every loop. We need to add
game. We also respond to the start broadcast by playing wait 1 secs from Control to our loop, otherwise the loop will
music in a loop as the game plays. So change our focus on complete far too quickly. Now outside of the loop we add
the Stage by clicking on the Stage icon to the left of our broadcast scoreboard and wait which is found in the
sprites, and then we can start to create our first of three Control palette. This block will broadcast the message that
sequences of code. Our first sequence sets a countdown will trigger our scoreboard sprite, Tera, to pop up at the end
timer to 30 seconds. It is triggered when the green flag is of the game. Once this happens we use stop all from Control
clicked, so go ahead and find that block from Events. Now we to stop all sequences of code and stop the game.
need to do go to Data and create a new variable called When I receive start
countdown. Drag set countdown to 0 under the previous Repeat 30
block. Change the value 0 to 30 for our 30 second Change countdown by -1
countdown. Now we need to go to Control and use a forever Wait 1 secs
Rotating sprites
loop. Place this under the previous blocks. Now we shall add Broadcast scoreboard and wait
is best handled
play sound ___ until done block from Sounds. We used a Stop all
by altering their
loop that will play in the background while the game is played. We also changed the background in the same manner properties which
Feel free to use any music for your game. that we changed the costumes of our sprites. can be accessed
This sequence is now complete, here is the code for With our code completed, now it is time to defend via the “i” menu
reference: humanity from the evil aliens and their robotic soldiers! ■ for each sprite.

Coding Made Simple | 21


Scratch: Hack it
Scratch | Hack Scratch to make a game

We seek to capture the Space Dragon, but first we need to build and code a
rocket using the visual programming tool, Scratch.

S
eptember 2015 saw the release of Raspbian Jessie, GPIO pins for the buttons GPIO pins for the LEDs
and with it the Raspberry Pi Foundation released its
Game start GPIO 2 Red GPIO17
own version of Scratch. In this project we’ll learn more
about Scratch and use it to hack together a space game, Left GPIO14 Yellow GPIO27
which we will control using our very own controller. Right GPIO23 Green GPIO22
For this project you’ll need any model of Pi, the latest
Raspbian, three momentary switches, Male to Female jumper background. We chose ‘Stars’, found in the Nature folder. Now
cables, three 220-ohm resistors, a breadboard and three LEDs. click on the cat sprite, and change its name at the top of the
We’ll start by building our controller. We’ll connect our screen to something appropriate like Rocket.
buttons to the breadboard and then use the jumper cables to Click on ‘Costumes’ and you will see that this sprite has
attach one corner of the button to a GPIO pin, and another two, used for animation. To change our cat into something
corner to a Ground (GND) pin. Similarly, we connect our more space-related, we can paint a new costume. We used a
LED’s anode, the longer leg of an LED, to a GPIO pin and small rocket, which is included in the code download for this
connect the shorter leg, the cathode, to GND via a 220-ohm project. Click ‘OK’ to load the new costume, and then select
resistor. For a detailed diagram see http://bit.ly/LXF207- that costume as the default by clicking on it.
Scratch-Diagram. The preferred layout of the GPIO pins is Keeping your focus on the Rocket sprite, click ‘Scripts’.
Broadcom (see http://pinout.xyz) For the GPIO pins we’ll We’ll now create our first script for the Rocket. From the
use for the buttons, please see the table on this page (right). Control palette, drag Click on Green Flag to the coding area.
Let’s power up our Pi and start building our game. Also from the Control palette drag the Broadcast block to
Raspbian will automatically log you into the desktop. Navigate the coding area and attach it to the Green Flag block. In the
to the main menu and open Scratch in the Programming Broadcast block click on the drop-down, select New/Edit
menu. In Scratch, the left-hand column contains a palette of and type gpioserveron . This will start the Scratch GPIO
blocks, separated into groups according to their function. server when our game starts, enabling access to the GPIO
The blocks can be dragged into the centre column, which is in Scratch.
where we build our code. In the final column is the Stage, Now we need to configure our buttons as inputs. Add
where all the output for our game will take place. At the another Broadcast, and in its drop-down select New/Edit
bottom right you can see all the sprites used in the game. and type config2in to set GPIO2 as an input. Add two more
To start, let’s make the Stage look more spacey. Click the Broadcasts and repeat, using config14in and config23in
‘Stage’ icon, at the bottom right of the screen. This changes respectively for GPIO pins 14 and 23, our left and right
the focus of any code to the Stage. In the centre column, find buttons. To ensure that the pins are configured, click on the
the tab labelled ‘Backgrounds’. Click this, then Import a new ‘Green Flag’, just above the Stage.

Extension activities
Our game is good, but what will make it by’ block to do this. The other two If
great is scoring and a time limit. Firstly statements work in the same way but
our score is a variable. Select the Rocket deal with touching the obstacles, and
sprite, click on the Variable palette and points are deducted using minus values.
choose ‘Make a new variable’. Call it Our timer is linked to the Stage, so
score and set it for all sprites. We’ll use a change focus to this. Again we’ll use a
‘When I receive start’ Broadcast to ‘When I receive start’ Broadcast to
trigger the scoring system to life. Every trigger the timer. Create a new variable
time the game starts, we set the score to called timer and using the ‘set __ to 0’
0, found in the Variables palette. block, set the timer to 30. Now use a
Now add a Forever loop from the ‘repeat 10’ loop from the Control palette
Control palette and then use three If but change the 10 to 30. Next use
statements stacked on top of each other ‘Change __ by’ to change the timer by
in the loop. The first If conditional uses -1 every time the loop iterates. To control
the ‘touching sprite’ block in Sensing to the speed, put a ‘Wait 1 second’ from the
advance our score by 10 points if we Control palette in place. Outside of the Variables are containers that can
touch the Space Dragon, before waiting loop, we place ‘Stop All’ to stop the game store anything, with handy names
for 1 second. We use the ‘change score after 30 seconds. to identify their purpose/content.

22 | Coding Made Simple


Scratch | Hack Scratch to make a game
Next grab another Green Flag block from the Control We built a
palette, and add a Wait Until block to it. Inside the blank for custom controller
the Wait Until block place a __ = __ block from the Operators from spare
components,
palette. Now move to Sensing palette and look for Slider
an old slide box
Sensor value. Click the drop-down and change it to gpio2 .
and – for that
To the left you will see a tickbox; tick it and the sensor value authentic space
for GPIO2 is printed to the top left of the Stage. Currently the experience – a
sensor is reading 1, or high. Press the button and the sensor launch switch
value changes to 0, or low. Test complete, untick the Sensor found on eBay.
Value tickbox. Now that we know it works, drag the gpio2
sensor value block to the first blank in the __ = __ block, then
type 0 (zero) in the remaining box. Our last block for this
section is another Broadcast called Start.
This will be pre-populated with coordinates, but they’ll be
Interaction with sprites wrong. To fix this, change to another palette and then back to Quick
Now let’s create more sprites for our game. Draw a planet by Motion, and it will update. Drag the Glide block to the loop. tip
clicking the ‘New Sprite’ icon. The planet has no code Repeat this action four or more times to create a pattern for Scratch is very
attached to it. Now we’ll create two sprites to act as obstacles our enemy to follow. Remember that we had a sound play intuitive but often
for our ship to avoid. Add a new sprite by clicking the ‘Add when an obstacle is hit. Well, the same can happen with our we get a little stuck.
If your code breaks,
Sprite’ icon – the middle icon in the row below the Stage. We’ll Space Dragon: just add the same code from our Robot sprite.
pull it apart and
choose a robot, but at its default size it is a little large, so right- Return to the Rocket sprite and create another section of rebuild it and test it
click on the sprite and choose ‘Resize’. code that starts When I receive start, using a Forever loop. section by section.
Earlier, we created a Broadcast called Start, and in the Now turn on our LEDs by using a Broadcast to turn a pin on You can also quickly
duplicate code by
Control palette we can see that block now exists. Drag when I and off – for example gpio17on and gpio17off . Our LEDs
right clicking on the
receive start to the coding area, followed by a Forever loop. are on 17, 27 and 22, so construct a light sequence, code and selecting
In the Motion palette drag Turn clockwise 15 degrees and remembering to use Wait blocks to control the LEDs’ speed. Duplicate.
Move 10 steps. Place both of these blocks inside the loop. To create controls for the rocket drag another When I
Our last section of code for the robot starts with another receive start block into the coding area, along with a Forever
when I receive start block. Under that we add a Forever loop and two If statements. Both If statements will be inside
loop, and inside the loop we add an If statement. the loop, on top of each other. Grab two __=__ blocks from
This will constantly check to see if we are touching the the Operators palette and place one in each If statement.
Rocket sprite – the touching block is the top block in the Next grab a gpio14 sensor value from Sensing and place it
Sensing palette. If this is True, then our game will play a sound in the first blank of __=__ and type 0 in the other. Repeat for
effect, found in the Sound palette, then say “Ouch” for 0.5 the second If statement but change gpio14 to gpio23.
seconds. The Say block is found in the Looks palette. If you To finish our Rocket code, add one more When I receive
want to add more obstacles, right-click on the robot sprite start block. Use ‘Go to x: y:’ to set a starting position for the
and duplicate until you have the required number. rocket, say the bottom left of the screen (x:0, y:0). Next, we
Our next sprite is an enemy to hunt, a Space Dragon. use a Forever loop to play a laser sound, then move the ship
Choose a new sprite and then drag a when I receive start forward 10 steps before waiting for 0.1 seconds. We add ‘If on
Broadcast from the Command palette, and also grab a edge, bounce’ to stop the Rocket getting lost.
Forever loop. Drag the Space Dragon to a part of the screen. With all of the code complete as shown below, save your
Go to the Motion palette and look for Glide 1 secs to x: y:. work and blast off for an adventure! ■

Our project is
a crazy space
game where
our rocket
must attack
the mysterious
Space Dragon
while also
avoiding a deadly
Space Robot and
a Comet.

Coding Made Simple | 23


erubyracer”, “~> 0.11.4” group :development, :test do gem “rspec-rails”, “~> 2.13.0” $ gem install bundler $ gem install rails --version=3.2.12 $ rbenv rehash $ rails
ate_attributes(params[:task]) format.html { redirect_to @task, notice: ‘...’ } format.json { head :no_content } else format.html { render action: “edit” } format.json { re
xec rails generate migration add_priority_to_tasks priority:integer $ bundle exec rake db:migrate $ bundle exec rake db:migrate $ bundle exec rails server validate
_at, ‘is in the past!’) if due_at < Time.zone.now #!/usr/bin/en python import pygame from random import randrange MAX_STARS = 100 pygame.init() screen = py
stars = for i in range(MAX_STARS): star = [randrange(0, 639), randrange(0, 479), randrange(1, 16)] stars.append(star) while True: clock.tick(30) for event in pygame
$numstars = 100; use Time::HiRes qw(usleep); use Curses; $screen = new Curses; noecho; curs_set(0); for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] = rand(80); $s
>clear; for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] -= $star_s[$i]; if ($star_x[$i] < 0) { $star_x[$i] = 80; } $screen->addch($star_y[$i], $star_x[$i], “.”); } $screen->refre
ment, :test do gem “rspec-rails”, “~> 2.13.0” $ gem install bundler $ gem install rails --version=3.2.12 $ rbenv rehash $ rails new todolist --skip-test-unit respond
tml { redirect_to @task, notice: ‘...’ } format.json { head :no_content } else format.html { render action: “edit” } format.json { render json: @task.errors, status: :unpro
ority_to_tasks priority:integer $ bundle exec rake db:migrate $ bundle exec rake db:migrate $ bundle exec rails server validate :due_at_is_in_the_past def due_at_is_
one.now #!/usr/bin/en python import pygame from random import randrange MAX_STARS = 100 pygame.init() screen = pygame.display.set_mode((640, 480)) c
star = [randrange(0, 639), randrange(0, 479), randrange(1, 16)] stars.append(star) while True: clock.tick(30) for event in pygame.event.get(): if event.type == pyg
Res qw(usleep); use Curses; $screen = new Curses; noecho; curs_set(0); for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] = rand(80); $star_y[$i] = rand(24); $star_s[$i]
rs ; $i++) { $star_x[$i] -= $star_s[$i]; if ($star_x[$i] < 0) { $star_x[$i] = 80; } $screen->addch($star_y[$i], $star_x[$i], “.”); } $screen->refresh; usleep 50000; gem “ther
ails”, “~> 2.13.0” $ gem install bundler $ gem install rails --version=3.2.12 $ rbenv rehash $ rails new todolist --skip-test-unit respond_to do |format| if @task.update_
..’ } format.json { head :no_content } else format.html { render action: “edit” } format.json { render json: @task.errors, status: :unprocessable_entity } $ bundle exec rails
exec rake db:migrate $ bundle exec rake db:migrate $ bundle exec rails server validate :due_at_is_in_the_past def due_at_is_in_the_past errors.add(:due_at, ‘is in th
pygame from random import randrange MAX_STARS = 100 pygame.init() screen = pygame.display.set_mode((640, 480)) clock = pygame.time.Clock() stars =
ge(0, 479), randrange(1, 16)] stars.append(star) while True: clock.tick(30) for event in pygame.event.get(): if event.type == pygame.QUIT: exit(0) #!/usr/bin/perl $nu
= new Curses; noecho; curs_set(0); for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] = rand(80); $star_y[$i] = rand(24); $star_s[$i] = rand(4) + 1; } while (1) { $screen-
$i]; if ($star_x[$i] < 0) { $star_x[$i] = 80; } $screen->addch($star_y[$i], $star_x[$i], “.”); } $screen->refresh; usleep 50000; gem “therubyracer”, “~> 0.11.4” group :dev
undler $ gem install rails --version=3.2.12 $ rbenv rehash $ rails new todolist --skip-test-unit respond_to do |format| if @task.update_attributes(params[:task]) forma

CODING
ent } else format.html { render action: “edit” } format.json { render json: @task.errors, status: :unprocessable_entity } $ bundle exec rails generate migration add_priori
exec rake db:migrate $ bundle exec rails server validate :due_at_is_in_the_past def due_at_is_in_the_past errors.add(:due_at, ‘is in the past!’) if due_at < Time.zon
andrange MAX_STARS = 100 pygame.init() screen = pygame.display.set_mode((640, 480)) clock = pygame.time.Clock() stars = for i in range(MAX_STARS): star =
pend(star) while True: clock.tick(30) for event in pygame.event.get(): if event.type == pygame.QUIT: exit(0) #!/usr/bin/perl $numstars = 100; use Time::HiRes qw(u
r ($i = 0; $i < $numstars ; $i++) { $star_x[$i] = rand(80); $star_y[$i] = rand(24); $star_s[$i] = rand(4) + 1; } while (1) { $screen->clear; for ($i = 0; $i < $numstars ; $i++)
creen->addch($star_y[$i], $star_x[$i], “.”); } $screen->refresh; usleep 50000; gem “therubyracer”, “~> 0.11.4” group :development, :test do gem “rspec-rails”, “~> 2.13.0
ehash $ rails new todolist --skip-test-unit respond_to do |format| if @task.update_attributes(params[:task]) format.html { redirect_to @task, notice: ‘...’ } format.json {

MADE
json { render json: @task.errors, status: :unprocessable_entity } $ bundle exec rails generate migration add_priority_to_tasks priority:integer $ bundle exec rake db:m
alidate :due_at_is_in_the_past def due_at_is_in_the_past errors.add(:due_at, ‘is in the past!’) if due_at < Time.zone.now #!/usr/bin/en python import pygame from
een = pygame.display.set_mode((640, 480)) clock = pygame.time.Clock() stars = for i in range(MAX_STARS): star = [randrange(0, 639), randrange(0, 479), randrang
pygame.event.get(): if event.type == pygame.QUIT: exit(0) #!/usr/bin/perl $numstars = 100; use Time::HiRes qw(usleep); use Curses; $screen = new Curses; noecho;
0); $star_y[$i] = rand(24); $star_s[$i] = rand(4) + 1; } while (1) { $screen->clear; for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] -= $star_s[$i]; if ($star_x[$i] < 0) { $star_
>refresh; usleep 50000; gem “therubyracer”, “~> 0.11.4” group :development, :test do gem “rspec-rails”, “~> 2.13.0” $ gem install bundler $ gem install rails --versi

SIMPLE
pond_to do |format| if @task.update_attributes(params[:task]) format.html { redirect_to @task, notice: ‘...’ } format.json { head :no_content } else format.html { rende
unprocessable_entity } $ bundle exec rails generate migration add_priority_to_tasks priority:integer $ bundle exec rake db:migrate $ bundle exec rake db:migrate $
at_is_in_the_past errors.add(:due_at, ‘is in the past!’) if due_at < Time.zone.now #!/usr/bin/en python import pygame from random import randrange MAX_ST
40, 480)) clock = pygame.time.Clock() stars = for i in range(MAX_STARS): star = [randrange(0, 639), randrange(0, 479), randrange(1, 16)] stars.append(star) while Tr
pygame.QUIT: exit(0) #!/usr/bin/perl $numstars = 100; use Time::HiRes qw(usleep); use Curses; $screen = new Curses; noecho; curs_set(0); for ($i = 0; $i < $nums
$i] = rand(4) + 1; } while (1) { $screen->clear; for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] -= $star_s[$i]; if ($star_x[$i] < 0) { $star_x[$i] = 80; } $screen->addch($sta
erubyracer”, “~> 0.11.4” group :development, :test do gem “rspec-rails”, “~> 2.13.0” $ gem install bundler $ gem install rails --version=3.2.12 $ rbenv rehash $ rails
ate_attributes(params[:task]) format.html { redirect_to @task, notice: ‘...’ } format.json { head :no_content } else format.html { render action: “edit” } format.json { re
xec rails generate migration add_priority_to_tasks priority:integer $ bundle exec rake db:migrate $ bundle exec rake db:migrate $ bundle exec rails server validate
_at, ‘is in the past!’) if due_at < Time.zone.now #!/usr/bin/en python import pygame from random import randrange MAX_STARS = 100 pygame.init() screen = py
stars = for i in range(MAX_STARS): star = [randrange(0, 639), randrange(0, 479), randrange(1, 16)] stars.append(star) while True: clock.tick(30) for event in pygame
$numstars = 100; use Time::HiRes qw(usleep); use Curses; $screen = new Curses; noecho; curs_set(0); for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] = rand(80); $s
>clear; for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] -= $star_s[$i]; if ($star_x[$i] < 0) { $star_x[$i] = 80; } $screen->addch($star_y[$i], $star_x[$i], “.”); } $screen->refre
ment, :test do gem “rspec-rails”, “~> 2.13.0” $ gem install bundler $ gem install rails --version=3.2.12 $ rbenv rehash $ rails new todolist --skip-test-unit respond
tml { redirect_to @task, notice: ‘...’ } format.json { head :no_content } else format.html { render action: “edit” } format.json { render json: @task.errors, status: :unpro
ority_to_tasks priority:integer $ bundle exec rake db:migrate $ bundle exec rake db:migrate $ bundle exec rails server validate :due_at_is_in_the_past def due_at_is_
one.now #!/usr/bin/en python import pygame from random import randrange MAX_STARS = 100 pygame.init() screen = pygame.display.set_mode((640, 480)) c
star = [randrange(0, 639), randrange(0, 479), randrange(1, 16)] stars.append(star) while True: clock.tick(30) for event in pygame.event.get(): if event.type == pyg
Res qw(usleep); use Curses; $screen = new Curses; noecho; curs_set(0); for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] = rand(80); $star_y[$i] = rand(24); $star_s[$i]
rs ; $i++) { $star_x[$i] -= $star_s[$i]; if ($star_x[$i] < 0) { $star_x[$i] = 80; } $screen->addch($star_y[$i], $star_x[$i], “.”); } $screen->refresh; usleep 50000; gem “ther
ails”, “~> 2.13.0” $ gem install bundler $ gem install rails --version=3.2.12 $ rbenv rehash $ rails new todolist --skip-test-unit respond_to do |format| if @task.update_
..’ } format.json { head :no_content } else format.html { render action: “edit” } format.json { render json: @task.errors, status: :unprocessable_entity } $ bundle exec rails
exec rake db:migrate $ bundle exec rake db:migrate $ bundle exec rails server validate :due_at_is_in_the_past def due_at_is_in_the_past errors.add(:due_at, ‘is in th
pygame from random import randrange MAX_STARS = 100 pygame.init() screen = pygame.display.set_mode((640, 480)) clock = pygame.time.Clock() stars =
ge(0, 479), randrange(1, 16)] stars.append(star) while True: clock.tick(30) for event in pygame.event.get(): if event.type == pygame.QUIT: exit(0) #!/usr/bin/perl $nu
= new Curses; noecho; curs_set(0); for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] = rand(80); $star_y[$i] = rand(24); $star_s[$i] = rand(4) + 1; } while (1) { $screen-
$i]; if ($star_x[$i] < 0) { $star_x[$i] = 80; } $screen->addch($star_y[$i], $star_x[$i], “.”); } $screen->refresh; usleep 50000; gem “therubyracer”, “~> 0.11.4” group :dev
undler $ gem install rails --version=3.2.12 $ rbenv rehash $ rails new todolist --skip-test-unit respond_to do |format| if @task.update_attributes(params[:task]) forma
ent } else format.html { render action: “edit” } format.json { render json: @task.errors, status: :unprocessable_entity } $ bundle exec rails generate migration add_priori
exec rake db:migrate $ bundle exec rails server validate :due_at_is_in_the_past def due_at_is_in_the_past errors.add(:due_at, ‘is in the past!’) if due_at < Time.zon
andrange MAX_STARS = 100 pygame.init() screen = pygame.display.set_mode((640, 480)) clock = pygame.time.Clock() stars = for i in range(MAX_STARS): star =
pend(star) while True: clock.tick(30) for event in pygame.event.get(): if event.type == pygame.QUIT: exit(0) #!/usr/bin/perl $numstars = 100; use Time::HiRes qw(u
r ($i = 0; $i < $numstars ; $i++) { $star_x[$i] = rand(80); $star_y[$i] = rand(24); $star_s[$i] = rand(4) + 1; } while (1) { $screen->clear; for ($i = 0; $i < $numstars ; $i++)
creen->addch($star_y[$i], $star_x[$i], “.”); } $screen->refresh; usleep 50000; gem “therubyracer”, “~> 0.11.4” group :development, :test do gem “rspec-rails”, “~> 2.13.0
s new todolist --skip-test-unit respond_to do |format| if @
ender json: @task.errors, status: :unprocessable_entity } $
:due_at_is_in_the_past def due_at_is_in_the_past errors.

Raspberry Pi Coding | Contents


ygame.display.set_mode((640, 480)) clock = pygame.time.
e.event.get(): if event.type == pygame.QUIT: exit(0) #!/usr/
star_y[$i] = rand(24); $star_s[$i] = rand(4) + 1; } while (1) {
esh; usleep 50000; gem “therubyracer”, “~> 0.11.4” group
d_to do |format| if @task.update_attributes(params[:task])
ocessable_entity } $ bundle exec rails generate migration
_in_the_past errors.add(:due_at, ‘is in the past!’) if due_at
clock = pygame.time.Clock() stars = for i in range(MAX_

Coding on Pi
game.QUIT: exit(0) #!/usr/bin/perl $numstars = 100; use
= rand(4) + 1; } while (1) { $screen->clear; for ($i = 0; $i <
rubyracer”, “~> 0.11.4” group :development, :test do gem
_attributes(params[:task]) format.html { redirect_to @task,
s generate migration add_priority_to_tasks priority:integer
he past!’) if due_at < Time.zone.now #!/usr/bin/en python
for i in range(MAX_STARS): star = [randrange(0, 639),
Discover how you can develop on
umstars = 100; use Time::HiRes qw(usleep); use Curses; the low-cost, micro-PC system
->clear; for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] -=
velopment, :test do gem “rspec-rails”, “~> 2.13.0” $ gem
at.html { redirect_to @task, notice: ‘...’ } format.json { head Welcome to Pi������������������������������������������������������������������������� 26
ity_to_tasks priority:integer $ bundle exec rake db:migrate
ne.now #!/usr/bin/en python import pygame from random Coding in IDLE������������������������������������������������������������������������ 28
= [randrange(0, 639), randrange(0, 479), randrange(1, 16)]
usleep); use Curses; $screen = new Curses; noecho; curs_
Minecraft: Start hacking ���������������������������� 30
) { $star_x[$i] -= $star_s[$i]; if ($star_x[$i] < 0) { $star_x[$i]
0” $ gem install bundler $ gem install rails --version=3.2.12
Minecraft: Image walls ������������������������������������� 32
head :no_content } else format.html { render action: “edit” Sonic Pi: Make some noise! ��������������� 36
migrate $ bundle exec rake db:migrate $ bundle exec rails
m random import randrange MAX_STARS = 100 pygame. Ruby: Compose music ���������������������������������� 40
ge(1, 16)] stars.append(star) while True: clock.tick(30) for
; curs_set(0); for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] Sonic Pi hardware control ���������������������� 42
_x[$i] = 80; } $screen->addch($star_y[$i], $star_x[$i], “.”); }
sion=3.2.12 $ rbenv rehash $ rails new todolist --skip-test-
er action: “edit” } format.json { render json: @task.errors,
$ bundle exec rails server validate :due_at_is_in_the_past
TARS = 100 pygame.init() screen = pygame.display.set_
rue: clock.tick(30) for event in pygame.event.get(): if event.
stars ; $i++) { $star_x[$i] = rand(80); $star_y[$i] = rand(24);
ar_y[$i], $star_x[$i], “.”); } $screen->refresh; usleep 50000;
s new todolist --skip-test-unit respond_to do |format| if @
ender json: @task.errors, status: :unprocessable_entity } $
:due_at_is_in_the_past def due_at_is_in_the_past errors.
ygame.display.set_mode((640, 480)) clock = pygame.time.
e.event.get(): if event.type == pygame.QUIT: exit(0) #!/usr/
star_y[$i] = rand(24); $star_s[$i] = rand(4) + 1; } while (1) {
esh; usleep 50000; gem “therubyracer”, “~> 0.11.4” group
d_to do |format| if @task.update_attributes(params[:task])
ocessable_entity } $ bundle exec rails generate migration
_in_the_past errors.add(:due_at, ‘is in the past!’) if due_at
clock = pygame.time.Clock() stars = for i in range(MAX_
game.QUIT: exit(0) #!/usr/bin/perl $numstars = 100; use
= rand(4) + 1; } while (1) { $screen->clear; for ($i = 0; $i <
rubyracer”, “~> 0.11.4” group :development, :test do gem
_attributes(params[:task]) format.html { redirect_to @task,
s generate migration add_priority_to_tasks priority:integer
he past!’) if due_at < Time.zone.now #!/usr/bin/en python
for i in range(MAX_STARS): star = [randrange(0, 639),
umstars = 100; use Time::HiRes qw(usleep); use Curses;
->clear; for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] -=
velopment, :test do gem “rspec-rails”, “~> 2.13.0” $ gem
at.html { redirect_to @task, notice: ‘...’ } format.json { head
ity_to_tasks priority:integer $ bundle exec rake db:migrate
ne.now #!/usr/bin/en python import pygame from random
= [randrange(0, 639), randrange(0, 479), randrange(1, 16)]
usleep); use Curses; $screen = new Curses; noecho; curs_ Coding Made Simple | 25
) { $star_x[$i] -= $star_s[$i]; if ($star_x[$i] < 0) { $star_x[$i]
0” $ gem install bundler $ gem install rails --version=3.2.12
Coding | Getting started

Welcome to Pi
Reveal the Raspbian desktop and partake of the pleasures of Python
programming on the Raspberry Pi.

T
he Pi-tailored Raspbian desktop environment free to peruse that to learn about commands such as  ls , cd
received a thorough overhaul in late 2015, making it and mkdir . It’s a good idea to keep the software on your Pi
an even friendlier place to learn, play or work. The up to date, so let’s see how that works from the terminal.
Raspbian team has squeezed a great deal into the 3.5GB We’re going to use the apt-get package manager, which
install. Most importantly, there’s a special edition of Minecraft, handles all of the consultations with Raspbian mirrors and
but there’s also Wolfram Mathematica (for doing hard sums), does a remarkable job of (un)installing packages and their
LibreOffice and the Epiphany web browser, as well as PDF dependencies with a minimum of fuss. Open LXTerminal
and image viewers. We’re amply catered for programming- from either the menu or the launch bar, and enter the
wise, too – there’s Scratch (the visual coding language), Sonic following command:
Pi (the live coding synth), not to mention the Python $ sudo apt-get update
programming language.
Compared to, say, Windows 10, Raspbian may appear Terminal velocity
somewhat spartan. Bear in mind that the Pi (particularly non- That updates Raspbian’s local list of all available packages. In
Pi 2 models) is considerably less powerful than your average the next step, the list of current packages installed on the
desktop computer, so lightweight is the order of the day. It system is checked against this, and where newer packages
remains no less functional, and thanks to graphical hardware are available, these are offered for upgrade:
acceleration, it $ sudo apt-get
can play high-
definition video “The Pi is far less powerful than upgrade
If there’s lots
without batting an
eyelid. Software is
your average desktop computer, of packages to
upgrade, the
managed from but remains no less functional.” process may take
the Add/Remove some time. The
Software bottleneck is mostly
application. This downloads packages from Raspbian’s due to the speed at which data can be written to the SD card
repositories, which you can trust. It’s possible to do this from – you may want to make a cup of tea. You should update your
the command line too. In fact, it’s possible to do pretty much packages pretty regularly; you’ll get important security
anything from the command line. updates and the latest features or fixes for all your software.
There’s a very brief introduction to the terminal in the Mint Python is a particularly good first programming language.
tutorial (see page 58), which applies equally well here, so feel The syntax is clean and concise, there are no awkward

The new
Epiphany browser
works well; it can
even play HTML5
YouTube videos,
such as this one
featuring a tiny
arcade cabinet.

26 | Coding Made Simple


Coding | Getting started
The Raspbian desktop
Menu
Here you’ll find all the great
programs mentioned earlier –
and more. You’ll also find links
to help resources and, in the
Preferences menu, some tools
for adjusting system settings.

Launch bar
Frequently used applications
can be added here – just right-
click it and select Application
Launch Bar Settings. The black
screen icon in the centre opens
the terminal.

File manager
The PCManFM file manager is
lightweight but thoroughly
capable. It opens at your home
folder and is also capable of Terminal Network
browsing Windows and other The command line gives direct access to the From here you can configure your wired and wireless network
network shares. operating system. It can be daunting but, with connections. Some wireless adapters work better with the Pi
practice, you’ll appreciate how efficient it is. than others, so it’s worth doing some research before you buy.

semicolons to terminate statements, lots of shortcuts for >>> 60 * 60 * 24 * 365


things that are cumbersome in other languages and there’s a As mentioned elsewhere, it makes more sense to save
huge number of modules that enable you to achieve just your programs in text files. So we’ll now leave the interpreter
about anything. by hitting Ctrl+D, and make our first Pi Python program. At
this point, you have a choice: you can proceed as in the Mint
A tale of two Pythons tutorial and use the nano text editor, or you can use the
Raspbian comes with two versions of Python installed. This graphical one located in the Accessories menu. Before you
reflects a duality that has formed in Pythonic circles over the make that choice, though, we’ll create a directory for storing
last few years. Python 3 (see page 84 onwards) has been our Python programs. Keeping on top of your filing is A Good
around since 2008, but people have been slow to adopt. Thing, too.
Many of the larger projects that used to only work on the old $ mkdir ~/python
version have been ported to the new, so finally the shift to 3 is Now type the following into your chosen editor
gaining traction. Sooner or later, you’ll run into something that print(‘Hello World’)
requires Python 2.7, and then you might have to unlearn some and then save the file. Assuming you’re using the graphical
things, but for this tutorial we’re going to stick with the editor, choose, File > Save As, and then navigate to the
version of Python provided by Raspbian – 3.4. recently created Python folder, and save it as helloworld.py.
Open up a terminal, if you haven’t already done so, and If you’re using nano, use Ctrl+X to save and exit.
start the Python 3 interpreter by entering: Now we can run this and see what we have created:
$ python3 $ cd ~/python
Once again, if you have a look at the introductory Mint $ python3 helloworld.py
tutorial (see page 58), you’ll learn about a few things you can It’s not going to win any awards, but it’s a fully working
do here. For example, if you wanted to find out how many program and something you can build around in further
seconds there are in a year, you could do the following: programming adventures. n

Other programming tools


We’ve only covered Python in this tutorial Then there’s also Node-RED, for designing visual language, which means that programs are
but there are other programming languages applications based around the Internet of Things, created by dragging and connecting blocks that
available in Raspbian. To start with, there’s a for which the Raspberry Pi is well suited. It’s easy represent events and logic. Plus it has an orange
full-blown Java IDE called Greenfoot (which to add sensors, cameras or LEDs, and turn your cat as its mascot. Scratch was developed at MIT
has been developed in partnership with the Pi into a bona fide smart device. It can watch and, to date, some 12.5 million projects have
University of Kent and Oracle). This teaches your letterbox, monitor the weather, or even been shared on its website at https://scratch.
the basics of open-source design using visual water your plants. mit.edu. Fortune has it that by turning to the
scenarios but you can also play with the Finally, Scratch (see page 8) is a great way start of this bookazine, you will find a number of
underlying Java source (if you’re feeling brave). to get kids (or grown-up kids) into coding. It’s a tutorials devoted to the language.

Coding Made Simple | 27


Coding | Coding with IDLE

Coding in IDLE
Make Python coding more convenient and start hacking in Minecraft.

T
he rationale for favouring an integrated development kinds of colourful, improbable things involving obsidian and
environment (IDE) is discussed later on (see page 60), TNT blocks.
wherein we met the Geany IDE. Ultimately, it comes
down to being a more centralised, efficient way to work. IDLE hands
Raspbian comes with IDLE – an IDE specifically designed for We’ll put Minecraft aside for the moment as we introduce
the Python language – and we’re going to use it to further our IDLE. Press Tab to release the mouse cursor from the game,
programming adventures using a game called Minecraft, and click on the Raspbian menu. You’ll notice that it rather
which you might have heard of. unhelpfully appears behind the Minecraft window. This is
You’ll find Minecraft in the Games menu, so start it up now because of the selfish way the game accesses the GPU, in
as a pre-coding warm-up. Click on Start Game and then effect ignoring anything else on the screen and summarily
Create New to generate a new world. After a few seconds, drawing on top of it. So either minimise the Minecraft window
you’ll find yourself in the Minecraft world. You can navigate or put it somewhere out of the way. We need it open so that
with the W, A, S IDLE can talk to it.
and D keys, and You’ll find Python
look around with
the mouse. Space
“In no time you can be coding all 2 and 3 versions of
IDLE in the
makes you kinds of colourful, improbable Programming
(actually the
Minecraft things involving TNT blocks.” menu. The
Minecraft Python
protagonist, API has been
whose name is Steve) jump, and double-tapping Space updated to support version 3, so use that one. There’s a quick
makes you fly (or fall, if you were already flying). You can bash guide to the interface opposite – note that only the
away at the landscape with the left mouse button – the right Interpreter window opens initially. Select File > Open, then
button is used for placing blocks. To choose a type of block to navigate to the python/ folder and open the helloworld.py
place, press E to bring up a menu. file we made in the previous tutorial. The Editor window opens
In the event that you’re already something of a Minecraft to display our code, complete with helpful syntax highlighting.
aficionado, you’ve probably noticed that the Pi edition is From the Run menu, select Run Module or press F5. The
slightly restricted. There’s no crafting, no enemies and no Interpreter window now springs to life with its greeting. If you
Nether, but it does support networked play, and it is free. It edit the code without saving it, the Run Module helpfully asks
also has another trick up its sleeve – it comes with a if you want to save it first – you can’t run unsaved code. If
comprehensive API (application programming interface) for your code contains mistakes, you get an error message and
hooking it up to Python. So in no time you can be coding all the offending bit of code is highlighted in red.

Steve feels
catastrophically
compelled to
introduce his
sword to the
TNT. It’s actually
harmless
because it’s not
live. This can
be changed,
however...

28 | Coding Made Simple


Coding | Coding with IDLE
The IDLE interface
Debug
The built-in debugger helps
you to track down any errors
in your code. It also shows any
variables, and navigates any
breakpoints you’ve set up in
the Editor.

Interpreter
We can use this shell exactly
as we did earlier when we ran
Python from the command line.
Output from programs run from
the Editor appear here.

Class browser
This is where the functions,
classes or methods of any
code we have open appear.
You can access it from the Run menu Editor
Window menu. You’ll find the Run Module option (F5) here. This This is where we edit our code. Similar to Geany (see page
checks the syntax of your code, then executes it, 60), Python keywords are highlighted. IDLE auto-indents
with the output appearing in the shell. using four spaces, rather than a tab.

Close the helloworld.py file and start a new one by x, y, z = mc.player.getPos()


choosing File > New from the Interpreter window. We’ll start mc.player.setPos(x, y + 50, z)
our new program with the boilerplate code required to get Save this update, and again make sure the Minecraft
Python talking to our Minecraft game: window is visible before running the module. As before, the
from mcpi.minecraft import Minecraft message is displayed, but then we suddenly find ourselves
mc = Minecraft.create() high in the sky and falling fast. Fortunately, Steve doesn’t get
The first line imports the Minecraft module into our code hurt in the game, and he’ll land somewhere around where
– don’t worry too much about the awkward syntax here, but he was before the program was run, presumably a little
do worry about getting the capitalisation correct. The second discombobulated, though…
line sets up a new object, mc (short for minecraft), using the
create() function that we imported in the first line. The mc Catching the bug
object acts as a conduit between our code and the Minecraft We can use IDLE’s built-in debugger to see this happening
game. Now let’s add a third line, so that our program actually step by step. Right-click the final setPos() line and choose
does something: Set Breakpoint. Next, in the Interpreter window, choose
mc.postToChat(‘Hello Minecraft World’) Debug > Debugger. Now return to your program and run it
Save this file in the python/ folder as hellomc.py. Now once again. The debugger enables you to run step by step
arrange windows so that both your code and Minecraft are through your code, which is incredibly useful for (funnily
visible, and run your program. If all goes according to plan, a enough) ridding your code of bugs.
message should appear in the game. A few seconds later, it By defining a breakpoint, we can also tell IDLE to execute
will vanish. We’ve manipulated the game’s chat feature to everything up to this line, and on our go ahead continue. From
display messages not from other users, but from our own the debugger window, choose Go. Notice that in the game
program. And we can do an awful lot more. window we get as far as displaying the message, but not as
As you wander around the Minecraft world, you’ll notice far as being sent skyward. There’s a lot of stuff you needn’t
that some numbers in the top-left change. These give your worry about going on in the debugger, but notice that the
position in terms of a 3D co-ordinate system. Don’t worry if variables x , y and z from the getPos() line have been
the idea of doing geometry is terrifying or offensive – for calculated in the Globals panel. Press Go again to initiate
now, all you need to know is that the x and z directions are Steve’s catapulting skyward.
parallel to the world’s surface, and the y direction determines The Minecraft API also contains getBlock() and
your height.  setBlock() functions for probing and manipulating the
The API contains functions for working with the player’s environment. These functions are beyond the scope of this
position: we can use mc.Player.getPos() to get the player’s primer, unfortunately, but you’ll be able to find some great
current position, and mc.player.setPos() to change it. Add the Minecraft tutorials at Martin O’Hanlon’s handy website:
following lines to your code: http://stuffaboutcode.com. n

Coding Made Simple | 29


Coding | Hacking Minecraft

Minecraft:
Start hacking
Use Python on your Pi to merrily meddle with Minecraft.

A
rguably more fun than the generously provided Assuming you’ve got your Pi up and running, the first step
Wolfram Mathematica: Pi Edition is Mojang’s is downloading the latest version from http://pi.minecraft.
generously provided Minecraft: Pi Edition. The latter net to your home directory. The authors stipulate the use of
is a cut-down version of the popular Pocket Edition, and as Raspbian, so that’s what we’d recommend – your mileage
such lacks any kind of life-threatening gameplay, but includes may vary with other distributions. Minecraft requires the X
more blocks than you can shake a stick at, and three types of server to be running so if you’re a boot-to-console type you’ll
saplings from which said sticks can be harvested. have to startx. Start LXTerminal and extract and run the
This means that there’s plenty of stuff with which to contents of the archive like so:
unleash your creativity, then, but all that clicking is hard work, $ tar -xvzf minecraft-pi-0.1.1.tar.gz
and by dint of the edition including of an elegant Python API, $ cd mcpi
you can bring to fruition blocky versions of your wildest $ ./minecraft-pi
dreams with just a few lines of code. See how smoothly it runs? Towards the top-left corner you
can see your x, y and z co-ordinates, which will change as you
navigate the block-tastic environment. The x and z axes run
parallel to the floor, whereas the y dimension denotes altitude.
Each block (or voxel, to use the correct parlance) which
makes up the landscape is described by integer co-ordinates
and a BlockType. The ‘floor’ doesn’t really have any depth,
so is, instead, said to be made of tiles. Empty space has the
BlockType AIR, and there are about 90 other more tangible
substances, including such delights as GLOWING_OBSIDIAN
and TNT. Your player’s co-ordinates, in contrast to those of
the blocks, have a decimal part since you’re able to move
continuously within AIR blocks.
The API enables you to connect to a running Minecraft
instance and manipulate the player and terrain as befits your
megalomaniacal tendencies. In order to service these our first
task is to copy the provided library so that we don’t mess with
the vanilla installation of Minecraft. We’ll make a special folder
for all our mess called ~/picraft, and put all the API stuff in
~/picraft/minecraft. Open LXTerminal and issue the
following directives:
$ mkdir ~/picraft
Don’t try this at home, kids… actually do try this at home. $ cp -r ~/mcpi/api/python/mcpi ~/picraft/minecraft

Dude, where’s my Steve?


Here we can see our intrepid character (Steve) Euclidean space into discrete blocks. A 2D version
inside the block at (0,0,0). He can move around of this problem occurs whenever you render any
inside that block, and a few steps in the x and z kind of vector graphics: Say, for instance, you want
directions will take Steve to the shaded blue block. to draw a line between two points on the screen,
On this rather short journey he will be in more than then unless the line is horizontal or vertical, a
one block at times, but the Minecraft API’s decision has to be made as to which pixels need to
getTilePos() function will choose the block which be coloured in. The earliest solution to this was
contains most of him. provided by Jack Elton Bresenham in 1965, and we
Subtleties arise when trying to translate standard will generalise this classic algorithm to three Isometric projection makes
concepts, such as lines and polygons from dimensions a little later in this chapter. Minecraft-world fit on this page.

30 | Coding Made Simple


Coding | Hacking Minecraft
Now without further ado, let’s make our first
Minecraftian modifications. We’ll start by
running an interactive Python session
alongside Minecraft, so open another tab in
LXTerminal, start Minecraft and enter a world
then Alt-Tab back to the terminal and open up
Python in the other tab. Do the following in the
Python tab:
import minecraft.minecraft as minecraft
import minecraft.block as block
mc = minecraft.Minecraft.create()
posVec = mc.player.getTilePos()
x = posVec.x
y = posVec.y
z = posVec.z
mc.postToChat(str(x)+’ ‘+ str(y) +’ ‘+ str(z))
Behold, our location is emblazoned on the
screen for a few moments (if not, you’ve made
a mistake). These co-ordinates refer to the
current block that your character occupies, and
so have no decimal point. Comparing these
with the co-ordinates at the top-left, you will
see that these are just the result of rounding
down those decimals to integers (e.g. -1.1 is
rounded down to -2). Your character’s
co-ordinates are available via mc.player.getPos(), so in t = mc.getBlock(x, y – 1, z) All manner
some ways getTilePos() is superfluous, but it saves three mc.postToChat(str(x) + ‘ ‘ + str(y) + ‘ ‘ + str(z) + ‘ ‘ + of improbable
float to int coercions so we may as well use it. The API has str(t)) structures can
be yours.
a nice class called Vec3 for dealing with three-dimensional Now fire up Minecraft, enter a world, then open up a
vectors, such as our player’s position. It includes all the terminal and run your program:
standard vector operations such as addition and scalar $ python gps.py
multiplication, as well as some other more exotic stuff that The result should be that your co-ordinates and the
will help us later on. BlockType of what you’re stood on are displayed as you move
We can also get data on what our character is standing about. Once you’ve memorised all the BlockTypes (joke),
on. Go back to your Python session and type: Ctrl+C the Python program to quit.
Quick
curBlock = mc.getBlock(x, y - 1, z) We have covered some of the ‘passive’ options of the API,
tip
mc.postToChat(curBlock) but these are only any fun when used in conjunction with the Check out Martin
Here, getBlock() returns an integer specifying the block more constructive (or destructive) options. Before we sign off, O’Hanlon’s
website www.
type: 0 refers to air, 1 to stone, 2 to grass, and you can find all we’ll cover a couple of these. As before start Minecraft and a
stuffaboutcode.
the other block types in the file block.py in the ~/picraft/ Python session, import the Minecraft and block modules, and com, which
minecraft folder we created earlier. We subtract 1 from the y set up the mc object: includes some
value since we are interested in what’s going on underfoot – posVec = mc.player.getTilePos() great examples of
calling getBlock() on our current location should always x = posVec.x just what the API is
capable of.
return 0, since otherwise we would be embedded inside y = posVec.y
something solid or drowning. z = posVec.z
As usual, running things in the Python interpreter is great for j in range(5):
for playing around, but the grown up way to do things is to for k in range(x - 5, x + 5)
put all your code into a file. Create the file ~/picraft/gps.py mc.setBlock(k, j, z + 1, 246)
with the following code. Behold! A 10x5 wall of glowing obsidian has been erected
import minecraft.minecraft as minecraft adjacent to your current location. We can also destroy blocks
import minecraft.block as block by turning them into air. So we can make a tiny tunnel in our
mc = minecraft.Minecraft.create() obsidian wall like so:
oldPos = minecraft.Vec3() mc.setBlock(x, y, z + 1, 0)
while True: Assuming of course that you didn’t move since inputting the
playerTilePos = mc.player.getTilePos() previous code.
if playerTilePos != oldPos: Later on in this chapter we’ll show you how to build and
oldPos = playerTilePos destroy some serious structures, dabble with physics, rewrite
x = playerTilePos.x some of the laws thereof, and go a bit crazy within the
y = playerTilePos.y confines of your 256x256x256 world. Until then, try playing
z = playerTilePos.z with the mc.player.setPos() function. Teleporting is fun! n

Coding Made Simple | 31


Coding | Minecraft image walls

Minecraft: Image
wall importing
Have you ever wanted to reduce your pictures to 16 colour blocks?
You haven’t? Tough – we’re going to tell you how regardless.
things to use some other blocks to add different colours to
your palette. The process of reducing an image’s palette is
an example of quantization – information is removed from
the image and it becomes smaller. In order to perform this
colour quantization we first need to define our new restrictive
palette, which involves specifying the Red, Green and Blue
components for each of the 16 wool colours. This would be a
tedious process, involving importing an image of each wool
colour into Gimp and using the colour picker tool to obtain
the component averages, but fortunately someone has done
all the hard work already.
We also need to resize our image – Minecraft-world is only
256 blocks in each dimension, so since we will convert one
pixel to one block our image must be at most 256 pixels in its
largest dimension. However, you might not want your image
taking up all that space, and blocks cannot be stacked more
than 64 high, so the provided code resizes your image to 64
Not some sort of bloodshot cloud, but a giant raspberry floating in the sky.
Just another day at the office.
pixels in the largest dimension, maintaining the original
aspect ratio. You can modify the maxsize variable to change

T
echnology has spoiled us with 32-bit colour, multi- this behaviour, but the resultant image will be missing its top
megapixel imagery. Remember all those blocky if it is too tall.
sprites from days of yore, when one had to invoke The PIL module handles the quantization and resizing
something called one’s imagination in order to visualise what with one-line simplicity, but we must first define the palette
those giant pixels represented? In this tutorial we hark back and compute the new image size. The palette is given as a list
to those halcyon days from the comfort of Minecraft-world, as of RGB values, which we then pad out with zeroes so that it is
we show you how to import and display graphics using blocks of the required 8-bit order. For convenience, we will list our
of coloured wool. Also Python. And the Raspberry Pi. colours in order of the blockData parameter.
The most colourful blocks in Minecraft are wool mcPalette = [
(blockType 35): there are 16 different colours available, which 221,221,221, # White
are selected using the blockData parameter. For this tutorial 219,125,62, # Orange
we shall use these exclusively, but you could further develop 179,80,188, # Magenta

Standard setup
If you’ve used Minecraft: Pi Edition before All the files will be in a subdirectory called $ tar -xvzf mcimg.tar.gz
you’ll be familiar with the drill, but if not this is mcpi. To run Minecraft you need to have first $ cp -r ~/mcpi/api/python/mcpi ~/mcimg/
how to install Minecraft and copy the API for started X, then from a terminal do: minecraft
use in your code. $ cd ~/mcpi For this tutorial we’re going to use the PIL
We’re going to assume you’re using Raspbian, $ ./minecraft-pi (Python Imaging Library), which is old and
and that everything is up to date. You can It is a good idea to set up a working directory deprecated but is more than adequate for this
download Minecraft from http://pi.minecraft. for your Minecraft project, and to copy the API project’s simple requirements. It can import
net, then open a terminal and unzip the file as there. The archive on the disk will extract into a your .jpg and .png files, among others, so there’s
follows (assuming you downloaded it to your directory called mcimg, so you can extract it to no need to fiddle around converting images.
home directory): your home directory and then copy the api files Install it as follows:
$ tar -xvzf ~/minecraft-pi-0.1.1.tar.gz in the following way: $ sudo apt-get install python-imaging

32 | Coding Made Simple


Coding | Minecraft image walls
With just
107,138,201, # Light Blue to replace this value with your image’s background colour, 16 colours,
177,166,39, # Yellow then the transparent parts will not get drawn. We make a new Steve can
65,174,56, # Lime Green single-pixel dummy image to hold this palette: draw anything
208,132,153, # Pink mcImagePal = Image.new("P", (1,1)) he wants
64,64,64, # Dark Grey mcImagePal.putpalette(mcPalette) (inaccurately).
154,161,161, # Light Grey The provided archive includes the file test.png, which is in
46,110,137, # Cyan fact the Scratch mascot, but you are encouraged to replace
126,61,181, # Purple this line with your own images to see how they survive the
46,56,141, # Blue {res,quant}ize. You can always TNT the bejesus out of them if
79,50,31, # Brown you are not happy. To ensure the aspect ratio is accurate we
53,70,27, # Green use a float in the division to avoid rounding to an integer.
150,52,48, # Red mcImage = Image.open("test.png")
25,22,22, # Black width = mcImage.size[0]
] height = mcImage.size[1]
ratio = height / float(width)
mcPalette.extend((0,0,0) * 256 - len(mcPalette) / 3) maxsize = 64
Unfortunately the “/ 3” is missing from the code at As previously mentioned, blocks in Minecraft-world do not
http://bit.ly/ca2015ref though it is a mistake without any stack more than 64 high. The next codeblock proportionally
real consequence (phew). Padding out the palette in this resizes the image to 64 pixels in its largest dimension.
manner does however have the possibly unwanted side-effect if width > height:
of removing any really black pixels from your image. This rwidth = maxsize
happens because their value is closer to absolute black (with rheight = int(rwidth * ratio)
which we artificially extended the palette) than the very else:
slightly lighter colour of the ‘black’ wool. To work around this rheight = maxsize
you can change the (0,0,0) above to (25,22,22), so that there rwidth = int(rheight / ratio)
are no longer any absolute blacks to match against. A If you have an image that is much longer than it is high,
reasonable hack if you’re working with a transparent image is then you may want to use more than 64 pixels in the

Coding Made Simple | 33


Coding | Minecraft image walls

horizontal dimension and fix the height at 64. Replacing the if pixel < 16:
above block with just the two lines of the else clause would mc.setBlock(j + x + 5, rheight - k + y, z, 35, pixel)
achieve precisely this. To do all the magic, start Minecraft and move Steve to
Now we convert our image to the RGB colourspace, so as a position that befits your intended image. Then open a
not to confuse the quantize() method with transparency terminal and run:
information, and then force upon it our woollen palette and $ cd ~/mcimg
new dimensions. You might get better results by doing the $ python mcimg.py
resize first and the quantization last, but we prefer to keep So that covers the code, but you can have a lot of fun by
our operations in lexicographical order. expanding on this idea. A good start is probably to put the
mcImage = mcImage.convert("RGB") contents of mcimg.py into a function. You might want to give
mcImage = mcImage.quantize(palette = mcImagePal) this function some arguments too. Something like the
mcImage = mcImage.resize((rwidth,rheight)) following could be useful as it enables you to specify the
For simplicity, we will position our image close to Steve’s image file and the desired co-ordinates:
location, five blocks away and aligned in the x direction to be def drawImage(imgfile, x=None, y=None, z=None):
precise. If Steve is close to the positive x edge of the world, or if x == None:
if he is high on a hill, then parts of the image will sadly be lost. playerPos = mc.player.getPos()
Getting Steve’s coordinates is a simple task: x = playerPos.x
playerPos = mc.player.getPos() y = playerPos.y
x = playerPos.x z = playerPos.z
y = playerPos.y If no co-ordinates are specified, then the player’s position
z = playerPos.z is used. If you have a slight tendency towards destruction,
Then it is a simple question of looping over both then you can use live TNT for the red pixels in your image.
dimensions of the new image, using the slow but trusty Just replace the mc.setBlock line inside the drawing loop
getpixel() method, to obtain an index into our palette, and with the following block:
using the setBlocks() function to draw the appropriate if pixel == 14:
colour at the appropriate place. mc.setBlock(j + x + 5, rheight - k + y, z, 46, 1)
If your image has an alpha channel then getpixel() will else:
return None for the transparent pixels and no block will be mc.setBlock(j + x + 5, rheight - k + y, z,
drawn. To change this behaviour one could add an else mcPaletteBlocks[pixel])
clause to draw a default background colour. Image If you don’t like the resulting image, then we’ve got good
co-ordinates start with (0,0) in the top-left corner, so to news, as it’s highly unstable and a few careful clicks on the
avoid drawing upside-down we subtract the iterating variable TNT blocks will either make some holes in it or reduce it to
k from rheight. dust. It depends how red your original image was.
for j in range(rwidth): While Minecraft proper has a whole bunch of colourful
for k in range(rheight): blocks, including five different types of wooden planks and
pixel = mcImage.getpixel((j,k)) stairs, six kinds of stone, emerald, and 16 colours of stained

Unlike in Doom,
this strawberry/
cacodemon
doesn’t spit
fireballs at you.
This is good.

34 | Coding Made Simple


Coding | Minecraft image walls
That’s right,
Steve, go for
the ankles.
Let’s see how
fast he runs
without those!

glass, the Pi Edition is a little more restrictive. There are some 116,217,212
good candidates for augmenting your palette, though: ]
mcPaletteLength = len(mcPalette / 3)
then we can structure our lookup table as follows:
Blockname Block ID Red Green Blue
mcLookup = []
Gold 41 241 234 81 for j in range(16):
Lapis Lazuli 22 36 61 126 mcLookup.append((35,j))
mcLookup += [(41,0),(22,0),(24,0),(79,0),(57,0)]
Sandstone 24 209 201 152
Ice 79 118 165 244 Thus the list mcLookup comprises the blockType and
Diamond 57 116 217 212 blockData for each colour in our palette. And we now have
a phenomenal 31.25% more colours with which to play. To
use this in the drawing loop, use the following code inside
We have hitherto had it easy insofar as the mcPalette the for loops:
index aligned nicely with the coloured wool blockData pixel = mcImage.getpixel((j,k))
parameter. Now that we’re incorporating different blockTypes if pixel < mcPaletteLength:
things are more complicated, so we need a lookup table to do bType = mcLookup[pixel][0]
the conversion. Assuming we just tack these colours on to the bData = mcLookup[pixel][1]
end of our existing mcPalette definition, like so: mc.setBlock(j + x + 5, rheight - k + y, z, bType, bData)
mcPalette = [ … In this manner you could add any blocks you like to your
241,234,81, palette, but be careful with the lava and water ones: their
36,61,126, pleasing orange and blue hues belie an inconvenient
209,201,152, tendency to turn into lava/waterfalls. Incidentally, lava and
118,165,244, water will combine to create obsidian. Cold, hard obsidian. n

More dimensions
One of the earliest documentations of displaying counterpart has also done similar, though parts to jump around on. If you were to proceed
custom images in Minecraft:Pi Edition is Dav of Minecraft-Denmark were sabotaged by with this, then you’d probably have to make
Stott’s excellent tutorial on displaying Ordnance miscreants. Another fine example is Martin everything pretty small – the drawing process
Survey maps, http://bit.ly/2fe27wk. Two- O’Hanlon’s excellent 3D modelling project. This is slow and painful. Naturally, someone (Henry
dimensional images are all very well, but Steve can import .obj files (text files with vertex, face Garden) has already taken things way too far
has a whole other axis to play with. To this end and texture data) and display them in Minecraft: and has written Redstone – a Clojure interface
the aforementioned Ordnance Survey team has Pi Edition. Read all about it at http://bit. to Minecraft which enables movies to be
provided, for the full version of Minecraft, a ly/1sutoOS . Of course, we also have a temporal rendered. You can see the whole presentation
world comprising most of Great Britain, with dimension, so you could expand this tutorial in including a blockified Simpsons title sequence
each block representing 50m. Its Danish that direction, giving Steve some animated gifs at http://bit.ly/1sO0A2q.

Coding Made Simple | 35


Coding | SonicPi

Sonic Pi: Make


some noise!
We serve up a selection of ‘phat beats’ using nothing more than
a Raspberry Pi and Raspbian.

F
or this project you’ll need any Pi model and Raspbian is quite old. It’s well worth updating the software installed on
(www.raspberrypi.org/downloads). In previous your Pi by opening a terminal and typing the following:
tutorials we’ve focused on creating physical projects $ sudo apt-get update
that can be interacted with, but this time we’ll delve into the $ sudo apt-get upgrade
world of music using Sonic Pi. This is the personal project of If you are prompted to confirm installation, please do so.
Dr. Sam Aaron and the goal of Sonic Pi is to introduce With Sonic Pi installed you can find the application in the
creativity into programming via music and reduce the friction ‘Programming’ menu. Open the interface and you’ll see that
that’s encountered by children learning to code, eg the the interface is split into three vertically tiled panes. The top
alignment and indentation of code and syntax errors. pane contains a row of buttons that are used to control the
Sonic Pi uses the Ruby programming language created in playback of your composition, save the composition to a file
the mid 1990s by Yukihiro “Matz” Matsumoto, which was an and also record the audio to a WAV file. Further buttons are
easy to learn and syntax-friendly alternative to the languages used to reduce the text size of your code, align and indent
of that time. Sonic Pi refines the Ruby language to provide a code automatically and access the Help/Preferences system.
number of easy to use functions that enable learning. In this The centre pane contains the area in which code is written,
tutorial we’ll learn the basics of Sonic Pi and then consolidate which is split into a series of workspaces enabling you to write
that knowledge with a piece of music. multiple compositions or test logic in a spare workspace.
Sonic Pi comes preinstalled with Raspbian but if you have To the right of the code area is the Preferences area where
an older installation it’s possible that your version of Sonic Pi configuration changes can be made at the bottom. We also

Quick
tip
Sonic Pi has a great
auto-alignment
tool, so if your code
gets into a pickle,
click on the ‘Align’
button to ensure
that everything is
where it should be.

The Sonic Pi
interface has
been designed
to offer a
frictionless
approach to
composition
using code.

36 | Coding Made Simple


Coding | SonicPi
Live coding!
Dr. Sam Aaron is a bright and bubbly individual unique performances, where the audience can Perera used data sonification. However, this
who knows his craft well and loves to show see the code transform to match the tone and wasn’t a real-time project, which opens the door
others, so it’s no surprise that he’s a big pace of the music. for Sonic Pi to be used with open data in a live
advocate for Live Coding, the practice of coding At the recent OpenTech event in London, we coding exhibition. Data from a number of
in front of a live audience. Sam is part of the saw open data, in the form of natural disaster sources, such as The Guardian, Met Office and
band Meta-ex (http://meta-ex.com), along data, being used to shape the notes used in a UK government can be ‘mashed’ into a live
with Jonathan Graham. Together they merge rather eclectic piece of music. The piece coding musical composition that can illustrate
coding with musical instruments to create co-produced by Leah Borromeo and Jamie the subject of the data being used.

have the help area which contains extensive help use_synth :dsaw At the top
documentation and example compositions. play :c4 of the user
Lets start our musical adventure by playing a note. In the sleep 1 interface are a
coding pane type RUBY//play 60 . Now press ‘Run’ on the top end series of buttons
pane. You should hear the note briefly play. What does 60 Click on ‘Run’ and you will hear the c4 note played once to control the
playback and
mean? Well it refers to the MIDI (Musical Instrument Digital per second until ‘Stop’ is pressed. But what if we want to
recording of
Interface) numbering scheme, which is used in professional iterate a loop for a set number of times? Ruby has an easy
your code and
music production to cover the protocol by which data is sent way to do this: to align or resize
to and from computers and digital instruments, but it also 2.times do the code to meet
covers the connection made between the devices. The 60 use_synth :dsaw your needs.
note refers to a C4 note, but we can just use the name of the play :c4
note instead so RUBY//play :c4 . sleep 1
If we wanted to play a series of notes then we could type end
out something like: Another kind of loop is a live_loop. This is an infinite loop
play :c4 to be used when live coding a performance. Changes made to
sleep 1 code inside of a live_loop don’t instantly take effect rather Quick
play :g4 they require the user to press ‘Run’ to instigate the changes tip
sleep 1 the next time the loop is run. Live_loops enable the user to
Sam has written a
play :d4 create concurrency where multiple segments of code are 30000 help tutorial
sleep 1 working together to form the backdrop of our music. The that is inside Sonic
This is a correct but rather long-winded approach. Instead, syntax for a live_loop is similar to a standard loop but requires Pi, the tutorial walks
Sonic Pi enables you to play patterns of notes in the same a name to be given to the loop, so lets create a loop named through each of
the computational
manner with: beat that incorporates the play_pattern function that we
concepts and the
play_pattern [ :c4, :g4, :d4 ] learnt earlier. Then press ‘Run’ to play. musical concepts
Perhaps the notes are a little too slow for you? Well, Sonic live_loop :beat do used to create
Pi has you covered. To speed up the playback of a use_synth :dsaw compositions. You
composition, we can set the Beats Per Minute (BPM) for play_pattern [ :c4, :g4, :d4 ] can find the tutorial
in the help section
playing that pattern of notes faster: sleep 1 at the bottom of
use_bpm 240 end the screen.
play_pattern [ :c4, :g4, :d4 ] Change the c4 note for a f4 note and click ‘Run’, you
should hear the note change in pitch accordingly. We can also
Using synths play a pattern backwards using Ruby’s handy .reverse
So we can play a series of notes, but right now it’s not very function like so:
exciting so let’s introduce another feature of Sonic Pi: synths. live_loop :beat do
Synths enable a note to be played with many different use_synth :dsaw
instruments, similar to electronic keyboards and other digital play_pattern [ :c4, :g4, :d4 ].reverse
instruments. So lets alter our code to use a synth: sleep 1
use_synth :dsaw end
play :c4 As well as playing notes forward and backwards we can
Press ‘Run’ to hear the difference. So now that we can play also play random notes using two functions:
a note with a synth, lets put it into a loop to repeat playback. play rrand(50, 100)
Sonic Pi can create an infinite loop using the loop do...end play rrand_i(50, 100)
construct. Any code inside the loop will repeat forever. The first rrand can play any note between 50 and 100
To ensure that your code is properly indented click on the including any floating point MIDI values, but the second
Align button in the top pane to automatically align the code: rrand_i can only play integer based MIDI values between 50
loop do and 100.

Coding Made Simple | 37


Coding | SonicPi

A common practice in programming is to create a function sample :loop_amen


into which we can contain a block of code, then when we wish sleep sample_duration :loop_amen
to use this code we merely call the function by its name: end
define :loopy do The sleep statement for this loop is unusual as it doesn’t
use_bpm 480 have an integer or float value visible. Rather we instruct Sonic
use_synth :dsaw Pi to learn the duration of the sample used and use that as
play_pattern [ :c3, :c4, :c5, :c6 ] the sleep value.
sleep 0.5
end Building our tune
live_loop :testy do Now that we have the basics under our belt let’s start building
loopy our composition. Click on a blank Workspace and start your
end piece by creating a live_loop called beat. This will contain the
In our example, we create a function called loopy and use code that forms the beat of our piece. Let’s put a sample
the do...end construct to store the code that will set the BPM inside the live_loop. When completed press ‘Run’ to hear
to 480 beats per minute, and play a pattern using dsaw the beat.
synth , before sleeping for half a second. Inside a live_loop we live_loop :beat do
call the function loopy by its name and the code contained sample :bd_haus
inside is run. sleep 0.5
Our last Sonic Pi concept we’ll introduce is samples. These end
are segments of audio that are pre-recorded and in the music So our beat is a sample played two times per second so
industry they are used often to embellish a song using clips that’s a BPM of 120, which is quite quick and punchy. Let’s
from classic songs. To use a sample in a new live_loop we’ll build upon the beat by creating another live_loop which will
need to recreate the following code below the existing live_ contain a melody. Before we start the live_loop we will add
loop :beat : some FX to our audio. To do this, we’ll use the fx plugin reverb
live_loop :samples do to add a spacious feel to the notes. We pass the room 1

Sonic Pi
has multiple
workspaces and
these can be
used as scratch
pads to test
out loops and
compositions
or they can be
used to create
multiple layers
to a track when
played together.

Minecraft in the mix!


Minecraft on the Raspberry Pi has become the At the time of writing this is still a bleeding Minecraft functionality to be added to any
killer app to teach Python to classes and Sonic edge feature but there’s a great deal of previously written Sonic Pi compositions.
Pi has attained the same status for it’s use of functionality, such as getting the position of the To use Sonic Pi with Minecraft just open the
music. But what if there were a way to merge the player or a block, changing the position of the Minecraft application, load a world, and open
musicality of Sonic Pi with the fun of building new player and block type and posting data to the Sonic Pi 2.5 and choose a Minecraft function to
worlds in Minecraft? Well, now there is and from chat window. The syntax is exceptionally easy trigger the connection, eg the chat window:
version 2.5 of Sonic Pi you can also integrate to pick up and integrates seamlessly into the mc_chat_post(“Hello World”)
Minecraft into your musical compositions. standard Sonic Pi syntax structure enabling Run the code and hey presto you’re connected.

38 | Coding Made Simple


Coding | SonicPi
argument to instruct Sonic Pi to use the maximum-sized play sound.choose, detune: 6, release: 0.1, amp: 0.5, Sonic Pi
room available, in other words this gives the sound the cutoff: rrand(70, 80) comes with a
maximum available spacious sound. This melody will use the sleep 0.125 few examples
synth beep for any notes played. end that you can
end paste into the
Using FX plugins end
workspaces. Try
them out and
We then add a seed to the mix which changes the starting Press ‘Run’ to play the composition. Remember that you
learn how each
point for any random numbers generated by Sonic Pi. can alter the random seed to produce a different sound. of the synths,
Numbers generated using random are never truly random You can also alter the scale of notes, by changing g3 to samples and FX
merely chaotic in nature. We used 66678 as our starting point another scale, g5, c4 etc. You can alter the major_pentatonic plugins can help
but try other numbers to see how the composition changes. to a minor_pentatonic to produce a much darker and more enhance your
Next, we create a variable called sound and in there we store sorrowful tone. music projects.
a scale of notes in the key of g3. Next, we instruct Sonic Pi to Our next live_loop is used to create an ambience to the
perform the next bank of code 16 times, so it chooses the composition and, again, we shall use an FX plugin. This time
notes from sound variable and then uses a number of it’s going to be ixi_techno a low-pass filter between the
arguments to achieve the following: detunes the notes to minimum and maximum cutoffs. We shall call the loop
create a slightly off sound to each note; alters the fade out ambience and first off it will perform a block of code eight
and release of the note so that it fades quickly; and amp times. Using the hollow synth, we shall play the note c3 with
controls the level of the note played – in this case it’s half the an amplitude of 0.5, putting the note into the mid-tone mix of
volume relative to the others. Last, we modify the cutoff to our composition. We then wait for one second before entering Quick
use a random note between 70 and 80 to cut off certain into another loop that iterates eight times. But this time it tip
frequencies. We now instruct the code to wait for 0.125 plays the ambi_choir, a haunting choir sound, at standard Sonic Pi is all about
seconds. Last as we have opened three loops using do we speed but mixed down into the composition so that it experimentation so
must close them correctly: appears as background noise. We then sleep for one seconds free your mind of
any logic and just
with_fx :reverb, room: 1 do before closing the four loops that have been created:
write what feels
live_loop :melody do with_fx :ixi_techno do natural. Sonic Pi
use_synth :beep live_loop :ambience do is a musical tool
use_random_seed 66678 8.times do that just happens
sound = (scale :g3, :major_pentatonic, num_octaves: 3) use_synth :hollow to be based on
programming.
16.times do play :c3, amp: 0.5
sleep 1
8.times do
sample :ambi_choir, rate: 1, amp: 0.2
sleep 1
end
end
end
end
Click on ‘Run’ to hear the composition. Does it need
tweaking to match your goal? Try changing the sample
playback rate from 1 to 0.5 or to 2 for different results.
So using Sonic Pi and some simple coding we have
managed to create a looping piece of audio that can be
recorded using the ‘Record’ button and uploaded to
SoundCloud or used in your YouTube videos.
All of the code for this little Sonic Pi project can be
accessed in our GitHub repository, which can be found at
The Preferences area has everything you need to control https://github.com/lesp/LXF201---Sonic-Pi or you can
the output of audio and various debug and editor options. download a ZIP file containing all of the code from here:
There’s also a log to show the output of your composition. http://bit.ly/LXF201-SonicPi. ■

Coding Made Simple | 39


Coding | Ruby & Sonic Pi

Ruby: Compose
random music
Let’s look at how we can learn a little Ruby while programming a Raspberry
Pi and composing a random piece of music with Sonic Pi.

W
hen we think of the languages that we can use Next, we’ll use two coding concepts on this line of code:
with our Raspberry Pi we naturally think of a loop to repeat the note and a variable:
Scratch and Python. But Ruby, the popular pace = 1
language created by Yukihiro “Matz” Matsumoto, is used to loop do
power the Sonic Pi, the live coding synth, and is also another play 60
viable language to learn. In this tutorial, we’ll run through a sleep pace
few coding practices that are powered by Ruby using the end
Sonic Pi application. We’ll use variables to store data; loops to The variable pace is used to store a numerical value,
repeat the project; arrays to store patterns of notes; and we’ll either an integer or a float. Using this method we can create
use conditionals to change the music based on a test. By the one place that will store the value used to pace our project.
end of this project you will create something unique; it might Rather than hard code the values across the project. Looking
not be music as we understand it, but it will be your first step at the loop, we start it using do and close it with end . This is
in generating music using random number generation. an important thing to remember as every loop must be
For this project you can use any model of Raspberry Pi opened and closed correctly. In this example our loop will
and you’ll need audio on your TV (or a 3.5mm set of run indefinitely.
speakers) and the latest version of Raspbian Jessie. All the
project code is at http://bit.ly/LXF208Randomness. Pace and threads
We’ll start by booting up our Pi to the desktop and then To change the pace of the project, you simply change the
opening the Sonic Pi application, which you can find in the value of pace so, eg if it’s less than 1, using a float number
Programming menu. After a few seconds Sonic Pi will be such as 0.3, will make it really fast. In the example (below)
ready for use. Sonic Pi uses a series of buffers to store your we’ve added two more lines after line four, but before the end
code, in buffer 0 we shall start writing some Ruby. of the loop:
Our first line of code plays a note, Sonic Pi uses MIDI play 70
(Musical Instrument Digital Interface) numbers to represent a sleep pace
note, so for the C note we shall use 60: play 60 .
Go ahead and click ‘Run’ when done, if you cannot hear Next, let’s add some code to contain our loop in a thread.
anything, click on the Prefs menu and alter the audio output In Ruby we can easily thread procedures so that we can run
to match your device. You should hear a ‘bong’ note. code in multiple ways. In Sonic Pi we use this to create layers
to the music generated.
Our code will now look like this, remember that if we start
a loop with do we must end it, and the same principle applies
to threads:
Quick pace = 0.3
tip in_thread do
Ruby is an loop do
awesome language play 60
and is a great
sleep pace
introduction to
typed languages. play 70
If you need any sleep pace
help when using end
Sonic Pi, musically
end
or computational
logic, then Sonic We’ll now go on to create another thread which will
Pi has a great help contain another set of notes. In this case we’ll copy and paste
system, located in Sonic Pi has a great clean interface that promotes explo- the original thread and change the pitch of the note so that
the bottom left of it’s lower.
ration. This is mirrored by the exceptionally clean and easy
the screen.
to read Ruby code in the editor. in_thread do

40 | Coding Made Simple


Coding | Ruby & Sonic Pi
Sonic Pi Minecraft
Sonic Pi is a great way to introduce Ruby our composition, eg we can teleport
to children, but as we know, many Steve two blocks into the air, and this will
children are hooked on Minecraft and happen to the beat of the music by
spend copious amounts of time playing adding mc_teleport(0,2,0) .
the game. But did you know that Sonic Pi Thanks to James Robinson from the
can also be used to control Minecraft, in Raspberry Pi Foundation, the Sonic Pi
a similar manner to the Python library? can be set to react to input in the
For this you’ll need both Minecraft and Minecraft world as he’s written a
Sonic Pi open. This is possible on all keyboard game where the player
Raspberry Pis but for the best results composes music using a Minecraft
come use the Pi 2. In Sonic Pi we can keyboard. Sonic Pi has a help section Kids Ruby is a great application and can help anyone
integrate the Minecraft commands into that covers the Minecraft functionality. take their first steps with Ruby.

loop do Play the music and have a listen.


play 50 Our final thread is the most ambitious, we’ll use a loop to
sleep pace continually check the value of a variable against a series of if..
play 55 elsif..else conditions. If the value of the variable tests correctly
sleep pace against a condition then the code contained therein is run:
end in_thread do
end loop do
So now we have two threads working together to make a with_fx :reverb do
beat. For our next experiment we will use a random number random = rand_i(100)
to change the pitch of a note. We’ll use rand_i(70) to choose if random > 75 then
a random number between 0 and 70. We shall also use one of use_synth :dull_bell
the many instruments available in Sonic Pi, known as synths, play random
to alter the sound of our music. In this case we’ll use dsaw, a sleep 0.2
digital saw/droning noise. So for the second thread our code elsif random > 50 and random < 75 then
now looks like this: use_synth :pulse
in_thread do play random
loop do sleep 0.2
use_synth :dsaw else
play 50 use_synth :piano
sleep pace play random
play rand_i(70) sleep 0.2
sleep pace end
end end
end end
What this will do is create a subtly different tune each time end
the music is played through. Here we’ve created a new variable called random and
Now let’s add another thread to our project, which will used that to store a random integer between 0 and 100. We
allow us to add another layer to the cacophony of sound that then use the conditional statements to check the value of the
we are creating. This thread uses another loop, and plays variable random and if it is over 75 then the instrument is
any notes using a synth called ‘blade’, which is reminiscent changed to dull_bell and the music note is played. The loop
of Vangelis’ work on the Blade Runner movie soundtrack. repeats and the random number is compared again. If it fails
What we will do differently this time is the method of playing to match the two tests, then the else condition is enabled and
our notes. the piano synth is chosen to play the note.
Before we’ve asked Sonic Pi to play a note then sleep, and So there we have it. Using programming logic, some
this can become unwieldy rather quickly. So we shall use a random numbers and the Sonic Pi, we’ve created a tune that
function called play_pattern_timed which takes two has been written by a computer using random numbers. ■
conditions: an array used to store the notes that we wish to
play and accepts a condition to control the timing of the
notes, in this case we use the pace variable that we created
earlier. Your new thread should look like this:
in_thread do
loop do
use_synth :blade
play_pattern_timed [70,72,74],[pace]
end The Sonic Pi has a great help system that covers both the coding and musical
end composition of a project. Take a look for inspiration when you get stuck.

Coding Made Simple | 41


Coding | Sonic Pi

Python: Sonic Pi
hardware control
We find a way to link Python to a Sonic Pi, though not a way to write a
guaranteed No.1 single (or get on the X Factor).

M
aking music with your Raspberry Pi is easy thanks play(D5)
to Sonic Pi. But what if we could control the GPIO sleep(1)
pins at the same time? Using components, such as play(G5)
buttons or sensors to shape the performance of our tune sleep(1)
would add an extra dimension to compositions. For this Save your code and click on Run > Run Module to play.
tutorial you’ll need: any model of Raspberry Pi running the You should hear three short notes played with a one second
latest Raspbian distribution (distro); an internet connection; gap between them. If you can’t hear the notes ensure you’ve
three LEDs; a breadboard (remove the loaf first); three chosen the correct audio playback device from the
330Ohm resistors; and three momentary switches. All of the Preferences menu and the main system Volume Control,
code for this project can be downloaded from http://bit.ly/ found by right-clicking on the speaker icon in the top right of
LXF211SonicSampler and you can download a diagram of the Raspbian desktop.
the pin layout http://bit.ly/LXF211SonicSamplerDiagram. We’ll continue working in the gpio-sonic-sampler.py file
To use Python Sonic, we need to enable communication that we’ve just created but start by deleting all of the code
between Python and Sonic Pi. In a terminal type: we’ve just written. Our first section will import the modules
$ pip install python-osc that enable our project to work. These are gpiozero, which is
We’ll also need to download a ZIP file (https://github. used when working with the GPIO – in our case specifically
com/gkvoelkl/python-sonic/archive/master.zip) that working with LEDs and buttons – and psonic, which is our link
contains the library that will add the functionality for this to Sonic Pi. We also import the time module, used to pace our
project. Download it to your Pi and extract the contents using project. Last, we import the uniform function from the
the Archive application. Once extracted to a directory, random module, this will be used later in our project.
navigate to that directory. The file that we require for our from psonic import *
project is called psonic.py and this is a Python library. Using from gpiozero import LED, Button
the main menu open the Sonic Pi application and when it has import time
finished opening minimise Sonic Pi, as we don’t need to from random import uniform
access it anymore for the project. From the main menu, click We now create three variables, these will be used to
on Programming > Python 3. When Python 3 appears click on contain the GPIO pin used for each corresponding LED. In this
File > New File to open a new document. Immediately save case Red, Yellow and Green. These LEDs help us identify
using File > Save calling your project gpio-sonic-sampler.py which note is being played. Using the LED class from gpiozero
and ensure that it’s saved in the same directory as psonic.py. enables us to control the LEDs without configuring the GPIO
We’ll start by testing that the connection to Sonic Pi is pin, which is the opposite to how RPi.GPIO works.
working. In the document type the following: red = LED(5)
from psonic import * yellow = LED(6)
play(C5) green = LED(13)
sleep(1) Next, we create three more variables for containing the
location of our buttons. The Button class from gpiozero is pre-
configured so that the GPIO pin used for the button is pulled
high—in other words it has current applied to it. The two
connections to the GPIO – from the button to Ground and the
GPIO pin – are connected together when the button is
pressed, causing the GPIO pin state to change from high to
Using Python low, giving us the trigger we need to execute our code.
to control
button1 = Button(2)
Sonic Pi gives
button2 = Button(3)
direct access
to the music, button3 = Button(4)
rather than We now start the main body of code, and use an infinite
pre-recorded loop to constantly run our code with:
samples. while True :

42 | Coding Made Simple


Coding | Sonic Pi
GPIO Zero
The Raspberry Pi is well known for its GPIO, members to create a new module for interacting GPIO Zero is constantly evolving and the team
General Purpose Input Output, pins. These pins with the GPIO. Not a module that would replace are open to suggestions and help. If you would
were added to enable the Pi to be merged with RPi.GPIO, rather introduce the GPIO in a more like to learn more or download the latest version
electronics projects and to read and control friendly manner. GPIO Zero (gpiozero) is that of the module, then head over to the project
devices. The main module to interact with the module and it comes with a number of classes page on GitHub https://github.com/RPi-
GPIO is called RPi.GPIO and for many years this that enable easy access to the GPIO. The classes Distro/python-gpiozero.
has been the default library. While being provide a two-line configuration of LEDs and
relatively easy to use for those familiar with buttons. Sensors such as PIR and LDR can be
Python, RPi.GPIO can seem daunting to new handled without multiple lines of configuration.
users and there are a number of steps to The team are currently working on a simpler
configure and use the pins. method of using ultrasonic sensors, commonly
In mid 2015, Ben Nuttall (spelt with two ‘l’s), found in robotics projects, with GPIO Zero. Both
community manager at the Raspberry Pi GPIO Zero and RPi.GPIO are pre-installed on the
Foundation got together with a few community Raspbian operating system.

if button1.is_pressed: print(“Button 2 is Pressed”)


time.sleep(0.3) yellow.on() Quick
print(“Button 1 Pressed”) play(G5) tip
red.on() For this second condition we check the status of button2 Not sure of the
sample(LOOP_AMEN, rate=uniform(0.5,2)) and if pressed we pause the code for a tenth of a second names for all
Inside the while True loop we create four conditions to (0.1) , print the status to the Python shell, turn on the yellow of the samples,
synths and effects
test. Each one is used to see if a button has been pressed. LED and play note G5 in Sonic Pi. The code for button3 is
in Python Sonic?
When this condition is true, the corresponding code is run. identical to button2 except we play note D5 instead. Want to hear
Our first condition checks the status of button1 . If the button Our last condition to test is else : them quickly?
is pressed we pause the code for 0.3 seconds and print that else: No problem, open
up Sonic Pi and
the button has been pushed to the Python shell. This is a red.off()
try a few out in a
handy step to add when debugging a project. Next, we turn on yellow.off() spare buffer.
the red LED attached to GPIO5 before we call Sonic Pi to play green.off()
the LOOP_AMEN sample. The playback speed of the loop is This condition requires no further arguments, as it’s
controlled using rate . We’re using the uniform function from implied that this condition must be true if all of the others are
the random module to choose a random float value between false, and simply turns off all of the LED, indicating that none
0.5 and 2. So sometimes the sample is played at high speed of the buttons have been pressed.
and other times it’s stretched and played slowly. With the code now written, save your work and then click
elif button2.is_pressed: on Run > Run Module to start the project. Get ready to rock
time.sleep(0.1) using GPIO Zero, Python Sonic and Sonic Pi! ■

The circuit for


this project is
rather simple,
and is nothing
more than three
buttons and
three LEDs wired
to GPIO pins and
Ground. Despite
this simplicity
it’s fiendishly
hackable!

Coding Made Simple | 43


rubyracer”, “~> 0.11.4” group :development, :test do gem “rspec-rails”, “~> 2.13.0” $ gem install bundler $ gem install rails --version=3.2.12 $ rbenv rehash $ rails
ate_attributes(params[:task]) format.html { redirect_to @task, notice: ‘...’ } format.json { head :no_content } else format.html { render action: “edit” } format.json { ren
xec rails generate migration add_priority_to_tasks priority:integer $ bundle exec rake db:migrate $ bundle exec rake db:migrate $ bundle exec rails server validate
_at, ‘is in the past!’) if due_at < Time.zone.now #!/usr/bin/en python import pygame from random import randrange MAX_STARS = 100 pygame.init() screen = py
tars = for i in range(MAX_STARS): star = [randrange(0, 639), randrange(0, 479), randrange(1, 16)] stars.append(star) while True: clock.tick(30) for event in pygame
$numstars = 100; use Time::HiRes qw(usleep); use Curses; $screen = new Curses; noecho; curs_set(0); for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] = rand(80); $s
>clear; for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] -= $star_s[$i]; if ($star_x[$i] < 0) { $star_x[$i] = 80; } $screen->addch($star_y[$i], $star_x[$i], “.”); } $screen->refre
ment, :test do gem “rspec-rails”, “~> 2.13.0” $ gem install bundler $ gem install rails --version=3.2.12 $ rbenv rehash $ rails new todolist --skip-test-unit respond
ml { redirect_to @task, notice: ‘...’ } format.json { head :no_content } else format.html { render action: “edit” } format.json { render json: @task.errors, status: :unpro
rity_to_tasks priority:integer $ bundle exec rake db:migrate $ bundle exec rake db:migrate $ bundle exec rails server validate :due_at_is_in_the_past def due_at_is_
one.now #!/usr/bin/en python import pygame from random import randrange MAX_STARS = 100 pygame.init() screen = pygame.display.set_mode((640, 480)) c
star = [randrange(0, 639), randrange(0, 479), randrange(1, 16)] stars.append(star) while True: clock.tick(30) for event in pygame.event.get(): if event.type == pyg
Res qw(usleep); use Curses; $screen = new Curses; noecho; curs_set(0); for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] = rand(80); $star_y[$i] = rand(24); $star_s[$i]
rs ; $i++) { $star_x[$i] -= $star_s[$i]; if ($star_x[$i] < 0) { $star_x[$i] = 80; } $screen->addch($star_y[$i], $star_x[$i], “.”); } $screen->refresh; usleep 50000; gem “theru
ils”, “~> 2.13.0” $ gem install bundler $ gem install rails --version=3.2.12 $ rbenv rehash $ rails new todolist --skip-test-unit respond_to do |format| if @task.update_
.’ } format.json { head :no_content } else format.html { render action: “edit” } format.json { render json: @task.errors, status: :unprocessable_entity } $ bundle exec rails
exec rake db:migrate $ bundle exec rake db:migrate $ bundle exec rails server validate :due_at_is_in_the_past def due_at_is_in_the_past errors.add(:due_at, ‘is in th
ygame from random import randrange MAX_STARS = 100 pygame.init() screen = pygame.display.set_mode((640, 480)) clock = pygame.time.Clock() stars = for i in ran
drange(1, 16)] stars.append(star) while True: clock.tick(30) for event in pygame.event.get(): if event.type == pygame.QUIT: exit(0) #!/usr/bin/perl $numstars = 100;
oecho; curs_set(0); for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] = rand(80); $star_y[$i] = rand(24); $star_s[$i] = rand(4) + 1; } while (1) { $screen->clear; for ($i = 0; $i <
ar_x[$i] = 80; } $screen->addch($star_y[$i], $star_x[$i], “.”); } $screen->refresh; usleep 50000; gem “therubyracer”, “~> 0.11.4” group :development, :test do gem “rsp
sion=3.2.12 $ rbenv rehash $ rails new todolist --skip-test-unit respond_to do |format| if @task.update_attributes(params[:task]) format.html { redirect_to @task, noti

CODING
ction: “edit” } format.json { render json: @task.errors, status: :unprocessable_entity } $ bundle exec rails generate migration add_priority_to_tasks priority:integer $ b
exec rails server validate :due_at_is_in_the_past def due_at_is_in_the_past errors.add(:due_at, ‘is in the past!’) if due_at < Time.zone.now #!/usr/bin/en python impo
game.init() screen = pygame.display.set_mode((640, 480)) clock = pygame.time.Clock() stars = for i in range(MAX_STARS): star = [randrange(0, 639), randrange(0, 47
or event in pygame.event.get(): if event.type == pygame.QUIT: exit(0) #!/usr/bin/perl $numstars = 100; use Time::HiRes qw(usleep); use Curses; $screen = new Curs
$i] = rand(80); $star_y[$i] = rand(24); $star_s[$i] = rand(4) + 1; } while (1) { $screen->clear; for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] -= $star_s[$i]; if ($star_
i], “.”); } $screen->refresh; usleep 50000; gem “therubyracer”, “~> 0.11.4” group :development, :test do gem “rspec-rails”, “~> 2.13.0” $ gem install bundler $ gem
-skip-test-unit respond_to do |format| if @task.update_attributes(params[:task]) format.html { redirect_to @task, notice: ‘...’ } format.json { head :no_content } else form

MADE
rors, status: :unprocessable_entity } $ bundle exec rails generate migration add_priority_to_tasks priority:integer $ bundle exec rake db:migrate $ bundle exec rake d
ast def due_at_is_in_the_past errors.add(:due_at, ‘is in the past!’) if due_at < Time.zone.now #!/usr/bin/en python import pygame from random import randrange MA
e((640, 480)) clock = pygame.time.Clock() stars = for i in range(MAX_STARS): star = [randrange(0, 639), randrange(0, 479), randrange(1, 16)] stars.append(star) wh
e == pygame.QUIT: exit(0) #!/usr/bin/perl $numstars = 100; use Time::HiRes qw(usleep); use Curses; $screen = new Curses; noecho; curs_set(0); for ($i = 0; $i <
$star_s[$i] = rand(4) + 1; } while (1) { $screen->clear; for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] -= $star_s[$i]; if ($star_x[$i] < 0) { $star_x[$i] = 80; } $screen->add
em “therubyracer”, “~> 0.11.4” group :development, :test do gem “rspec-rails”, “~> 2.13.0” $ gem install bundler $ gem install rails --version=3.2.12 $ rbenv rehash $

SIMPLE
update_attributes(params[:task]) format.html { redirect_to @task, notice: ‘...’ } format.json { head :no_content } else format.html { render action: “edit” } format.json {
exec rails generate migration add_priority_to_tasks priority:integer $ bundle exec rake db:migrate $ bundle exec rake db:migrate $ bundle exec rails server validate
_at, ‘is in the past!’) if due_at < Time.zone.now #!/usr/bin/en python import pygame from random import randrange MAX_STARS = 100 pygame.init() screen = py
tars = for i in range(MAX_STARS): star = [randrange(0, 639), randrange(0, 479), randrange(1, 16)] stars.append(star) while True: clock.tick(30) for event in pygame
$numstars = 100; use Time::HiRes qw(usleep); use Curses; $screen = new Curses; noecho; curs_set(0); for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] = rand(80); $s
>clear; for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] -= $star_s[$i]; if ($star_x[$i] < 0) { $star_x[$i] = 80; } $screen->addch($star_y[$i], $star_x[$i], “.”); } $screen->refre
ment, :test do gem “rspec-rails”, “~> 2.13.0” $ gem install bundler $ gem install rails --version=3.2.12 $ rbenv rehash $ rails new todolist --skip-test-unit respond
ml { redirect_to @task, notice: ‘...’ } format.json { head :no_content } else format.html { render action: “edit” } format.json { render json: @task.errors, status: :unpro
rity_to_tasks priority:integer $ bundle exec rake db:migrate $ bundle exec rake db:migrate $ bundle exec rails server validate :due_at_is_in_the_past def due_at_is_
one.now #!/usr/bin/en python import pygame from random import randrange MAX_STARS = 100 pygame.init() screen = pygame.display.set_mode((640, 480)) c
star = [randrange(0, 639), randrange(0, 479), randrange(1, 16)] stars.append(star) while True: clock.tick(30) for event in pygame.event.get(): if event.type == pyg
Res qw(usleep); use Curses; $screen = new Curses; noecho; curs_set(0); for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] = rand(80); $star_y[$i] = rand(24); $star_s[$i]
rs ; $i++) { $star_x[$i] -= $star_s[$i]; if ($star_x[$i] < 0) { $star_x[$i] = 80; } $screen->addch($star_y[$i], $star_x[$i], “.”); } $screen->refresh; usleep 50000; gem “theru
ils”, “~> 2.13.0” $ gem install bundler $ gem install rails --version=3.2.12 $ rbenv rehash $ rails new todolist --skip-test-unit respond_to do |format| if @task.update_
.’ } format.json { head :no_content } else format.html { render action: “edit” } format.json { render json: @task.errors, status: :unprocessable_entity } $ bundle exec rails
exec rake db:migrate $ bundle exec rake db:migrate $ bundle exec rails server validate :due_at_is_in_the_past def due_at_is_in_the_past errors.add(:due_at, ‘is in th
ygame from random import randrange MAX_STARS = 100 pygame.init() screen = pygame.display.set_mode((640, 480)) clock = pygame.time.Clock() stars = for i in ran
drange(1, 16)] stars.append(star) while True: clock.tick(30) for event in pygame.event.get(): if event.type == pygame.QUIT: exit(0) #!/usr/bin/perl $numstars = 100;
oecho; curs_set(0); for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] = rand(80); $star_y[$i] = rand(24); $star_s[$i] = rand(4) + 1; } while (1) { $screen->clear; for ($i = 0; $i <
ar_x[$i] = 80; } $screen->addch($star_y[$i], $star_x[$i], “.”); } $screen->refresh; usleep 50000; gem “therubyracer”, “~> 0.11.4” group :development, :test do gem “rsp
sion=3.2.12 $ rbenv rehash $ rails new todolist --skip-test-unit respond_to do |format| if @task.update_attributes(params[:task]) format.html { redirect_to @task, noti
ction: “edit” } format.json { render json: @task.errors, status: :unprocessable_entity } $ bundle exec rails generate migration add_priority_to_tasks priority:integer $ b
exec rails server validate :due_at_is_in_the_past def due_at_is_in_the_past errors.add(:due_at, ‘is in the past!’) if due_at < Time.zone.now #!/usr/bin/en python impo
game.init() screen = pygame.display.set_mode((640, 480)) clock = pygame.time.Clock() stars = for i in range(MAX_STARS): star = [randrange(0, 639), randrange(0, 47
or event in pygame.event.get(): if event.type == pygame.QUIT: exit(0) #!/usr/bin/perl $numstars = 100; use Time::HiRes qw(usleep); use Curses; $screen = new Curs
$i] = rand(80); $star_y[$i] = rand(24); $star_s[$i] = rand(4) + 1; } while (1) { $screen->clear; for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] -= $star_s[$i]; if ($star_
i], “.”); } $screen->refresh; usleep 50000; gem “therubyracer”, “~> 0.11.4” group :development, :test do gem “rspec-rails”, “~> 2.13.0” $ gem install bundler $ gem
-skip-test-unit respond_to do |format| if @task.update_attributes(params[:task]) format.html { redirect_to @task, notice: ‘...’ } format.json { head :no_content } else form
rors, status: :unprocessable_entity } $ bundle exec rails generate migration add_priority_to_tasks priority:integer $ bundle exec rake db:migrate $ bundle exec rake d
ast def due_at_is_in_the_past errors.add(:due_at, ‘is in the past!’) if due_at < Time.zone.now #!/usr/bin/en python import pygame from random import randrange MA
e((640, 480)) clock = pygame.time.Clock() stars = for i in range(MAX_STARS): star = [randrange(0, 639), randrange(0, 479), randrange(1, 16)] stars.append(star) wh
e == pygame.QUIT: exit(0) #!/usr/bin/perl $numstars = 100; use Time::HiRes qw(usleep); use Curses; $screen = new Curses; noecho; curs_set(0); for ($i = 0; $i <
$star_s[$i] = rand(4) + 1; } while (1) { $screen->clear; for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] -= $star_s[$i]; if ($star_x[$i] < 0) { $star_x[$i] = 80; } $screen->add
em “therubyracer”, “~> 0.11.4” group :development, :test do gem “rspec-rails”, “~> 2.13.0” $ gem install bundler $ gem install rails --version=3.2.12 $ rbenv rehash $
s new todolist --skip-test-unit respond_to do |format| if @
nder json: @task.errors, status: :unprocessable_entity } $
:due_at_is_in_the_past def due_at_is_in_the_past errors.

Coding basics | Contents


ygame.display.set_mode((640, 480)) clock = pygame.time.
e.event.get(): if event.type == pygame.QUIT: exit(0) #!/usr/
star_y[$i] = rand(24); $star_s[$i] = rand(4) + 1; } while (1) {
esh; usleep 50000; gem “therubyracer”, “~> 0.11.4” group
d_to do |format| if @task.update_attributes(params[:task])
ocessable_entity } $ bundle exec rails generate migration
_in_the_past errors.add(:due_at, ‘is in the past!’) if due_at
clock = pygame.time.Clock() stars = for i in range(MAX_

Coding basics
game.QUIT: exit(0) #!/usr/bin/perl $numstars = 100; use
= rand(4) + 1; } while (1) { $screen->clear; for ($i = 0; $i <
rubyracer”, “~> 0.11.4” group :development, :test do gem
_attributes(params[:task]) format.html { redirect_to @task,
s generate migration add_priority_to_tasks priority:integer
he past!’) if due_at < Time.zone.now #!/usr/bin/en python
nge(MAX_STARS): star = [randrange(0, 639), randrange(0,
Everything you need to start
use Time::HiRes qw(usleep); use Curses; $screen = new coding today
< $numstars ; $i++) { $star_x[$i] -= $star_s[$i]; if ($star_x[$i]
pec-rails”, “~> 2.13.0” $ gem install bundler $ gem install
ice: ‘...’ } format.json { head :no_content } else format.html Get started with Linux ������������������������������������� 46
bundle exec rake db:migrate $ bundle exec rake db:migrate
ort pygame from random import randrange MAX_STARS Mint and Python ��������������������������������������������������������������� 50
79), randrange(1, 16)] stars.append(star) while True: clock.
ses; noecho; curs_set(0); for ($i = 0; $i < $numstars ; $i++)
Get started with IDEs ������������������������������������������� 52
_x[$i] < 0) { $star_x[$i] = 80; } $screen->addch($star_y[$i],
m install rails --version=3.2.12 $ rbenv rehash $ rails new
Python lists ������������������������������������������������������������������������������������� 54
mat.html { render action: “edit” } format.json { render json: Functions & objects ������������������������������������������������� 56
db:migrate $ bundle exec rails server validate :due_at_is_
AX_STARS = 100 pygame.init() screen = pygame.display. Conditionals ��������������������������������������������������������������������������������� 58
hile True: clock.tick(30) for event in pygame.event.get(): if
< $numstars ; $i++) { $star_x[$i] = rand(80); $star_y[$i] = Variables
����������������������������������������������������������������������������������������������� 60
dch($star_y[$i], $star_x[$i], “.”); } $screen->refresh; usleep
$ rails new todolist --skip-test-unit respond_to do |format| Building proper programs ��������������������� 62
render json: @task.errors, status: :unprocessable_entity }
:due_at_is_in_the_past def due_at_is_in_the_past errors.
Recursion ������������������������������������������������������������������������������������������� 64
ygame.display.set_mode((640, 480)) clock = pygame.time.
e.event.get(): if event.type == pygame.QUIT: exit(0) #!/usr/
Sorting algorithms ������������������������������������������������������ 66
star_y[$i] = rand(24); $star_s[$i] = rand(4) + 1; } while (1) { Hidden secrets of numbers ��������������� 68
esh; usleep 50000; gem “therubyracer”, “~> 0.11.4” group
d_to do |format| if @task.update_attributes(params[:task]) Using loops �������������������������������������������������������������������������������������� 70
ocessable_entity } $ bundle exec rails generate migration
_in_the_past errors.add(:due_at, ‘is in the past!’) if due_at The magic of compilers ��������������������������������� 72
clock = pygame.time.Clock() stars = for i in range(MAX_
game.QUIT: exit(0) #!/usr/bin/perl $numstars = 100; use Common coding mistakes ��������������������74
= rand(4) + 1; } while (1) { $screen->clear; for ($i = 0; $i <
rubyracer”, “~> 0.11.4” group :development, :test do gem
_attributes(params[:task]) format.html { redirect_to @task,
s generate migration add_priority_to_tasks priority:integer
he past!’) if due_at < Time.zone.now #!/usr/bin/en python
nge(MAX_STARS): star = [randrange(0, 639), randrange(0,
use Time::HiRes qw(usleep); use Curses; $screen = new
< $numstars ; $i++) { $star_x[$i] -= $star_s[$i]; if ($star_x[$i]
pec-rails”, “~> 2.13.0” $ gem install bundler $ gem install
ice: ‘...’ } format.json { head :no_content } else format.html
bundle exec rake db:migrate $ bundle exec rake db:migrate
ort pygame from random import randrange MAX_STARS
79), randrange(1, 16)] stars.append(star) while True: clock.
ses; noecho; curs_set(0); for ($i = 0; $i < $numstars ; $i++)
_x[$i] < 0) { $star_x[$i] = 80; } $screen->addch($star_y[$i],
m install rails --version=3.2.12 $ rbenv rehash $ rails new
mat.html { render action: “edit” } format.json { render json:
db:migrate $ bundle exec rails server validate :due_at_is_
AX_STARS = 100 pygame.init() screen = pygame.display.
hile True: clock.tick(30) for event in pygame.event.get(): if
< $numstars ; $i++) { $star_x[$i] = rand(80); $star_y[$i] = Coding Made Simple | 45
dch($star_y[$i], $star_x[$i], “.”); } $screen->refresh; usleep
$ rails new todolist --skip-test-unit respond_to do |format|
Coding basics | Get started with Linux

GET STARTED
WITH LINUX
It runs on most desktop and
laptop PCs, it’s free and you
don’t even need to install it.
Let’s look at Linux!

A
s you read through this Coding with many languages built in or ready to install you can get hold of Mint and then get it up and
Made Simple bookazine, you’ll from a central server. No scouting round running on your PC.
notice that most of the screens dodgy sites; just run a command or fire up a It’s not scary, it won’t damage your PC and
don’t look like Microsoft software centre to get what you need. you don’t even have to install anything if you
Windows or Apple macOS. There’s a good That’s the beauty of Linux – it’s built by don’t want to. If you currently have a Windows
reason for that: they’re not. Just as there geeks for geeks to do geeky things. Once PC, there are three options: run Linux in
are different car VirtualBox, run it off a DVD or
manufacturers or makes of
TV, there’s more than one “It’s not scary, it won’t damage USB drive, or install it on your
PC dual-booting with Windows.
operating system that can
run your PC or Mac. It’s just
your PC and you don’t even We’re only going to look at
the first two as they’re the least
that Linux happens to be
free because it’s developed
have to install anything.” likely to cause any damage. The
walkthrough opposite explains
by thousands of coders around the world. you’re used to its slightly different interface how to run Mint within VirtualBox on top of
All the coding projects in this bookazine are and way of working, you’ll find how easy it Windows (or macOS), while the next
based on someone running Linux on their really is to get along with. We recommend that walkthrough shows you how to create a live
desktop. You don’t have to – the code works you use a version (known as a distro) called image that you can boot and run from either a
on Windows or macOS – but Linux comes Linux Mint, and we’re going to look at the ways DVD or a USB flash drive.

46 | Coding Made Simple


Coding basics | Get started with Linux
VirtualBox

1 Get VirtualBox 2 Create a machine 3 Start virtual Mint


Head to www.virtualbox.org and download Choose Ubuntu and the bits should match the A prompt asks for a disc. Locate the Mint ISO
Virtual Box 5 for your operating system, be ISO you downloaded. Click Next. Under file you downloaded and click Start. Linux
that Windows or macOS. Install it and be Memory, we recommend 2048, but if you Mint starts and, once loaded, you’re free to try
aware you’ll need around 20GB of spare drive have an 8GB PC, 4096 is best. You can leave it out or use the Install icon to properly install
space to store the virtual OS file. You also all the rest as default settings, apart from the Mint to the virtual machine. For extended use,
need the Mint ISO file from www.linuxmint. dynamic hard drive size. The default is 8GB, in the virtual machine’s settings under
com. Once installed, start VirtualBox, click but we suggest 32GB just in case. Finish and Display, you should enable 3D acceleration
New Machine, choose Linux and call it ‘Mint’. click Start to get going. and allocate 16MB of memory.

If you’ve never tried Linux, we think you’ll be developers. In many ways, the key weakness of
surprised at how easy it is to use, and how
good a development platform it makes. You
Linux has been its lack of ease of use (Mint is
an exception to that rule) but then, when it’s
Top tip
should also know that Linux runs the designed and created by developers, ease of What’s a distro?
majority of the internet, from its core use is going to come at the bottom of the to-do Unlike Windows and macOS, because Linux
servers to websites, alongside powering list. The upshot of this history is that there’s a is free software, anyone can take it and
97% of the world’s supercomputers, and wealth of the most advanced tools freely effectively create their own OS to distribute.
being used widely in science and industry. available on all Linux platforms. As long as In the Linux world, these are called distros for
So it’s not such a bad thing to understand, you’re willing to seek out help yourself and short, and there are literally hundreds out
after all. contribute back to the community, you’ll find there – not all good, not all maintained, but
No matter which tutorial you follow, you’ll a very welcoming and rich development hundreds nonetheless.
need a copy of the Linux Mint Cinnamon distro. ecosystem waiting for you.
Head to www.linuxmint.com/download. programs has always been from a central
php and download the 32-bit build, unless Getting apps repository of software, protected and
you know your system is 64-bit, in which With Windows, in the past you’ve been used to maintained by the distro’s creators.
case get that. If you have an older or slower getting programs by downloading them from This is one of the reasons why Linux has
machine, opt for the MATE edition, which is here, there and everywhere. More recently, the remained so secure (it’s not infallible) but
less graphically demanding. introduction of the Windows Store has at least people downloading dodgy software is a key
centralised where software comes from and way that machines become infected. With
Up and running removed the worry of getting infected by Linux Mint, there’s the Software Center, which
A big reason why Linux makes such a good viruses and malware. The fact is that with gives you access to hundreds of programs and
development platform is that it was created by Linux, the key way of getting new tools and all the programming development tools you

The GNU of GNU/Linux


The GNU project (GNU stands for ‘GNU’s Not come from GNU; glibc is the core C library used
Unix’) predates Linux by several years. It had in Linux and it also comes from GNU. So just
created most of the basic tools needed by a about any time you do anything on your
computer of the early 1980s – compilers, computer – every time you type a command or
text editors, file and directory manipulation click an icon – GNU software is being run at
commands, and much more – but did not have some level.
a usable kernel (some would say its kernel, GNU No wonder the GNU die-hards get upset
Hurd, is still not that usable). when we refer to our operating system as
When Linus Torvalds started tinkering with his Linux and not GNU/Linux. It is worth mentioning
small project in 1991, he had a kernel without the that no one really denies the importance of the
tools to run on it. The two were put together and GNU aspect; calling the OS Linux rather than
GNU/Linux was born – an operating system GNU/Linux has far more to do with convenience
using the Linux kernel and the GNU toolset. It is and laziness than politics – the full title is just
not only the programs in /bin and /usr/bin that too cumbersome.

Coding Made Simple | 47


Coding basics | Get started with Linux

Easy ways to run Linux


If you’re not a big Linux user, then you’ll probably a DVD. When you first turn on a PC, you can virtual optical drive. There are more options
not want to destroy your existing Windows or usually get it to boot from alternative media available, including writing the ISO file to a
Mac system, and we don’t blame you. The truth by pressing F11/F12, or hold down C on the Mac suitable USB thumb drive and, following a
is, you don’t need to – Linux is flexible enough – some PCs boot from a suitable optical disc similar boot process as discussed above,
that it can be run in a number of ways beside, on by default. running Linux from this. To get this to work, you
top of or alongside most other operating Another option is to install VirtualBox from need to use a write tool such as UNetbootin
systems, and on most types of hardware – from www.virtualbox.org (see previous page). Install from http://unetbootin.github.io.
virtual versions to versions running off spare and run this – it looks complex, but creating a For the brave-hearted, you can also install
USB drives, DVDs or on low-cost hardware such virtual PC is pretty easy if you stick to the default Linux on your system directly. Most versions
as the Raspberry Pi. The standard way, once settings. The main stumbling block is ensuring of Linux create space alongside Windows and
you’ve got your hands on the ISO, is to burn it to under Storage that you add the ISO file to the make a dual-boot system.

could wish for. It’s not why we’re here but you called the Terminal. This can be called a a Terminal and use the ls command to list a
can also download Valve’s Steam gaming client number of different things, depending on the directory, and cd to change directory.
and take advantage of over 1,700 Linux games system, such as the command line, command
it has to offer. prompt or command-line interface. It is a direct Linux isn’t Windows
interface to the operating system and all of its One thing to keep in mind when you first use
Drivers tools, which you access through text Linux is that it’s not Windows or macOS. This
We’re not really here to talk about using Linux commands. Going back to the early days of largely means things you’re used to in
in every detail but there are a few standard computers and Linux, as computers were so Windows won’t work the same in Linux, or be
questions that often crop up when people much slower, there weren’t any graphical in the same place, nor does it offer the same
move over from Windows. One key one is interfaces, so computers were controlled set of programs. So big commercial products
where are all the drivers? The cool thing with entirely through text commands. such as Microsoft Office, Adobe
Linux is that, on the whole, there’s no need to Linux was developed originally in this type Photoshop and development
worry about drivers – they’re built into the of environment, so all of its core tools are tools such as Microsoft Visual
Linux kernel. That isn’t to say you can’t add based on Terminal use. Many of them – or all Studio aren’t directly made for
drivers, but they’re generally not required. the ones you’ll care about – do have graphical Linux – you can run them via a
There are a couple of exceptions: certain more interfaces these days. The fact is, the Terminal system called Wine – but the
obscure laptop wireless cards can cause remains an efficient way of controlling Linux, Linux open-source community
issues, while if you want maximum 3D gaming and when it comes to troubleshooting, it offers has created its own tools
performance, you need to install the dedicated a consistent set of tools and interfaces to such as LibreOffice, Gimp,
graphics driver from your card’s manufacturer. resolve problems. Krita and a whole range of
You don’t need to know anything about the freely available and
The Terminal Terminal to use Linux on a day-to-day basis, open-source products
If you’ve heard of Linux, then one area you but it’s good to know that it’s there just in case. that offer the
might fear or just wonder about is a thing However, we would advise you to at least open same capabilities.

Mint on a USB drive

1 UNetbootin Linux 2 Install Mint 3 Boot and run


To run Mint from a USB stick, you first need a The tool can directly download the Mint ISO You can now boot your PC from the USB
USB drive at least 4GB in size – 16GB would image for you, but it’s best practice to do this drive. However, you need to ensure your PC
be ideal. You’ll need the Mint ISO file from yourself, then you have a local copy to hand if selects the USB drive as the boot device.
www.linuxmint.com, as discussed in the you want to create a DVD copy or redo the Usually, when you first turn on your PC, a
VirtualBox walkthrough, and we’ll use the process. Select Diskimage and locate the file message says to press F11 or F12 to select the
download tool UNetbootin from http:// in the Download folder. Ensure you have the boot device. Some PCs have their own
unetbootin.github.io. This installs the live correct USB drive selected in the pull-down specific button – consult your manual or
disc ISO file directly to your USB drive. menu and click OK to create the drive. manufacturer. Linux Mint will now run.

48 | Coding Made Simple


Coding basics | Get started with Linux
Linux distro guide
A tantalising taste of the many different flavours of Linux.
In the Linux world, because it’s hardcore Linux geeks to servers, science, older PCs and people who want modern
free software that can be redistributed by media editing and so many more. The fancy interfaces. The choice can be
absolutely anyone, this has lead to a majority are general-use distros, which aim bewildering, so to help you get started if
proliferation of different versions of the themselves at different types of users, such you’re interested in finding out more about
Linux OS appearing. There are Linux distros as experienced hands-on Terminal types, Linux, here’s our rundown of the major
tailored to a host of common uses, from complete beginners, businesses, those with distro groups.

running commercial Linux distro called


Debian Red Hat Mandriva, which eventually went bust. From its
www.debian.org www.redhat.com ashes comes a fresh and powerful desktop
One of the older distributions It’s highly unlikely you’ll distro, which offers a powerful but easy-to-use
on the block, Debian is also come across Red Hat as desktop and complete software library. It
technically the father of the it’s the big-business distro stands alongside Ubuntu and Mint for its ease
most number of spin-off distros, including one used by enterprises and corporations. It is, of use yet manages to bring new features, too.
of the most popular in the world – Ubuntu (see however, worth mentioning because it funds
below). Debian itself can be thought of a bare- a couple of high-quality distros that can be Arch
bones distro, because it comes with just freely used. Red Hat is a billion-dollar business www.archlinux.org
enough to get it installed and up and running. and is, unusually, a paid-for Linux distro, but A super-advanced version of
It’s really designed for servers and experts, but there are ways of effectively getting the same Linux that you almost have
it’s very stable and has complete repositories technology with a freely available distro. to build from scratch. This
of software, which means that it is also very means you need to be an expert to have any
easy to extend. Fedora luck with it, but it also means you get an
http://getfedora.com awesome OS that’s exactly what you want. A
Ubuntu The Fedora project was big advantage is that Arch’s active community
www.ubuntu.com created by Red Hat as a test of experts delivers the latest builds of software
This is arguably the most platform for cutting-edge before anyone else gets them.
popular – or at least the most Linux technology. Features are tested in Fedora
widely known – Linux distro and, when they’re deemed stable enough, they Manjaro
in the world. As we mentioned above, Ubuntu are merged into the Red Hat distribution. This https://manjaro.github.io/
was spun out of the Debian project to create an isn’t as scary as it sounds, as Fedora only gets Arch Linux but without all the
easy-to-use distribution that would be suitable these features when they’re stable. It’s an complexity. The Manjaro
for anyone and everyone to use. Over the years, excellent way of testing the latest technologies community has taken the base
a huge number of spin-offs have been created because Fedora tends to get them before most of Arch and created a pre-built Linux distro that
– both official, such as Ubuntu Server, but also other distros. is constantly updated, also called a rolling-
unofficial – because it became such an easy release distro. While it does lean to the more
base to start from, with an easy installation, OpenSUSE technical side of distro releases, the developers
easy interface and easy software centre. www.opensuse.org have gone out of their way to try to make it
Another business- accessible to all levels of users.
Mint orientated distro that
www.linuxmint.com also has a long-standing pedigree. It might not SteamOS
Based on Ubuntu, Mint be the sexiest distro on the block but it’s widely http://store.
took the crown of the used and often ranked in the top five distros, as steampowered.
most popular distro it’s super-stable and can be put to many uses, com/steamos
after Ubuntu moved to a from standard desktop use to server. This is Here’s more of
more modern, touch-like desktop, whereas largely because it’s another corporate- an example of how Linux is used in a fully
most Linux users wanted a traditional sponsored project and is much admired by commercial way. SteamOS is created by Valve
keyboard/mouse design, with a program developers and software vendors. Software, the company behind the PC digital
menu and desktop icons. Mint offers the distribution system called Steam. SteamOS is
simplicity of installation, ease of use and the Mageia based on Debian and is a custom OS that
large software base of Ubuntu, but with www.mageia.org drives a front for the Steam Big Picture mode,
optimised versions for older, slower Showing you how fluid the integrating controllers, home streaming and
computers, and a more fancy version Linux distro world is, Mageia was the store into one experience that you can
that’s known as Cinnamon. created off the back of a long- enjoy from a box under your TV. n

Coding Made Simple | 49


Coding basics | Mint and Python

Get started with


Mint and Python
Take a crash course in how to use the command line and follow our guide to
create your very first Python program.

M
int’s Cinnamon desktop (unlike Ubuntu’s Unity) is We shall begin this tutorial by opening the Terminal
cosmetically quite similar to Windows: there’s a program from the menu. We find ourselves confronted with
menu in the bottom-right; open windows will appear an arcane prompt of the form
in the taskbar; there’s a system tray area to which diverse user@host:~$
applets may be added; right-clicking on things gives the usual and a rather menacing flashing cursor. The ~ is shorthand
context menus; and so on. Perusing the aforementioned for our home directory, which lives at /home/user/ in the
menu, you will find a plethora of pre-installed software, Linux directory hierarchy. The $ shows that we do not have
including (but not limited to) the LibreOffice suite, the Firefox root access, which limits the amount of damage we can do.
web browser, VLC for playing movies, Gimp for image Root is the superuser in Linux and, as such, access to the
manipulation and the Transmission BitTorrent client. Besides account is limited. On a standard Linux Mint installation, root
navigating the program groups in the Places menu, you can access is granted through the sudo command (take a look
quickly access things by typing a few characters into the at https://xkcd.com/149/), which temporarily elevates our
livesearch box. privileges. If things were arranged differently, we would see
The idea of working at the command line sends shivers that a root shell has not a $ in its prompt, but a # . Let us
down the spines of many people, not least because it stirs up ignore our hungry cursor no more, and start doing some
long-repressed memories of darker times, viz. MS-DOS. But command line-fu.
don’t worry, it’s a very powerful way to work, and thanks to If we want to see a listing of all the files in the current
tab-completion, you won’t have to painstakingly transcribe directory, we use the ls command. So if we type that in and
lengthy hit Enter, we’ll see
commands or
pathnames. Much “Pretty much anything you might that we’ve got
directories for
of your day-to-day
computing can be
be used to doing in a GUI can be Documents,
Downloads,
done at the done from the command line.” Music and a few
terminal. File others. We can
management, text access the directory
editing and music playing can all be done with not one single one level up through the .. operator. So if we do
click. In fact, pretty much anything you might be used to $ ls ..
doing in a GUI can be done – or at least instigated (for we will see a listing of the directory /home/ in which we’ll see
example, playing a video) – from the command line. our user’s directory, together with the directories of any other
users that are on the system (of which there probably none).
If required, we can get more information by using the  -l
(long) option:
$ ls -l
This shows us file metadata such as permissions, ownership
information, last modified date and file size.
We can navigate the directory hierarchy using the cd
command. For example, to jump to the very top of the
filesystem and see what the view is like from up there, you
should issue:
$ cd /
$ ls
We see all kinds of tersely named directories, but we
recognise /home/ from being there a couple of sentences
ago. The /etc/ directory houses configuration files, which
advanced users enjoy manipulating, but apart from that,
LibreOffice Writer is a more than adequate word processor for almost there’s generally no reason to do anything with the filesystem
everybody’s needs. It’s compatible with Microsoft Word files. outside of our home directory – it’s all taken care of by Mint’s

50 | Coding Made Simple


Coding basics | Mint and Python
Mint comes
bundled with
some pretty
wallpapers, which
you peruse by
right-clicking
the desktop
and choosing
Change Desktop
Background.

package manager. That said, it’s fun to explore and familiarise get confused with actual programming directives or variable
yourself with how Linux does its filing. For example, the /dev/ names. Since strings can contain spaces, it’s easy to see how
directory contains device nodes representing all the hardware such confusion may arise. There isn’t a reasonable notion for
attached to your system. Disk partitions get names such as subtracting or dividing by strings, so attempting to do that
sda1 or sdb2, and the primary video card lives in /dev/dri/ results in an error. Programmers encounter diverse error
card0. This is quite a radical idea to digest, but on Linux, messages as a matter of course, so you may as well try that
everything is a file. now. Your first ever type error – congratulations! Exit
For a more thorough look at the command line, see the the interpreter by pressing Ctrl+D or typing exit() . The
five-minute introduction at http://community.linuxmint. interpreter is good for trying out code snippets but it’s no use
com/tutorial/view/100. We’re going to focus our attention for proper coding. We’re going to create our first Python
towards Python programming now. We can return to our program and run it, all from the command line.
home directory at any time simply by calling cd with no All programming begins with simple text files, and we can
arguments. So let’s do that to start with, and then create a use the humble nano editor to create one. Let’s navigate to
new directory in which to store our Pythonic labours. our newly created directory and create our Python script:
$ cd ~ $ cd ~/python
$ mkdir python $ nano helloworld.py
Mint currently uses the older Python 2.7 by default but it’s Python programs all use the .py extension, and our
worth adopting the newer 3.x series, unless you’re morally particular program, as is tradition in such matters, is going to
opposed. So start the Python 3 interpreter by typing: issue a worldly greeting. The nano text editor is pretty easy to
$ python3 work with – you can press Ctrl+X at any time to exit (you’ll be
We are presented with some version information, terse prompted to save any changes). There are some helpful
guidance and a different prompt: >>>. This enables us to shortcuts displayed on the bottom for searching (Ctrl+W),
enter Python commands and have the results immediately saving (Ctrl+O) and the like. If you’ve never used a terminal-
returned to us. It’s known as a Read-Evaluate Print Loop based text editor, then you might dismayed to learn that the
(REPL). For example, we can use it as we would a standard mouse can’t be used as you might expect here. It is possible
calculator to perform basic arithmetic: to select text and paste it using the middle mouse button, but
>>> 32 * 63 positioning of the cursor is done with – and only with – the
2016 cursor keys.
>>> 9 ** 2 Getting Python to print messages to the terminal is easy –
81 we use the print() function. Type the following into nano:
>>> 1 / 3 print(‘Hello world’)
0.3333333333333333 As before, we’ve had to enclose our string in quotes. Now
We’ve put spaces around each operator, which is not commence departure from nano with Ctrl+X, press Y to save
necessary but does improve readability. And readable code is and then press Return to use our existing file. Back at the
A Good Thing. But it’s not just numbers that we can add up – command line, the moment of truth – let’s see whether
we can do it with strings, too. We call them strings because Python can run our program:
they are strings of characters, but that doesn’t stop them $ python3 helloworld.py
being added or multiplied: If all goes to plan, a friendly greeting should be displayed. If
>>> ‘hello’ * 3 that didn’t happen, welcome to the world of programming, in
‘hellohellohello’ which careless typing is punished. Rinse, lather and repeat
>>> ‘hello there, ’ + ‘friend’ the editing and running stages until it works. Then settle down
‘hello there, friend’ with a cup of tea, satisfied in the knowledge that you wrote a
Notice that we enclose strings in quotes. This is so they don’t program and lived to tell the tale. n

Coding Made Simple | 51


Coding basics | IDEs

Get started
with IDEs
Speed up your programming workflow by using Geany, a lightweight
integrated development environment.

T
he cycle of editing, running and debugging even The grown-up way to begin Python files is with a directive
simple programs can rapidly become painful. So known as a shebang. This is a line that tells the shell how it
imagine how ugly things can get when working on a ought to be run. So our Python 3 code should begin:
huge project involving complex build processes. This is why #!/usr/bin/env python3
integrated development environments (IDEs) exist – so that The env program is a standard Linux tool that is always
the editing, compiling, linking and debugging can all take accessible from the /usr/bin/ directory. It keeps track of
place on a unified platform (and you have a single point at where various programs are installed, because this can differ
which to direct programming rage). Some IDEs are tailored wildly from distro to distro. On Mint, our shebang could
for a particular language, such as IDLE for Python (see page equally well call /usr/bin/python3 directly.
28). We’re going to look at a more general purpose tool called Now we’ll change up our program slightly. We’re going to
Geany. Geany is pretty basic as far as IDEs go – in fact, by show how variables can be used as placeholders, and in doing
some measures, it’s more of a text editor on steroids than an so make our greeting a little more customisable. Edit the code
IDE, but it is more than sufficient for this tutorial. (keeping the shebang above, unless you have some personal
You’ll find Geany in Mint’s repositories, so you can install it grievance) so that it looks like this:
either from the Software application or by doing: name = ‘Dave’
$ sudo apt-get update print(‘Hello ’, name)
$ sudo apt-get Note the space
install geany after Hello ,
Now start
Geany from the
“Variables allow us to abstract otherwise the
output would look a
Places menu.
There’s a quick
away specifics and deal with bit funny. We have
declared a variable
run-through of the quantities that, well, vary.” called name
interface’s major containing the string
features opposite. We can start by opening up our helloworld. ‘Dave’ . We can test our code by pushing F5 or clicking the
py program from before: Select File > Open and then navigate Run button (see annotation). You probably knew what was
to our python/ directory to select the file. going to happen, and you probably realise that the same
effect could be achieved just by changing ‘world’ to ‘Dave’
in the original program – but there is something much more
subtle going on here. Variables allow us to abstract away
specifics and deal with quantities that, well, vary. We can
elaborate on this concept a little more by introducing a
new function, input() , which takes a line of user input and
returns that string to our program. Change the first line to
name = input()
and run your code. In the terminal window, type your name, or
whatever characters you can muster, and press Return. The
program took your input and courteously threw it back at you.
The input() function can also be given a string argument,
which will be used to prompt the user for input. Our print()
function above does our prompting for us, so we have no
need for this.
Before we go further, it’s worth talking about tabs and
spaces. Python is terribly fussy about indentation, and even if
it wasn’t, you still should be. Correctly indenting code makes
it easy to demarcate code blocks – lines of code
that collectively form a function or loop – so we can see,
Before you start, you need to install Geany from Mint’s repositories. for example, which level we are at in a nested loop. A tab

52 | Coding Made Simple


Coding basics | IDEs
The Geany interface
Run button
The Run button (or F5) will
save and execute your Python
program in a terminal. When the
program finishes or breaks, you
can study any output or error
messages here before closing it.

Tabs
By default, Geany opens your
recent files in tabs. So if you’re
working on a more involved,
multi-file project, related code is
just one click away.

Symbols
The Symbols tab lists all the
functions, variables and
imports in the current file,
together with the line on
which they are declared.
Clicking will take you
straight there.

Code folding Code editor


Code folding is de rigueur for any IDE. The main area where you enter or edit code.
Clicking on the + or - will reveal or collapse Geany is good at guessing the language
the block of code on the adjacent line. you’re typing, and keywords are highlighted.

represents a fixed amount of white space decided by the text greeting is issued. We can put as many lines as we want in
editor, but just because an editor renders a tab character as this clause – so long as they respect the indentation, Python
eight spaces, that doesn’t make it equivalent to pushing the knows that they all should be run when the condition is met.
space bar eight times. Python happily works with files that The else block is run when the condition is not met, – in this
use tabs or spaces, so long as they’re consistent. case, the program behaves exactly as it had done before.
The reason Python is fussier than other languages about Note that strings are case-sensitive, so someone called
these matters is because indentation levels actually form Agamemnon would not be recognised as an old acquaintance
part of the code. So just adding a random indent to your code of our program. As well as testing for equality, we can also use
is likely to break it. We need some more coding concepts at the greater than ( > ) and less than ( < ) operators. The len()
our disposal to illustrate this. Let’s start with the  if function returns the length of a string, so we could instead
conditional. Suppose we want our program to behave make our if statement:
differently when someone named, say, Agamemnon uses it. if len(name) > 9:
Replace the last line of our code with the following block, print(‘My what a long name you have’)
noting that Geany automatically indents your code after Now anyone whose name is 10 characters or more gets
the  if and else statements. recognition. Of course, the else block from above can be
if name == ‘Agamemnon’: included, too, if that behaviour is still desired.
print(‘Ah, my old friend...) There are many other IDEs besides Geany. If you want to
else: check out something more advanced, see PyCharm or
print(‘Hello ’, name) perhaps the PyDev plugin for Eclipse. Or maybe you’re
It can be hard to get used to the autotabbing, but it saves happier with a couple of terminals open – you wouldn’t be the
you considerable effort. The code we’ve just introduced is first. Also, don’t forget IDLE, which is packaged with Python –
highly readable – we use the == operator to test for equality we cover it in the Raspberry Pi chapter on page 28. However
and use a colon to indicate a new code block is starting. If the you choose to do it, though, we wish you good luck with your
condition is met (ie Agamemnon is visiting), then a special continued adventures in Linux and coding. n

Coding Made Simple | 53


Coding basics | Python lists

Get to grips with


Python lists
Let’s start by exploring some of the fundamental ideas behind programming
logic, beginning with the concept of lists.

I
t’s difficult to know where to start when it comes to remind you what’s on your shopping list, it would make much
explaining the basic programming concepts. When more sense to put these values together. In Python, for
someone begins coding, there’s an overwhelming number example, you could create a list of those values with the
of different ideas to understand, absorb and eventually turn following line:
into solutions. And that’s on top of the syntax and >>> shoppinglist = [“milk”, “bread”, “baked beans”]
peculiarities of your chosen language. This is technically a list of lists, because each value is itself
One of the best approaches is to just start writing code, a list – a string of characters. Some languages like to make
either by following an example project, such as the ones we that distinction, but most prefer the convenience.
provide in this book, or by piecing together examples from Each of these items has been added to the freshly created
documentation. Both methods work, and they’re the only real shoppinglist list. But lists are dynamic, and one of the first
way to get to grips with the problems and complications of things you often want to do is add new values.
any particular concept. This is where lists start to become interesting, because
We’d like to make this challenge slightly easier by looking the method for adding and removing values can help to
at basic approaches that apply to the vast majority of define the list’s function. For example, it’s faster for the CPU
circumstances and languages. And our first target is lists. to add a new item to the end of a list because all the
You don’t get far with any moderately complex task application has to do is link the last element to the new one.
without a list, whether that’s a holiday to Diego Garcia or If you insert an item into the middle of a list, the process
a trip to the supermarket. And list logic in code is just like in first splits the links between the two items on either side of
real life. A list is a convenient place to store loosely-related the insertion point, then links both the preceding item and the
snippets of information. Programmers like to call loosely- following one to the new item.
related snippets of information a data structure, and a list is
just another example. With a shopping list, for instance, the Stacks and queues
relationship might be something as simple as food – ‘milk’, The most important characteristic for a list is that the chain
‘bread’ and ‘baked beans’. If you were writing an application to of data it contains is in a specific order. It might not be
important what that order is, but it’s the order that
differentiates a list from a random array of values, such as
a chunk of memory.
It’s for this reason that some of the earliest lists are stacks,
with values either pushed on to the end or pulled off, rather
than lists with values inserted and removed from the middle,
which are more processor intensive.
Processing speed means that stacks aren’t a necessity
If you’re any more, but they’re still useful for temporarily holding
learning
values, for example before retrieving them in reverse order
Python, the
like a stack of cards. The list could be your terminal command
tab completion
history, or a browser’s ‘Back’ button.
in the Eric
programming In Python, you can execute a function called append to
environment is the same effect:
a great helper. >>> shoppinglist.append(“soup”)

POP A QUEUE PUSH

With a queue,
the values you
put on the list
first are the
1 2 3 4 5
first out (FIFO).

54 | Coding Made Simple


Coding basics | Python lists
This will add soup to our shopping list. When we’ve added
it to our shop, it can be removed easily with pop:
>>> shoppinglist.pop()
Using Python’s interpreter
If you’re running these commands from the interpreter, You might wonder why we have three > and data. If you execute a function that
you’ll see the contents of the last value in the list as it’s symbols preceding the snippets of code returns a value, for example, such as
popped off the stack, in our case the word soup. If you’ve got on these pages, as well as in our more len(list) to return the length of a list, the
processing limitations in mind, you might wonder why there comprehensive Python tutorials. value is output to your terminal
isn’t an option to pop the first value off the stack, too. These symbols represent the cursor immediately, rather than needing any
This would require the same amount of relinking as of Python’s interactive interpreter, and explanation in a script or assigning to
they help to distinguish between another variable. You can quit the
popping off a value from the end. It’s perfectly possible, and
something you might want to build into interpreter by pressing [Ctrl]+[D]
turns a list into something called a ‘queue’ – the values you
a script and something you can try together, but you will obviously lose the
put on the list first are first out, known as FIFO. This is in immediately by typing in to the current state of your code.
contrast to a stack, which is LIFO. interpreter – although they are,
There are many ways to use a queue, but the most in fact, interchangeable.
obvious is to preserve the order of incoming data. As we Launching the interpreter is as simple
explained, the only difference between a queue and a stack is as typing python from the command
where the pop value comes from, which is why Python line without any further arguments. It’s
doesn’t have any special commands for accessing the first at this point you’ll see the cursor
value, it just uses an argument for the pop command. The symbols, and you can now start typing
lines of Python code.
following will remove the first item in the list, and should
This is a brilliant way of learning
output ‘milk’ from the interpreter:
how the language works, as well as
>>> shoppinglist.pop(0) experimenting with syntax and the
concepts you’re working with. Errors in a
Modern lists single line are far easier to spot than
Lists are no longer limited by processor speed to stacks and those in a 20-line script that’s being run If you’re learning to program, the
queues, and most modern languages and frameworks for the first time, and you can also get Python interpreter can teach you
provide a vast number of handy functions for dealing with a really good feel for how Python, and a great deal, regardless of your
them. These offer a big advantage over the original primitive programming in general, handles logic chosen language.
operations, and can turn lists into super-flexible data types.
Python is particularly good at this, and includes plenty of
built-in functions for manipulating lists without having to write all things code-wise, 0 is the real first element in a list and
your own code. You can output a value from any point in the array, making 1 the second. And if you want to output the
list by treating it as an array. Typing shoppinglist[1], for entire list, you typically need to construct a simple loop that
instance, will return the second value in the list. As with nearly shuffles through these values from beginning to end.
Python is an exception, because simply typing
shoppinglist will output the list’s contents, but for other
languages, you might have to construct something like:
A STACK >>> for x in range(0,len(shoppinglist)):
Quick
... shoppinglist[x]
POP PUSH ... print
tip
The for loop here gives a value to x that steps from 0 to We’re using Python
len(shoppinglist), which is a method to return the length of for our examples
because it’s
a list. Each location in the list is output as we loop through it in
a great language
the order they were added (FIFO). for beginners. But

4 You can change the order in lots of ways, but Python’s


sort method is tough to beat:
every concept we
discuss works with
other languages,
>>> shoppinglist
too – it’s just a
[‘baked beans’, ‘bread’, ‘milk’, ‘soup’] matter of finding
>>> shoppinglist.append(“apples”) the correct syntax

3 >>> shoppinglist
[‘baked beans’, ‘bread’, ‘milk’, ‘soup’, ‘apples’]
for the functionality.

>>> shoppinglist.sort()
>>> shoppinglist
[‘apples’, ‘baked beans’, ‘bread’, ‘milk’, ‘soup’]

2 If you can follow the logic of that simple piece of code,


then it’s safe to assume you’ve grasped the logic of lists.
There’s really nothing more to it, and now we hope you’re
wondering what all the fuss is about. The main problem is
that it can get complicated quickly, and because lists are

1 shorthand for so many different data types, it can be difficult


working out what might be happening in any one chunk of
code. This is especially true of Python – because it has so
many convenience functions, unless you know what they do,
With a stack, the values you put
on the list last are the first out (LIFO). you’re unlikely to grasp the logic. But at their heart, they’re
just a chain of values, and that’s the best place to start. n

Coding Made Simple | 55


Understanding
Coding basics | Functions & objects

functions &
objects After introducing the concept of lists, it’s
time for us to tackle the fundamental
building blocks behind any application.

W
e’ve already covered a concept called a list. Lists
have been around since people started to write
one line of code after another because, in essence,
they simply store one value after another.
But what must have come soon after lists in the mists of
language creation is the idea of a function, because a function
is a kind of list for code logic. It’s not built at runtime, but while
you’re constructing your project, and much like their
mathematical counterparts, functions are independent
blocks of code that are designed to be reused.
Functions are fundamental for all kinds of reasons. They
allow the programmer to break a complex task into smaller
chunks of code, for instance, and they allow you to write
a single piece of code that can be reused within a project. You BBC BASIC was the first programming language many of
us came into contact with.
can then easily modify this code to make it more efficient, to
add functionality or to fix an error. And when it’s one piece of
code that’s being used in lots of places, fixing it once is far there’s a good chance it was written in BASIC – a language
easier than trawling through your entire project and fixing embedded within the ROMs of many of the home computers
your same broken logic many times. of the early eighties.
Functions also make program flow more logical and easier BASIC code was mostly sequential, with many systems
to read, and you can keep your favourite functions and use even using line numbers, and there’s a good chance that the
them again and again. When you break out of single-file following might have been your first program:
projects, functions become the best way of grouping 10 PRINT “Hello world!”
functionality and splitting your project into different source This led to one of the most primitive hacks of the day. You
files, naturally breaking complex ideas into a group of far had to find a computer shop displaying a selection of
easier ones. If you then work with a team of programmers, machines. You’d then sneak in and quickly type the above line
they can work on functions and files without breaking the followed by 20 GOTO 10, RUN and a carriage return. This
operation of the application, and it’s this idea that led to the would create an infinite loop that printed ‘Hello World’ for ever
creation of objects. These are a special kind of function that – or for the 10 minutes it took for the store staff to notice and
bundle both the code logic and the data the logic needs to wearily turn it off and on again. The cooler kids would change
work into completely encapsulated blocks. But let’s start at the text to say something rude and add colour to the output.
the beginning. If your first programming project was from Either way, it’s a basic example of a function if you can
about 30 years ago, and written on a home computer, then execute it from another part of your project.
BASIC programming without functions can be a little like
writing assembly language code. If you want to repeat a series
of lines, you need to remember where you are in the code,
jump to the new code, and jump back after execution. BASIC
provided some of this functionality with procedures, but
functions give that chunk of code a label, which can then be
called from any other point in your project. Functions can also
return a value, such as the sum of a group of numbers, and
accept arguments. That could be a list of numbers to be
added, for example. But you’d have needed to be a wealthy
Acorn Archimedes owner to get those facilities out of BASIC.
BASIC wasn’t With Python, you can try these ideas without getting too
always put to retro. From the interpreter, for example (just type python on
the best uses. the command line and add our code), type the following:

56 | Coding Made Simple


Coding basics | Functions & objects
>>> def helloworld():
... print (“Hello World”)
... return
The art of objects
... An object bundles functions and the refers to when specification is used
As ever with Python, you need to be very careful about type of data they accept together, so within your code. In our example, the
formatting. After creating a new function called helloworld() that there’s less ambiguity on how class is the structure of Shopping while
with the def keyword, the interpreter precedes each new line a function should be used, and better the object is instance. The function
with .... Any lines of code you now add will be applied to the separation from the main flow and called __init__ is run when the object is
function, and you’ll need to press [Tab] at the beginning of side processes. Dealing with objects can created, and we pass the two values –
each to indent the code and make sure Python understands quickly get complicated, partly because one for the item’s name and the other
there are so many different concepts, for its price. You should be able to see
this. Other languages aren’t so picky. After the return
language-specific features and how this class could be quickly
statement, which signals the end of the function, press
implementations, and partly because it expanded to include other functions (or
[Return] to create a blank line. You’ve now created a function, requires the programmer to think about methods), and how the world of classes
and you can execute it by typing helloworld() into the problems differently. This simple and objects can transform your coding
interpreter. You should see the output you’d expect from a example creates a class that contains projects for the better.
function with a name like helloworld(), and you’ve just both the item and the price from our
jumped forward 30 years. previous shopping list:
>>> class Shopping:
Passing arguments ... def __init__(self, item, price):
There’s a problem with our new function: it’s static. You can’t ... self.item = item
... self.price = price
change anything. This can be solved by opening the function
...
up to external influence, and you can do that by enabling it to
>>> instance = Shopping(“Bread”, 0.85)
pass and process arguments. If you alter the function >>> instance.item
definition to def helloworld( str ), for instance, Python will ‘Bread’
expect to find a string passed to the function whenever it’s >>> instance.price
called. You can process this string within the function by 0.85 You can still create classes and
changing print (“Hello World”) to print str, but you should A class is a bit like the specification functions from within the interpreter,
obviously be doing anything other than simply printing out for an object, whereas the term object but it begins to make less sense.
what’s passed to the function. It can now be executed by
typing helloworld(“something to output”) and you’ll see
the contents of the quotes output to the screen. definitions before the program logic, and why types are often
To show how easy it is to create something functional, we’ll declared in header files because these are read before the
now build on the idea of lists from the previous tutorial. main source code file.
Instead of a shopping list, we’ll create a list of prices and then Working out what your language requires and where is
write a function for adding them together and returning the more difficult than working out how to use functions. And
total value. Here’s the code: that’s why they can sometimes appear intimidating. But
>>> def addprices( plist ): Python is perfect for beginners because it doesn’t have any
... return (sum (plist)) convoluted requirements – apart from its weird tab
... formatting. All we’ve done in our code is say there’s going to Quick
>>> pricelist = [1.49, 2.30, 4.99, 6.50, 0.99] be some data passed as an argument to this function, and tip
>>> addprices(pricelist) we’d like Python to call this plist. It could even have had the
When you’re using
16.27 same name as the original list but that might look confusing. other packages,
Python is very forgiving when it comes to passing types to The only slight problem with this solution is that you’ll get only the functions
functions, which is why we didn’t need to define exactly what an error if you try to pass anything other than a list of are exposed. You
plist contained. Most other languages will want to know numbers to the function. This is something that should be don’t need to know
how they work, just
exactly what kind of types an argument may contain before checked by the function, unless you can be certain where
what input they’re
it’s able to create the function, and that’s why you often get those numbers come from. But it does mean you can send expecting and what
a list of values in exactly the same way you define a list: output they return.
>>> addprices([10, 12, 13, 18]) That’s functional
53 programming in
a nutshell.
The biggest challenge comes from splitting larger
problems into a group of smaller ones. For a programmer, this
task becomes second nature, but for a beginner, it’s an
intimidating prospect. The best way is to first write your
application, regardless of functions or programming finesse.
Often, it’s only when you’re attempting to write your first
solution that better ones will occur to you, and you’ll find
yourself splitting up ideas as the best way to tackle a specific
issue within your project. The best example is a GUI, where it’s
common sense to give each menu item its own function,
which can be launched from either the icons in the toolbar or
by selecting the menu item. Many developers consider their
first working copy to be a draft of the final code, and go to the
An IDE, such as Eric, can make working with functions trouble of completely rewriting the code after proving the idea
and objects easier. works. But don’t worry about that yet. n

Coding Made Simple | 57


Adapt and evolve
Coding basics | Conditionals

using conditionals
Any non-trivial program needs to make decisions based on circumstances.
Get your head around coding’s ifs and buts.

M
urray Walker, the great Formula 1 commentator,
used to say “IF is F1 spelled backwards.” Ifs, buts
and maybes play a vital role in motor racing, as IF condition...
they do in computer programming. If you’re writing a
program that simply processes and churns out a bunch of
numbers, without any user interaction, then you might be THEN ELSE
able to get away without any kind of conditional statements.
But most of the time, you’ll be asking questions in your code: Consequent Alternative
if the user has pressed the [Y] key, then continue. If not, stop.
Or if the variable PRICE is bigger than 500, halt the
action action
transaction. And so forth.
At its core, a conditional statement is something like this.
A condition is just a question, as in everyday life: if the
kettle has boiled, turn off the gas. (We don’t use newfangled
electricity around here.) Or if all the pages have gone to the if x == 10:
printers, go to the pub. Here’s an example in Python code: print “X is ten”
x=5 somefunction()
else:
if x == 10: anotherfunction()
print “X is ten” In this case, if X contains 10 we print the message as
else: before, but then call the somefunction routine elsewhere in
print “X is NOT ten” the code. That could be a big function that calls other
functions and so forth, thereby turning this into a long branch
print “Program finished” in the code.
Here, we create a new variable (storage place for There are alternatives to the double-equals we’ve used:
a number) called X, and store the number 5 in it. We then use if x > 10 If X is greater than 10
an if statement – a conditional – to make a decision. If X if x < 10 If X is less than 10
contains 10, we print an affirmative message, and if not (the if x >= 10 If X is greater than or equal to 10
else statement), we print a different message. Note the if x <= 10 If X is less than or equal to 10
double-equals in the if line: it’s very important, and we’ll come if x != 10 If X is NOT equal to 10
on to that in a moment. These comparison operators are standard across most
Here, we’re just executing single print commands for the programming languages. You can often perform arithmetic
if and else sections, but you can put more lines of code in inside the conditional statement, too:
there, providing they have the indents, Python style: if x + 7 == 10:
print “Well, X must be 3”

Comparing function results


While many if statements contain mathematical tests such
as above, you can call a function inside an if statement and
perform an action depending on the number it sends back.
Look at the following Python code:
def truefunc():
return 1
Python doesn’t
have switch/
case. Why? Read def falsefunc():
the explanation return 0
at www.python.
org/dev/peps/ print “Execution begins here...”
pep-3103/

58 | Coding Made Simple


Coding basics | Conditionals
if truefunc():
print “Yay” Assignment vs comparison
if falsefunc(): In some languages, especially C, you value of X to be 1! Well actually, we did,
print “Nay” have to be very careful with but in the if line we then performed an
The first four lines of code define functions (subroutines) comparisons. For instance, look at this assignment, not a comparison. That’s
bit of C code – try to guess what it does, what the single equals sign does.
that aren’t executed immediately, but are reserved for later
and if you like, type it into a file called We’re not saying “if X equals 5”, but
use. They’re really simple functions: the first sends back the
foo.c, run gcc foo.c to compile it and rather, “put 5 in X, and if that succeeds,
number 1, the second zero. Program execution begins at the then ./a.out to execute it. execute the code in the curly brackets”.
print line, and then we have our first if statement. Instead of #include <stdio.h> Ouch. If you recompile this code with
doing a comparison, we call a function here, and act on the gcc -Wall foo.c (to show all warnings),
result. If the if statement sees the number 1, it goes ahead int main() you’ll see that GCC mentions
with executing the indented code, if not, it skips past it. So { assignment used as truth value. This
when you run this, you’ll see Yay but not Nay, because if here int x = 1; is an indication that you might be doing
only does its work if it receives the number 1 back from the something wrong.
function it calls. In Python and many other languages, you can if (x = 5) The solution is to change the if line to
puts(“X is five!”); if (x == 5) instead. Now the program
replace 1 and 0 with True and False for code clarity, so you
} runs properly. It’s a small consideration,
could replace the functions at the start with:
If you run this program, you might be but if you’ve just written a few hundred
def truefunc(): surprised to see the X is five message lines of code and your program isn’t
return True appear in your terminal window. Shurley behaving, this could be the root cause.
shome mishtake? We clearly set the It’s caught us out many times...
def falsefunc():
return False
and the program will operate in the same way. }
This is neater and easier to read. Note that the break
Clearing up code instructions are essential here – they tell the compiler to end
In more complicated programs, a long stream of ifs and elses the switch operation after the instruction(s) following case
can get ugly. For instance, consider this C program: have been executed. Otherwise, it will execute everything
#include <stdio.h> following the first matching case.
Another way that some programmers in C-like languages
int main() shorten if statements is by using ternary statements.
{ Consider the following code:
int x = 2; if (x > y)
result = 1;
if (x == 1) else
puts(“One”); result = 2;
else if (x == 2) This can be shortened to:
puts(“Two”); result = x > y ? 1 : 2;
else if (x == 3) Here, if X is bigger than Y, result becomes 1; otherwise it’s
puts(“Three”); 2. Note that this doesn’t make the resulting code magically
} smaller – as powerful optimising compilers do all sorts of
C, and some other languages, include a switch statement tricks – but it can make your code more compact.
which simplifies all these checks. The lines beginning with if Although we’ve focused on Python and C in this guide, the
here can be replaced with: principles are applicable to nigh-on every language. And it all
switch(x) { boils down to machine code at the end of the day – the CPU
case 1: puts(“One”); break; can compare one of its number storage places (registers) with
case 2: puts(“Two”); break; another number, and jump to a different place in the code
case 3: puts(“Three”); break; depending on the result. n

Big ifs and small ifs


In C, and other languages that share its syntax, you but it will print the second. That’s because only the
don’t need to use curly brackets when using an if first is tied to the if statement. To attach both
statement followed by a single instruction: instructions to the if, put them in curly braces like
if (a == 1) the following:
puts(“Hello”); if (x == 5) {
But only one instruction will be executed. If you puts(“X is 5”);
do something like this: puts(“Have a nice day”);
int x = 1; }
Contrast this with Python, where the
if (x == 5) indentation automatically shows which code
puts(“X is 5”); belongs to which statement. C doesn’t care about Here we see how indentation isn’t
puts(“Have a nice day”); indentation – you have to explicitly show what you good enough for C – we need to use
When you execute it, it won’t print the first message, want with curly brackets. curly braces to bundle code.

Coding Made Simple | 59


Coding basics | Variables

Variable scope of
various variables
Caution! That variable you’re accessing might not be what you think it is. Why?
Because variables are variable. Have we said ‘variable’ enough now?

O
nce upon a time, programs were just big lists of and therefore it’s a good thing to get right in the early days of
instructions, and these instructions could do your programming journey.
anything with variables and the contents of memory. Let’s start with a bit of Python code. Try this:
This was fine for simple, low-level programs but as time went def myfunc():
on and people started making bigger and more complicated x = 10
programs, the idea that one part of the program could do print x
anything with memory became less appealing.
For instance, you might have a program that controls
a robotic arm, and stores the state of the arm in a variable x=1
called X. Your program calls lots of different subroutines, print x
some of which may have been programmed by other people. myfunc()
How do you know that those routines aren’t messing about print x
with the RAM where X is stored? If you’re totally new to Python: the def bit and the
The results could be disastrous, especially when the arm following two lines of code are a function which we call later.
starts punching people instead of stroking puppies as Program execution begins with the x = 1 line. So, we create a
originally envisaged. variable called x and assign it the number 1. We print it out to
This is where the concept of variable scope comes into confirm that. We then call a function which sets x to 10, and
play. In programming, scope defines how a variable is visible prints it. As control jumps back to the main chunk of our
Most well- to the rest of the program. In most high-level languages, we code, we print x again… and it’s back to 1. How did that
documented can control the scope of a variable – that is, we can choose happen? Didn’t we just set x to 10 in the function?
languages have whether it should be visible to the current chunk of code, to Well, yes, but the function had its own copy of the variable.
explanations the current source code file, or absolutely everywhere in all of It didn’t do anything with the x variable that was declared
of variable
the program’s files. outside of it. The function lives happily on its own, and doesn’t
scope, so once
This level of control is absolutely fundamental to good want to interfere with data it doesn’t know about. This is
you’ve got the
basics from this program design, so that multiple programmers can work essential to keeping code maintainable – imagine if all
article, you can together on a project, implementing their own routines variables were accessible everywhere, and you were writing a
explore specific without accidentally trampling over one another’s data. It’s routine to be dropped inside a 50,000-line software project.
implementations. good for modularisation and keeping data safe and secure, You’d be totally terrified of choosing variable names that
might be in use elsewhere, and accidentally changing
someone else’s data.

Change of routine
So most programming languages provide this level of
protection. Still, there are legitimate reasons why you might
want to make a variable accessible to other routines, and in
Python you can do this by inserting the following line into the
start of the myfunc() routine:
global x
This makes all the difference. Previously, the version of x
we were using in myfunc() was a local variable – that is, it
affects only the code located inside the function. By adding
the global command, we access x as a global variable – that
is, it’s the same one as we used in the main body of the code.
So if we run this Python code now, we see that x is set to 1 at
the start, but then the myfunc() routine grabs that x as a
global variable and sets it to 10, and it stays that way back in
the main code.
How variable scope is handled varies from language to
language, so let’s look at another implementation here, this

60 | Coding Made Simple


Coding basics | Variables
time in C. Whereas Python is pretty flexible about using
variables that you haven’t defined previously, C is a little more
strict. Consider this:
Automatic variables
#include <stdio.h> Most local variables are automatic – int x = 0;
that is, they are only created in RAM x = x + 1;
void myfunc(); when program execution reaches the printf(“x is %d\n”, x);
point of their initialisation. Once the }
routine containing the local variable Here, we call myfunc() three times,
int main()
has finished, that variable will no longer which creates a variable x containing
{
be useful, because outside routines zero, adds 1 to it and prints it out. You’ve
int x = 10;
can’t access it. So, the compiler will no doubt already guessed that running
printf(“x is %d\n”, x); typically reclaim memory used by that this produces 1 with each call of
myfunc(); variable, making room for other bits myfunc(), because x is being created
printf(“x is %d\n”, x); and bobs. each time. But what happens if you
} There is, however, a way to stop that, change the declaration in myfunc() to
and that’s by declaring a static variable. static int x = 0;? Well, the output
void myfunc() This is still a local variable that can be becomes this:
{ manipulated only by code inside the x is 1
current function, but it retains its state x is 2
int x = 20;
every time the function is called. For x is 3
printf(“x is %d\n”, x);
instance, look at the following C code: The static keyword here tells the
}
#include <stdio.h> compiler that it should preserve the
Here, because we’re explicitly creating variables with int, state of the variable between calls. So
it’s somewhat clearer that myfunc() has its own version of void myfunc(); on the very first call it sets up x as zero,
the variable. But how do you go about making the variable but in future calls it doesn’t initialise the
global in this particular instance? The trick is to put the int main() variable as new again, but retrieves its
variable declaration outside of the functions. Move int x = 10; { state from before. The compiler doesn’t
from inside main() to after the void myfunc(); line at the top, myfunc(); ditch it at the end of the function, as it
and now the variable has become global – that is, it’s myfunc(); does with automatic variables. So, using
myfunc(); static variables is a great way to get
accessible by all functions in the file.
} some of the benefits of global variables
However, that’s not the only job you need to do. Inside the
(retaining its state throughout
myfunc() routine, we still have a line that says int x = 20;.
void myfunc() execution) without exposing it to the
The int here is still creating its own version of the variable, so { rest of the program.
take it away so that the line just reads x = 20;. Run the
program, and you’ll see the intended result, that x is global
and can be modified everywhere.
Note that while putting the x declaration outside of personal choice for your particular program, but the general
functions makes it global to the current source code file, it rule is: use global variables only when necessary. Try to keep
doesn’t make it global absolutely everywhere in all of the data isolated inside functions, and only use a global variable
source code. If you’ve got a big project with multiple C files, when you have no other option.
you’ll have to use the extern keyword. So if you have int x = There are usually ways to access the local variables from
10; in foo.c and you want to use that in bar.c, you’d need the one function in another (for example, pointers in C and
line extern int x; in the latter file. references in C++), but those features are specific to
All of this leads to one final question: when should you use individual languages, so that’s something to look up in your
global variables, and when local? Ultimately, that’s a matter of own time. Pointers are a tricky business! n

Remember to initialise!
By default, most C compilers don’t don’t blindly use variables that
set newly-created automatic haven’t been initialised with some
variables to zero. This is especially kind of value!
true in the case of automatic Now, why don’t compilers just set
variables, because they might be the variable to zero? That would
created somewhere in RAM that was make everything a lot safer, right?
used previously by other data. Well, yes, but it’s extra work for the
So if you have a program like this: CPU and adds a performance hit.
#include <stdio.h> The compiler allocates space for
variables in RAM that may have
int main() been used for other data before, so
{ there’s no guarantee that the RAM is
int x; zeroed-out.
printf(“x is %d\n”, x); Setting that chunk of RAM to zero
} requires an extra CPU instruction,
then compile and run it, and then and GCC tries to be pretty efficient.
compile and run it again, the number You can tell GCC to warn about the
will probably be different each time use of uninitialised variables with the If you try to use automatic variables that haven’t been
you do. The moral of the story is: -Wall flag. given any value, prepare for some horrors.

Coding Made Simple | 61


Coding basics | Program structure

Building proper
programs
Learn to break problems down into manageable chunks, as we show you how
to design a well-sculpted program.

I
n this article, we’re going to do something a little different. types of data that are described. As you’re doing this,
Instead of looking at a specific feature that shows up in separate the data into input and output.
many programming languages, we’re going to look at the Output data: monthly payments and total interest
art of designing programs. Input: mortgage value, annual interest rate, duration
Knowing about if clauses, for loops, lists and functions Great, that was pretty easy; but what was the point? Well,
(and much more) is vital if you want to learn to program. But take a look at the output data; there are two types of data
you can get to a point where you know all of the elements, but there. If we have to come up with two pieces of output data,
you don’t have the faintest clue where to get started when that sounds like two problems instead of one – sneaky!
faced with a new programming challenge. You’ll find that many programming problems look like this
There are, however, some set processes – recipes of – you’ll start with a grand description of what you want to do:
a kind – that you can follow that will help to direct your “I want to make Space Invaders,” but on closer inspection
thinking and make solving a problem much easier. you’ll see that the problem’s actually made up of many
Some of the Python features we use to solve problems smaller ones.
might be unfamiliar, but that’s not really the important thing Identifying these smaller issues, by looking at the data
in this tutorial (you can always look those up on the internet involved, is often the first step to finding a solution. This is
yourself) – the important thing is the thought process that we called top-down development.
must go through.
To demonstrate, we need an example problem, and we’ve Functions: one task at a time
settled on a simple mortgage calculator. Let’s say that Mike Once you’ve identified the smaller problems, your next task
needs a mortgage of £150,000 to buy a nice house in will be to focus in on one. We’re going to start with the
Innsbruck. A bank has agreed to loan him the money at a rate monthly payments problem.
of 6% per annum, with Mike paying it back over 25 years at a If you look back at the tutorial on page 10 of this
fixed monthly rate. Another bank agrees to lend him the bookazine, you’ll see us explaining that functions are great
money, but at 4% per annum, paying it back over 30 years. because they allow you to break a complex task into smaller,
Mike wants to know what his monthly repayments will be in easier ones. Since that sounds exactly the same as what
each situation, and how much interest he’ll have paid in the we’re doing now, let’s try to create a function for our monthly
end. He wants us to help him. The first step when tackling a payments problem.
programming problem is to closely examine the specification. def monthlyPayments(mortgage, interest, term):
Read through the above text carefully and pick out all the monthlyPayments = 0
return monthlyPayments
There’s not much to this function yet; it’s more of a sketch
than something that might be useful, but it’s often helpful to
start with a sketch and fill it out later. Let’s take a look and see
what we have so far.
We’ve given the function a name, and we’ve specified all
the input data as arguments to the function. Since we know
that we’re trying to work out the monthly payments, we’ve
created a variable to hold this information, and instructed the
Check often for function to return it when it’s finished.
bugs in your program. The next thing we need to do is figure out how to combine
(Picture from: www. all those arguments – all that input data – to get the output
flickr.com/photos/ we’re after – monthlyPayments. This is what might be called
fastjack/282707058)
‘specific knowledge’. It’s not really anything to do with
programming, but it’s some extra knowledge that we need to
solve the problem. This is often a vital step in successfully
completing a programming problem: identifying and finding
the specific knowledge necessary to complete the problem.
You can use any source you like, so long as you’re confident
that it’s reliable (your program won’t work properly if it’s

62 | Coding Made Simple


Coding basics | Program structure
based on faulty assumptions). Knowing that we need some
information about how to calculate mortgage repayments, a
quick Google search turned up this handy and entirely
relevant formula on Wikipedia:
c = rP / (1 - (1 + r)^N)
Here, c is the monthly payment, r the monthly interest as
a decimal, P the amount borrowed and N the number of
monthly payments. Notice how all the variables needed to
calculate c in this formula are already provided to our
function as arguments?

Putting it all together


Now we must convert this knowledge into our programming
language of choice, filling out our function sketch.
One important thing to be wary of is that all of the inputs
that we have are in the same units as the formula expects. Mike wants to live here, and he needs us to figure out whether he can afford it!
Because they’re not here, we’ve added a couple of lines to (From Wikipedia’s Innsbruck page.)
convert them.
Also, note that we have changed the argument names to The simplest way to do this is to create a third function that
match the formula. This isn’t necessary, but consistency can calls both the others and prints their output in a pretty
help avoid mistakes. format. This is what our final program looks like:
import math import math

def monthlyPayments(P, r, N): def monthlyPayments(P, r, N):


r = r / 100.0 / 12.0 ...
N = N * 12
monthlyPayments = (r * P) / (1 - math.pow (1 + r), def totalInterest(c, N, P):
(N * 12 * -1))
return monthlyPayments def mortgageComp(P, r, N):
And that’s our function for calculating monthly payments print ‘Monthly Payments:’, monthlyPayments(P, r,
finished. At this point, it’s worth testing what we have put N)
together so far. print ‘Total Interest:’, totalInterest(monthlyPayment
It’s obviously not the complete program, as it doesn’t tell s(P, r, N), N, P)
us anything about the amount of interest paid, but testing
regularly will make spotting and fixing bugs much easier. mortgageComp(150000, 6, 25)
This is a vital step in the development process, and
working like this is known as incremental development. Designing programs
Before you can test code, you need some test cases to So, at the end of all this, what did our whole development
check it with. In this case, come up with a few values of P, r process look like?
and N, and work them out using a calculator. We began by critically reading the problem specification,
Be sure to take note of the expected result. Here’s one and identifying the input and output data involved. By looking
that we came up with: closely at this information, we managed to find
monthlyPayments (200000, 8, 30) = 1467.52 a way to split the problem in two, making it easier and more
Now that we’ve established a test case, modify the code manageable. We called this top-down development. We then
so that the function gets called with these arguments, and developed solutions to each of these as separate functions,
print the result. beginning with sketches and testing each as we progressed.
If everything matches, that’s great. If it doesn’t, a good This was called incremental development.
way of finding out where the problem lies is by adding more Also remember that, where we had to, we looked up
print statements specific knowledge
to check that which allowed us to
certain variables “A good way of finding out solve the problem.
are what you’d
expect them to where the problem lies is by Finally, with
working solutions
be at that point
in the code.
adding more print statements” to all of the
subproblems, we
For example: combined them to
r = r / 100.0 / 12.0 come up with a solution to the original, larger problem.
print r The steps are simple, but this is exactly what you would do
would allow us to check that r was what we expected. to tackle almost any programming problem. For some, you
With the first problem solved, we’re ready to move on to might have to further divide the subproblems, but you would
the second: calculating interest paid. We’ll leave you to do just keep going until you reached a level that was easily
that, following the method laid out here, and instead look at solvable and then work your way back, solving each level as
how you can tie these two functions together. and when you reached it. n

Coding Made Simple | 63


Recursion: round
Coding basics | Recursion

and round we go
Jump down the ultimate rabbit hole of programming ideas, but be careful –
you may well land on your own head.

R
ecursion is one of those concepts that sounds far If we wanted to approach this problem in the same way
more intimidating than it really is. Honestly. To make we’ve been doing with previous tutorials – a strategy known
use of it, you don’t need to grasp complicated as iterative programming – we’d maybe write a function that
mathematical ideas; or start thinking in four dimensions; or multiplied two values within a for loop which was counting
invade one level after another of someone’s dreams to down through the factorial input value. In pseudo code, this
implant an idea into their subconscious; or even understand might look something like the following:
the meaning of recursive acronyms, such as GNU (GNU’s function factorial(c)
not Unix). for i =c, i >= 1, i--
For the most part, many uses of recursion are well total = total *i
documented and explored. You can then just copy and paste print total
them into your code without necessarily understanding how Pseudo code like this is used to explain a concept and to
they work, or why they do what they do. But if you do this, create a template to show the logic of a program, but the
you’re missing out, because recursion is cool. It’s one of the syntax isn’t from any one specific language. It needs to be
best ways of letting the CPU do all the hard work while you detailed and clear enough for the reader to understand the
write a few lines of code; and as a result, it can save you from logic, without being weighed down by the peculiarities or
bending your brain around what might be a more complex eccentricities of one implementation. We’ve used a more
problem without recursion. C-like syntax for the for loop, for instance, because we think
This is because recursion is simply a way of solving a more this is easier to read than the range keyword we’d need to
complex problem by repeating a simple function. The trick is use if we wrote the same code in Python. If you’re working on
that this function repeats from within itself. Rather than being a problem and don’t know how to approach it, writing
run manually from another function, it calls another instance a pseudo code sketch of any potential solution is a great way
of itself from within its own code. It’s the programming of communicating your ideas or proving your concept works.
equivalent of pointing two mirrors together to create a In the above snippet, we create a for loop that uses a variable
seemingly infinite corridor, or connecting to the same virtual called i (that’s a common name for variables within a for
desktop from within a virtual desktop. loop) to step through a range of values. We’ve used the
C-syntax to say this value needs to hold a number more than
X factorial (>) or equal (=) to the value 1, and that it should be increased
In programming, one of the classic, and easiest, examples of by one with every iteration of the loop. In other words, the
recursion is a function to give a number’s factorial. The value of i steps down from c, the input value, to the value 1.
factorial of a positive integer (we have to say this because the Each iteration of the multiplication is controlled by the code,
function would change otherwise) is the product achieved by which is why this is an iterative approach.
multiplying the whole numbers it contains against one You might already see from the previous piece of code
another. The factorial of 4, for example, is 4x3x2x1, which that there’s a slightly more efficient way of achieving the
equals 24. exact same result.
And that way uses recursion. Instead of controlling the
function from a for loop, we’re going to ask the function to
control itself knowing that it has been called from within itself.
That’s confusing to read, but it’s a concept much clearer in
code. Here’s the pseudo code for an updated factorial
function that uses recursion instead:

4 3 2 1 1 2 6 24 function factorial(c)
if c > 1
return c * factorial(c-1)
else
return 1

To calculate the factorial of a number, we can use a function that calls itself All that’s happening here is that we’ve replaced the old
and returns the correct answer. That’s recursion! factorial function with one that calls itself and expects a value

64 | Coding Made Simple


Coding basics | Recursion
in return. Don’t forget that as well as passing values to
a function, the function itself can return a value, usually using
the return keyword, so that the code that called the function
can use the value. You can see that while it’s harder to
understand the logic of how the final value is calculated,
there’s a lot less code than with the iterative approach,
making this solution more efficient and less prone to errors.
This is true of the majority of recursive solutions.
As long as the incoming value is greater than 1, factorial
calls itself with a new value that’s one less than the one it was
called with, and multiplies this by the value that’s returned. If
We generate this fractal with just 16 lines of code. But its complexity is
you call factorial(4), for example, factorial() will be executed potentially infinite.
from within itself with the values 3, 2 and then 1. When it hits
1, the return values start to trickle back because factorial() is distribution doesn’t add this automatically, you’ll have to
no longer being called recursively. 1 is returned and multiplied install it yourself. Using the Turtle graphics module means we Quick
by 2, which itself returns (2x1) to the previous call, which can also see exactly what our script is doing as it’s doing it, tip
returns (3x2x1) which, in turn, returns (4x3x2x1). If you want because the cursor moves slowly along the path as our fractal
If you want your
to see this as Python code so you can try it out, type the is being drawn. Python application
following into the Python interpreter: The fractal we’re going to create is called a star fractal. to pause before
This is a five-pointed star, with another star drawn on to the quitting, or doing
>>> def factorial(c): end of each of its limbs, and a further one on each of those anything else, add
from time import
... if c > 1: limbs, and so on, and on. But to start with, we’re going to sleep to the top of
... return c * factorial(c-1) create a function to draw a star, then expand this to draw your script and use
... else: another star at the correct point. Drawing with Turtle graphics the sleep (seconds)
... return 1 is perfect for fractals because it doesn’t draw lines with command within
your code. This is
... co-ordinates, but instead uses the relative position of
very useful if you
>>> factorial(4) a cursor and an angle to draw the path with the cursor as it want to see the
24 moves forward. final Turtle graphic
>>> factorial(5) import turtle as trtl rendering before the
120 def fractal(length=100): window closes.

>>> if length < 10:


return
The last two lines in that example are simply executing the trtl.fd(length)
factorial() function with the value we want to calculate. When trtl.left(144)
the function finishes and returns the final calculation, the trtl.fd(length)
Python interpreter prints this out without us needing to do trtl.left(144)
anything else, which is why you see the results under this line. trtl.fd(length)
Congratulations – you’ve solved the problem using recursion! trtl.left(144)
You should now be able to see how recursion can be used in trtl.fd(length)
all sorts of places that require an indeterminate amount of trtl.left(144)
repetition, such as many sorting algorithms, other trtl.fd(length)
mathematical solutions and filesystem searches. Even if you trtl.left(144)
can’t think of a solution yourself, if you have an idea that return
something can be approached using recursion, then a simple
Google search will reveal whether it can and what the code, or If you run the above piece of code, either from the
pseudo code, should look like. interpreter, by typing fractal(200), or by adding that
command to the last line in a script, you’ll see the Turtle
Generating fractals cursor first move forward before turning left 144 degrees and
But if you want to visualise recursion in action, which is one of drawing another line. It does this four more times to complete
the quickest ways to understand the concept, there’s one the star. To turn this into a fractal, we want to execute the
particularly effective set of functions that can be used to same function from within the function itself at the end of
illustrate both its advantages and its complexities, and these each limb, and this can be easily achieved by adding
are fractals. Fractal algorithms use recursion to add infinite fractal(length*0.3) after every trtl.fd(length) line. This will
levels of detail to what’s a much simpler algorithm. Some of call the fractal function again, only this time with a length
the most famous were documented by the French value around a third smaller than the original. This star, too,
mathematician Benoît B Mandelbrot in his book, The Fractal will launch other iterations, but the reason why this doesn’t go
Geometry of Nature, but there are many easier algorithms on for ever is because we first check whether the length of
that can be created with just a few lines of code, which is what each line is going to be greater than 10. If it isn’t, then we
we’re going to do using Python. return from the function, and stars will stop being indefinitely
Before we start, though, you will need to make sure you drawn. As with the factorial function, this means that all the
have two dependencies installed. The first is Python’s Turtle other part-completed stars can draw their respective limbs
graphics module, but it should be part of any default Python until the main star itself has finished and the fractal is
installation. We use this to draw and display lines with as little complete. With just a few lines of code, you end up with what
code as possible. The Turtle module itself needs you to install could be an infinitely complex image. And that’s the never
tk-8.5 for its drawing routines, which means if your ending beauty of recursion. n

Coding Made Simple | 65


Coding basics | Sorting algorithms

Super sorting
algorithms
Let’s take our coding further and introduce you to the unruly world of
algorithms, efficiency and sorted data.

P
ython is a great language. You’re happily writing a little in numerical order? Well, it’s pretty simple: you’d look at them,
program, and you’ve got a huge list that you need to and if the card on the left was worth more than the card on
put in order. What do you do? Easy, just call the sort() the right, you’d switch them around; if the card on the right
method on the list, and you’re away. It works amazingly was worth more, you’d leave them as they were.
quickly, and it doesn’t even care how big the list is – it could What would that look like in Python?
be millions of elements long and still take virtually the same cards = [8,2]
amount of time to return the sorted list. if card[0] > card[1]:
This is really handy, but have you ever stopped to wonder card[0] = card[1]
how on earth it works? It’s a fascinating question, and in the card[1] = card[0]
next two articles we’re going to introduce you to some of the print cards
techniques that are used to solve this kind of problem. Along That seems pretty straightforward. There’s a list of cards,
the way, you’ll also get a gentle introduction to algorithms and with the values 8 and 2. We then check to see whether the
how to think about their performance. first card is more valuable than the second, and if it is, copy
So, where do we start? Sorting a list with a computer, like each card to the correct location in the list.
many programming problems, seems incredibly abstract and Run that code and see what happens. You should find that
difficult when you first begin. you don’t get [2,8], but [2,2]. That’s obviously not what we
If you start off trying to think about how to sort a want, so what happened?
Python list with a million items in it, you won’t get anywhere Because there’s no operator in Python that enables us to
very quickly. switch the position of two elements, we did what seems most
natural to us – we used the assignment operator to copy the
Sorting two cards value of the two cards. The problem is that after the first copy
But what if you step back, away from the computer and the statement, we ended up with both cards having the same
list of a million items? Imagine, for example, that you have two value. When we tried to do the second assignment, we just
hearts cards from a deck. How would you put these two cards copied two identical cards.

8 5 2 9

8 2 9
Bubble sort

5
works by
comparing
adjacent
elements in the
list. As it does
so, the largest
element ‘bubbles’
its way to the
end of the list.

66 | Coding Made Simple


Coding basics | Sorting algorithms
The way to get around this is to store a copy of the first
card’s value outside of the list, and before we do any copying.
Take a look at this code:
cards = [8,2]
card0 = cards[0]
if card[0] > card[1]:
card[0] = card[2]
card[1] = card0
print cards
If you run that, you should get the correct answer.
Because we stored a copy of the first card’s value when we
overwrote it with the first assignment statement, we could
use the copy to set the second card to the correct value.
In the end, it’s not quite how we would do things in real life,
but it’s pretty close.

Bubble sort
OK, so sorting a list two elements long isn’t particularly
impressive. But we can extend the same technique to sort a
list that has an infinite number of elements – this is known as that there’s nothing else to sort. In total, it had to perform just Bubble sort
bubble sort. two operations. is an algorithm
The idea is that we loop over the entire list, comparing When we add a third card, assuming that they’re in with O(n2)
(and swapping, if necessary) each set of adjacent elements reverse order, bubble sort has to do the most work possible; performance
in turn. it has do two comparisons on each loop, and three loops. – that means
it takes
The element with the greatest value will always end up on In total – that’s six operations.
increasingly
the right-hand side of the comparison, so will always be What about if we add a fourth? It will take three
longer for every
compared in the next pair of elements. Eventually, it will end comparisons on each loop, and four loops. That’s 12 element added.
up at the very end of the list, where it belongs. operations this time. Five cards? That’s four comparisons and
Notice that, if we were to loop over the list only once, we’d five loops: 20 operations.
get only the largest element in the correct position. There’s a definite pattern here. The work done by bubble
The way to get around this is to keep looping over the sort seems to conform to the formula:
list; on each loop, we’ll encounter another largest element num. operations = num. loops x num. comparisons
that always ends up on the right-hand side of each And we can see that the number of loops is always equal
comparison – that is, until it reaches the largest element to the number of elements in the list, and the number of
from the previous iteration. comparisons is always equal to one less than the number
At this point, it won’t move any further, because it’s now in of loops.
the correct position. This means that, if we have n elements, the amount of
We’ll know the list is sorted when we run a loop in which work done by bubble sort is:
nothing gets swapped. This code shows how a bubble sort num. operations = n x (n - 1) = n(n - 1) = n2 - n
might be implemented in Python:
cards = [8, 3, 7, 4, 2, 1] Big O
swapped = True What this means is that the amount of work bubble sort does
while swapped: #sort until swapped is False increases in polynomial time for every item added to the list.
swapped = False #assume nothing is swapped That is to say the increase in the amount of work becomes
for i in range(len(cards) - 1): #loop entire list more and more rapid for every element added to the list. This
cur = cards[i] is why it’s so slow for large lists – a 10-element list may take
j=i+1 only 90 operations, but a 1,000-element list will take 999,000
if cards[i] > cards[j]: operations, and it will simply get worse for every card from
cards[i] = cards[j] there on.
cards[j] = cur In the general case given above, the n2 term is always
swapped = True #reset swapped to True if anything going to be far larger than the n term, and hence will always
is swapped have a much larger influence on how well the algorithm
print cards performs. Because of this, when discussing the performance
of an algorithm, in computer science it’s only ever the largest
Speed matters term that’s considered.
It’s pretty clever, right? You can now use this program to sort The terminology used for this is ‘big O’ notation, and we
any size list and it will get the job done. However, if you try to say that bubble sort is a O(n2) algorithm. Bubble sort is
use it on a large list, you’ll find that it’s painfully slow – even actually considered to be one of the worst-performing sorting
on a fast computer. algorithms, and it’s definitely not how Python does it.
To understand why this is, let’s think a little about how That said, don’t discard it entirely. It’s easy to implement,
much work our bubble sort algorithm has to do. When we had and works all right for small lists on fast computers.
just two cards, bubble sort had to do two comparisons – once There may be times when you just want to get the job
to get the cards in the correct place, and then again to check done, and bubble sort makes the most sense here. n

Coding Made Simple | 67


Coding basics | Integers

Hidden secrets
of numbers
Allow us to channel the living spirit of Dan Brown, and uncover the hidden
meaning behind 1, 2 and -1b1010101.

Y
ou wouldn’t think that numbers would be a relevant memory. The position of each bit within a binary value
topic in the 21st century. After all, if there’s one thing represents a number that’s double the bit to the right of it,
computers can do well, it’s count them. Billions of giving a sequence of bits the ability to represent every value
times a second. But for better or worse, having some between zero and double the value of the most significant bit
knowledge of how computers deal with numbers, and the minus 1 (or 28-1). That’s a difficult couple of sentences to
systems used to process them, will help you to write better digest, so here are some examples:
programs. And it’s not all for low-level stuff like assembler The positions within an 8-bit binary number have the
either. Number systems are just as important for high-level following values: 1, 2, 4, 8, 16, 32, 64 and 128. But rather than
languages. If you write a PHP script for the web, for example, assign them in that order, the most significant bit – the one
small changes in the way you process numbers within the holding the largest value – is usually on the left. So, the binary
script can have a huge impact on the performance of your number 10, or 00000010, is equivalent to 2. If we move that
servers. Your code bit to the left so
might be run that the 1
thousands of “The position of each bit within a occupies the third
times a second,
making any small binary value represents a number slot along, the
total value
discrepancy in
how those
that’s double the bit to the right” doubles to 4, and
so on. If we
numbers are enable more than
calculated or stored have an impact on performance. one bit at a time, then all the values are added together, so
Numbers are important because they engage the CPU at that 00000011 represents 3 (1+2) and 10000011
its lowest level, right down to hardware and design. Typically, a represents 131 (128+2+1). If we enable every bit in an 8-bit
single operation of the CPU can deal only with a value held binary number, we get a maximum value of 255.
If you want
within one of its internal registers. And that value can be as
to see binary
registers update
large only as the number of bits the CPU supports. These 2’s compliment
days, that means either 32 or 64 bits. But what’s a bit? It’s Consider the following question: what does 10101010
in real time,
KCalc has a literally a switch that’s turned on or off – a single bit of represent in 2’s compliment? You might think, after the last
handy display information, and this is normally represented by a 1 for on couple of paragraphs, that the binary value represented here
mode for up to and a 0 for off. Computers use a numeral system called is 170 (2+8+32+128). But you’d be wrong. The clue is the
64 bits of data. binary to store these on/off values within their registers and reference to 2’s compliment. This is, in fact, a scheme for
representing negative values in binary, and it changes the
meaning of the bits and what they represent. It does this by
reversing the configuration of bits, so that 1 becomes 0, a
process known as flipping, and adding 1 (there is a single
exception to this).
So, the negative of 00000010 is first 11111101, then with 1
added 11111110, which is the 2’s compliment representation
of -2. Using this logic with the above question, we first
subtract 1 from 10101010 to get 10101001 and flip the bits to
01010110, which gives a decimal value of 86, so the answer
to the question is -86. The reason this method was chosen
rather than swapping the most significant bit is because most
binary arithmetic can still be performed on these negative
values in exactly the same way they’re performed on positive
values. Adding 1 to 10101010 (-86), say, yields 10101011,
which is -85 – the correct value.
While we’re in the binary zone, it’s worth mentioning
a couple of other numeral systems sometimes used when
programming. The first is octal, a base 8 system that uses the

68 | Coding Made Simple


Coding basics | Integers
numerals 0-7 to hold 8 values. 7+1, for example, is 10 in octal, BITWISE OPERATORS
just as 9+1=10 in decimal. It takes exactly three binary bits to
represent a value in octal, which is why it’s often used when NOT AND
you play with binary values. Similarly, hexadecimal, which is
1 1 1Ø
Ø1 1Ø
base 16, uses the characters 0-9 and a-f to represent decimal

Ø1 1 1
values 0-15, and that’s the equivalent of four bits of data. So,
the number 6c in hex is 0110 (6) and 1100 (12 = c) in binary,
which as an 8-bit value equates to 108. Hex is a more
= 1 ØØ 1
readable equivalent to binary, which is why it’s often used for
memory and binary editors, and for storing raw binary data
within your program.
=Ø 1 1 Ø
You can avoid using these numeral systems in your code
and your projects won’t suffer. But understanding a little OR XOR
about what they mean and how they relate to one another
can help you when looking at other projects, and how the
1 1 1Ø 1 1 1Ø
Ø1 1 1 Ø1 1 1
underlying systems that take your code and make it run work.
If you want to play with numeral systems, you can do so using
Python’s interpreter, and this is a great way of getting familiar
with how the numbers work. From version 2.6 onwards, for
example, you can enter a binary value using the 0b prefix – =1 1 1 1 = 1 ØØ 1
that’s a zero followed by the b. Typing a binary number will
output the decimal value:
>>> 0b01010110 have a processor capable of handling 64-bit instructions. For Binary and
86 that reason, like early bytes, there’s no standard storage size bitwise operators
You can convert values to binary using the bin function: for many data types. It always depends on your computer’s bring logic to
>>> bin(86) hardware and its internal representation of a value as bits. your programs.
‘0b1010110’ The best example is an ordinary integer, which is most often
>>> bin(-85) defined as int in programming languages such as C and C++.
‘-0b1010101’ The largest number an int can hold depends on the
As you can see with the last example, this also works with architecture of your CPU, and this limit is hidden within
negative integers, returning a 2’s compliment binary. If you something called an include file for C and C++, and an
want to input a 2’s compliment binary, you need to prefix the equivalent for other languages. On most machines, you’ll find
data with -0b. You can do similar things with octal by that an unsigned int can hold a maximum value of
replacing the 0b with 0c and with hexadecimal by using 0x, 4294967295, and if you paste this value into a binary
and both of these numeral types have supporting functions calculator, you’ll see this requires 32 bits of storage –
for converting integers: probably the most common architecture in use. Even 64-bit
>>> hex(85) machines can properly interpret 32-bit values.
‘0x55’ This is why an int is usually the most generic variable Quick
>>> oct(85) type; it can store large numbers and can be addressed tip
‘0o125’ efficiently by most recent x86 CPUs. If you need larger, there’s
long int and if you need smaller, there’s short int. You Understanding

Data types generally don’t need to worry about any of this in languages
how bits and bytes
hold together is
In many programming languages, you need to specify the such as Python, unless you want to, because the designers essential if you want
type of a variable before you can use it. This can cause have decided to forgo the advantages of specifying the size of to read or write to
confusion in the beginner, because they wonder how they’re a variable for the simplicity it gives to programming. This is an binary formats, or
create a utility that
supposed to know what they need to use before they write example of something known as Duck typing, and it’s another
communicates with
the code. But, in reality, you write the declaration for each reason why Python is such a good beginner’s language. external hardware.
variable as you come to use them. One set of types we’ve neglected to cover is those that
The compiler or interpreter needs to know about type include a floating point, such as 0.5 or 3.14159. Rather than
because it wants to assign only enough memory and worry about the size of a float, it’s the precision that’s
processing to handle that number, and no more. If you know important. But unless you’re dealing with small fractions, it’s
your variable is never going to have a value greater than 255 usually enough just to create a variable of type float to deal
(the value held by an 8-bit value), there’s no need for the with these numbers.
compiler to ensure more than this amount of storage is The biggest problems when dealing with floating point
available. An 8-bit value has become known as a byte. numbers, and why programmers try to stick to integers, are
Although the number of bits in a byte used to vary, it has introduced by rounding a value up or down from a more
settled on 8, because this is typically used to store a single precise number, such as when rounding the value of pi to 3.
character. A byte’s worth of data is still used to store While small rounding errors aren’t likely to cause problems,
characters to this day, which you can view through ASCII they do when many of these are combined. This problem, and
codes with any reasonable binary editor. its dire consequences, was brilliantly illustrated by Richard
But computer hardware has moved on, through the Pryor’s character in Superman III when he siphoned off the
16/32-bit era of the Atari ST and Amiga, to the pure 32-bit rounding errors in employees’ payslips into his own account,
PCs of the last decade and to today, where most machines and amassed a large fortune. n

Coding Made Simple | 69


Coding basics | Using loops

Using loops and


using loops
If we have explained how to use loops adequately, move to the next page.
Otherwise, try reading this again.

A
fter losing ourselves in the surprisingly complex problem by adding a loop in your code. In many ways, they’re
domain of using numbers in our code, we’re returning related to the idea of recursion. But where a loop or function
to a simpler concept. It’s the idea of a loop, and how in recursion calls another instance of itself, usually to build a
programmers use them to solve problems. A loop, in the more complex solution, a loop on its own is used mostly to
programming sense, is a chunk of the same code that’s solve a simple calculation, or for waiting for a specific
designed by the programmer to be run over and over again. condition. Which is why, perhaps, the most common loop
It’s different from a function or a method, because while combines a conditional statement within a loop’s structure –
they’re both designed to be re-run over and over again too, and that’s the for keyword. The for loop is one of those
they’re self-contained islands of logic. peculiar parts of any language, because it requires a specific
With a method or a function, the programmer needs to syntax that doesn’t feel that logical. In the case of Python, a
know only what input is needed and what output to expect. typical for loop looks like the following:
Everything else should be handled by the function. A loop is a >>> for i in range (5):
much more primitive construction, and without loops almost ... print (i)
any programming task would become impossibly tedious. ...
This is because they encapsulate what computers do well: 0
repetition and iteration. Without loops, programmers are 1
forced to write everything in longhand, and write code that 2
can’t accommodate unknown values or sizes. It’s the 3
difference between sowing a field by hand or by using Jethro 4
Tull’s horse-drawn You can see in this snippet
seed drill. that the initial for statement
If you want to
build your own
Loops are so
integral to code,
“Without loops, almost any requires a variable, which for
some reason is nearly always
C++ application,
add the source
we’ve already programming task would called i in examples. Ours is

code to a text file


and build it with
used several of
them in our become impossibly tedious” no exception. This is followed
in Python by the phrase in
examples in range (5). Range is a special
the command
‘g++ helloworld. previous tutorials in this bookazine. They’re used as counters, keyword in Python that we’ll revisit in a couple of paragraphs.
cpp -o helloworld’. as ways to step through data, for when you need to wait for a On the following line, we print the value of i. This line needs to
Just run ‘./ condition, and for filling arrays and files. But we’ve not spent be tabbed or spaced in because it’s going to be executed as
helloworld’ to see any time discussing the various kinds of loops you can part of the for loop (as denoted by the :).
the results. implement, or how you might attempt to solve a linear But without prior experience, you can’t really guess at the
output from the syntax of the for loop, and it’s the same with
other languages. This is because for is slightly different from
most loops, because it includes the implicit definition of a
variable. You just have to accept that whatever syntax they do
use does the equivalent of defining a variable and creating an
acceptable set of circumstances for the execution of your
program to leave the loop. In our previous example, the
variable i iterates between 0 and 4, leaving the loop when it
gets to 5 (a total of five steps when you include zero). We print
the value of i within the loop so you can see what’s
happening. If you write the same thing in C or C++, the syntax
looks slightly different, but it gives you a better insight into
what’s happening:
for ( int i=0 ; i < 5 ; i++ ){
cout << i << endl;
}
When compiled, linked and run (this is the big difference

70 | Coding Made Simple


Coding basics | Using loops
between compiled languages such as C/C++ and interpreted
languages such as Python and JavaScript), the output is
identical to our Python example from earlier. In the C++ code,
the variable i is declared as an integer (int) and incremented
(i++) one value at a time for as long as it remains less than 5
(<5). This is exactly what the Python loop is doing, and the
cout line is simply printing out the value of i during each
iteration. You should be able to see from this that both the
value of i and the value checked for by the condition can be
changed, so you could get the value of i to count down
instead by changing the loop to:
for ( int i=5 ; i > 0 ; i--){
cout << i << endl;
}
To do the same in Python, we need to take a closer
look at the range keyword used in the first example. Range
is a function in Python that takes a start point, a stop point
and a step size, much the same as the inputs for a C++ for
loop. It’s also much more versatile, as you don’t need to
restrict yourself to numbers – range can use indices of
Python is still
a sequence. If you put on one value in the range, as we end of the test. In C++, this function would look like this:
a great language
did in the original loop, the function counts from zero up to char c;
to learn with
the value -1. However, anything else will create a different do { because it lets
effect. The advantage of farming it out to a function is that cin >> c; you experiment
you’re no longer restricted to using it in just the for loop, and } while (c != ‘x’); and see results
you’ll find many programmers use range for convenience This example is oversimplified, and isn’t useful in itself, but as soon as you’ve
throughout their code. If you wanted to count down in Python, it illustrates one example where do...while works well, and typed your code.
for example, you could modify the for loop, as follows: that’s taking input. If you want to check the state of some
for i in range(5, 0, -1): input, whether it’s from a file or from someone typing on the
print (i) keyboard, you need to have first grabbed the input. You could
do this in a normal while loop by asking for the input before
Infinite loop you enter the loop, but it’s slightly more efficient and elegant
If you don’t need the iteration of a for loop, the best if you use a do...while loop to encapsulate the entire function.
alternative is a while loop. This includes only the conditional This is all the above loop is doing in C++. It grabs some input
check, and you’re free to make that check positive in any way from the keyboard using cin, and waits for that input to
you choose. You could easily emulate the behaviour of a for consist only of the x character, after which it quits the loop.
loop, for example, by making the while loop wait for a variable Another common use for while is to create what’s known as
to reach a certain value. Then, within your block of code, an infinite loop – simply a loop that never satisfies its exit
make sure your calculations attain that value at some point. condition. This might sound like insanity if you ever want the
Quick
In Python, we could recreate the previous for loop using processor to skip over the remainder of your code, but there
tip
while, like this: are certain times, and languages, where the use of an infinite Nearly all languages
>>> i = 5 loop is the best way of building your application. One example count zero as a
>>> while i > 0: is if you want to build a tool to monitor the state of a server or value, such as the
first position in an
... i -= 1 some other service.
array. This seems
... print (i) You also find infinite loops watching hardware inputs or illogical at first,
... controlling the rendering within a game engine. Using an because we’re used
4 infinite loop means you can be sure your application is to thinking of zero
as nothing, but it’s
3 running, and hasn’t exited under some other condition, and
just something you
2 using while is probably the easiest way of creating one. while have to get used to.
1 (true) {} is all that’s needed. However, many languages also
0 provide an escape from loops like this, and that’s using
It’s simpler this way, and by using while you can make the something called the break command. break can be used to
conditional checks for leaving a loop as complex as you need, escape from an infinite loop, as well as leaving other kinds of
rather than adhering to those required by for. Another trick in loops early if you need to. You might want to escape from a
other languages, but not Python, is to place the conditional for loop quickly, for example if you have detected that the
checking at the end of the block of code. This is normally user wants to quit the application. Using break, the execution
called a do...while loop, because the do is used to start the of your code continues after the loop section, and you’d
section and the while is used to close the section. normally use this section of code to tidy up files, processes
Most importantly, the while statement at the end of the and memory before an exit. Of course, there’s a good case for
loop is checking the condition, such as ‘do the washing up arguing against infinite loops, and building into your code the
while there are still some dirty plates’. This can be helpful in ability to escape on a specific condition, but this can take
certain circumstances, such as when you want the loop to more effort and might not be as efficient, especially for
take some input and then only test against that input at the smaller applications. n

Coding Made Simple | 71


Coding basics | Compilers

The magic of
compilers
A compiler turns human-readable code into machine code, but there’s a
difference between compiled and interpreted languages.

C
omputers aren’t actually very smart. Sure, they can do a compiler, and it’s one of the most important components of
a million things in the space of a second, and help us an operating system.
to transmit videos of cats around the internet, but Compilers exist for many different programming
they don’t understand human languages. Ultimately, languages, but here we’re going to focus on C, because it’s
everything in a computer boils down to binary – ones and the language used for many important projects, such as the
zeros – because that’s all that a CPU understands. For us Linux kernel. By far the most common compiler on Linux is
programmers, this makes things a bit complicated. We can’t GCC, from the GNU project, and that is what we are going to
directly tell the CPU in English that we want to print a use here.
message on the screen, wait for a key to be pressed and so
forth; we have to somehow tell the machine this information Dissecting a program
in binary. But then, imagine if your programs looked like this: First up, consider this simple C program:
10010010 11100011 #include <stdio.h>
01011011 10001101 int main()
... {
That would be a nightmare, wouldn’t it? Finding mistakes puts(“Hello, world!”);
would be nigh-on impossible, and if you gave your code to }
someone else for modification… Well, the entire concept of This simply prints the message “Hello world!” to the
free/open source screen. If you’ve
software falls never seen C before,
apart. So, to fix
this problem, we
“In a compiled language, source you might be a bit
puzzled by some of

Try to read
use compiled and code is processed, pulled apart the text, so here’s a

and converted into binary code”


interpreted brief explanation:
a binary
languages (more the #include line
executable file in
on the latter says that we want to
a text editor, and
you’ll just see
later). In a compiled language, human-readable source code use standard input and output routines (stdio). Then main
a load of messed- is processed, pulled apart, jumbled up and eventually says that this is the main part of our program (that is, where
up characters converted into binary code that the CPU can understand. The execution should begin), and the puts command means “put
like this. program that does this is called – naturally enough – a string”.
Enter this text into a file called foo.c and then run the
following commands:
gcc foo.c
./a.out
The first command uses GCC to compile foo.c from the
source code into a binary executable file called a.out, and the
second line runs it. You can get more information about the
resulting file by running file a.out – you’ll see output similar
to the following:
a.out: ELF 32-bit LSB executable, Intel 80386, version 1
(SYSV), dynamically linked (uses shared libs), for GNU/
Linux 2.6.15, not stripped
If you try to examine the file yourself, using less a.out for
instance, then you’ll just see gobbledygook, as in the
screenshot shown on the left. This is because we mere
mortals can’t read binary, and so less is trying to convert it
into plain text characters.
This final, resulting file isn’t intended for human
consumption, but we can peek into some of the stages in the
compilation process. First of all, enter this command:

72 | Coding Made Simple


Coding basics | Compilers
gcc -E foo.c > foo.p
With the -E switch, we tell GCC that we don’t want a binary
executable file just yet; instead, we want only to see what
happens after the first stage of processing. Open foo.p in a
text editor and you’ll see that it’s much longer than the
original program, because the contents of the stdio.h file
have been included in it. It’s only right at the bottom that you
can see the main function and our puts instruction.
In larger, more complicated programs, the compiler does
much more work in this ‘pre-processor’ stage. It expands
macros, handles #define statements and places additional
information into the file for debugging purposes. This file is
then complete, with all the information that GCC needs to
start converting it into machine code.

Assembly
But wait! There’s an intermediate step between the C code
and binary, and it’s called assembly language. Assembly is a
human-readable way of representing the instructions that the
CPU executes. It’s much lower-level than typical languages On the left, the output from gcc -S, and on the right a disassembled binary.
such as C and Python, where you can simply say “print a We’ve highlighted the areas showing identical instructions.
string for me”. In assembly, you have to move memory around
into the video buffer – for instance, telling the CPU exactly a compiler are deep and complex, and many would argue
which instructions it should execute. So, now enter this: that writing a fully-featured compiler for a complicated
gcc -S foo.c language such as C++ is an even harder job than writing an
This produces a file called foo.s that contains the operating system. Think of all the work a compiler has to do
assembly language version of our program. In other words, in terms of managing variables, parsing complicated
it’s a list of CPU instructions written in a slightly more instructions, passing control around to different functions,
readable form. Most of it will look like complete gibberish if and so on.
you have never touched assembly before, but these are the Don’t think for a second that we’ve completely covered
two most important lines: the compiler here. Shelves full of whopping great books have
movl $.LC0, (%esp) been written about the science of compilers – it’s not a
call puts subject for the faint-hearted! But now you know the
Essentially, this places the location of our “Hello world!” fundamentals, and you will certainly look at your code in a
text string into a register (a little like a variable), and then calls different way from this point on. n
the puts (put string) function from the C library. These two

What are interpreted languages?


lines are exact CPU instructions – as programmers, there is
no way that we can break them down into smaller pieces.
Given that modern CPUs execute billions of instructions per
second, it can be quite humbling to see single instructions laid There are two main types of quicker. Similarly, the compiler can spot
programming language: compiled and errors that might come up and warn the
bare like this.
interpreted. As we’ve seen in the former, programmer about them.
In the normal process of compilation (that is, without the
a program called a compiler takes an An interpreter, on the other hand, is a
-E or -S switches), GCC now runs an assembler to convert entire source code file and converts it much simpler program that simply
those human-readable instructions into their binary into CPU binary instructions in one fell steps through the program line-by-line.
equivalents. It then adds extra information to the resulting file swoop. In contrast, an interpreter reads It doesn’t know what’s coming up, and
(a.out) to make it a valid Linux executable, and we have a individual lines from a source code file just dutifully executes things as and
program that’s ready to run. and acts on them one at a time, when it sees them. This offers some
essentially interpreting each instruction advantages, in that you don’t have to
Jump back! at run time. For instance, take this wait for a compilation process to finish
We can take the a.out file and go one step backwards in the BASIC program: before testing your work; and many
10 LET A = 1 interpreters allow you to pause them
process, to the assembly language stage, using the objdump
20 PRINT “Hello world” and make changes in the middle
command, like so:
30 LET A = A + 1 of execution.
objdump -d a.out > list 40 IF A < 6 THEN GOTO 20 Ultimately, most programmers prefer
Have a look at the list file now – it’s a disassembly of the 50 END compiled languages over interpreted
binary file, and therefore full of assembly language It’s pretty clear what this does – it ones because of the performance
instructions. Most of them are unrelated to our program, and prints a message five times on the benefits. Having your whole work
are used to tell the Linux program loader some useful things screen. Now, how would a compiler look condensed down into CPU-readable
and set up the environment. But tucked away in there, you’ll at it? Because a compiler processes the binary makes for better performance
find these lines: source code file as a whole, it sees the than a background program parsing
movl $0x8048490,(%esp) bigger picture, knowing in advance that each line step by step during execution.
the loop is going to be executed five Interpreted languages can, however,
call 80482f0 <puts@plt>
times. Consequently, the compiler can be useful where speed isn’t crucially
Those are the exact same instructions as the ones we saw
make various optimisations, such as important, for example the Bash
a moment ago, expressed in a slightly different way. So, that’s replacing the whole bunch with five scripting language. Precision and
the process of how human-readable source code is converted PRINT lines if that makes execution individual execution rule here.
into CPU-understandable instructions. The inner workings of

Coding Made Simple | 73


Coding basics | Common mistakes

Avoiding common
coding mistakes
Bug reports are useful, but you don’t really want to cause too many.
Here’s what to avoid and how to avoid it.

I
t doesn’t matter how much care you put into writing your becomes important as it starts to grow, and you seldom
code. Even if you’ve had four cups of coffee and triple- revisit these old bits of code.
check every line you write, sooner or later you are going to Whenever you write a decent chunk of functionality, the
make a mistake. It might be as simple as a typo – a missing second thing you should do is add a few comments to
bracket or the wrong number, or it could be as complex as describe what it does and how it does it. Comments are
broken logic, memory problems or just inefficient code. Either simple text descriptions about what your code is doing,
way, the results will always be the same – at some point, your usually including any inputs and expected output. They’re not
program won’t do what you wanted it to. This might mean it interpreted by the language or the compiler – they don’t
crashes and dumps the user back to the command line. But it affect how your code works, they are there purely to help
could also mean a subtle rounding error in your tax returns other developers and users understand what a piece of code
that prompts the Inland Revenue to send you a tax bill for does. But, more importantly, they are there to remind you of
millions of pounds, forcing you to sell your home and declare what your own code does.
yourself bankrupt. This might sound strange, but no matter how clear your
insight might have been when you wrote it, give it a few days,
Finding the problems weeks or months, and it may as well have been written by
How quickly your mistakes are detected and rectified is someone else for all the sense it now makes. And as a
dependent on how complex the problem is, and your skills in programmer, one of the most frustrating things you have to
the delicate art of troubleshooting. For instance, even though do is solve a difficult problem twice – once when you create
our examples of code from previous tutorials stretch to no the code, and again when you want to modify it but don’t
more than 10 lines, you’ve probably needed to debug them as understand how it works. A line or two of simple description
you’ve transferred them from these pages to the Python can save you days of trying to work out what a function
interpreter. When your applications grow more complex than calculates and how it works, or may even obviate the need for
just a few lines or functions, you can spend more time you to understand anything about what a piece of code does,
hunting down problems than you do coding. Which is why as you need to know only the inputs and outputs.
before you worry about debugging, you should follow a few
simple rules while writing your code. The importance of documentation
The first is that, while you can’t always plan what you’re This is exactly how external libraries and APIs work. When you
going to write or how you’re going to solve a specific problem, install Qt, for instance, you’re not expected to understand
you should always go back and clean up whatever code you how a specific function works. You need only to study the
The IDLE
Python IDE has a end up with. This is because it’s likely you’ll have used now- documentation of the interface and how to use it within the
debug mode that redundant variables and bolted on functionality into illogical context of your own code. Everything a programmer needs to
can show how places. Going back and cleaning up these areas makes the know should be included in the documentation. If you want to
your variables code easier to maintain and easier to understand. And use Qt’s excellent sorting algorithms, for example, you don’t
change over time. making your project as easy to understand as possible have to know how it manages to be so efficient, you need to
know only what to send to the function and how to get the
results back.
You should model your own comments on the same idea,
both because it makes documentation easier, and because
self-contained code functionality is easier to test and forget
about. But we don’t mean you need to write a book. Keep
your words as brief as they need to be – sometimes that
might mean a single line. How you add comments to code is
dependent on the language you’re using. In Python, for
example, comments are usually demarcated by the # symbol
in the first column of a line. Everything that comes after this
symbol will be ignored by the interpreter, and if you’re using
an editor with syntax highlighting, the comment will also be
coloured differently to make it more obvious. The more detail

74 | Coding Made Simple


Coding basics | Common mistakes
you put into a comment the better, but don’t write a book.
Adding comments to code can be tedious when you just want
to get on with programming, so make them as brief as you
can without stopping your flow. If necessary, you can go back
and flesh out your thoughts when you don’t feel like writing
code (usually the day before a public release). When you start
to code, you’ll introduce many errors without realising it. To
begin with, for example, you won’t know what is and isn’t a
keyword – a word used by your chosen language to do
something important. Each language is different, but Python’s
list of keywords is quite manageable, and includes common
language words such as and, if, else, import, class and
break, as well as less obvious words such as yield, lambda,
raise and assert. This is why it’s often a good idea to create
your own variable names out of composite parts, rather than
go with real words. If you’re using an IDE, there’s a good
chance that its syntax highlighting will stop you from using a good at catching these problems. Another type of problem You have to be
protected keyword. Python is good at avoiding is inaccurate indenting. This is careful in Python
where conditions and functions use code hierarchy to split that the colons
Undeclared values the code into parts. Python enforces this by breaking
and indentation
are in the correct
A related problem that doesn’t affect Python is using execution if you get it wrong, but other languages try to make
place, or your
undeclared values. This happens in C or C++, for instance, if sense of code hierarchy, and sometimes a misplaced bracket script won’t run.
you use a variable without first saying what type it’s going to is all that’s needed to create unpredictable results. However, But this does
be, such as int x to declare x an integer. It’s only after doing this can make Python trickier to learn. Initially, if you don’t stop a lot of
this you can use the variable in your own code. This is the big know about its strict tabbed requirements, or that it needs a runtime errors.
difference between compiled languages and interpreted ones. colon at the end of compound statement headers, the errors
However, in both languages, you can’t assume a default value created don’t make sense. You also need to be careful about
for an uninitialised variable. Typing print (x) in Python, for case sensitivity, especially with keywords and your own
instance, will result in an error, but not if you precede the line variable names.
with x = 1. This is because the interpreter knows the type of a When you’ve got something that works, you need to test it
variable only after you’ve assigned it a value. C/C+ can be – not just with the kind of values your application might
even more random, not necessarily generating an error, but expect, but with anything that can be input. Your code should
the value held in an uninitialised variable is unpredictable until fail gracefully, rather than randomly. And when you’ve got
you’ve assigned it a value. something ready to release, give it to other people to test.
Typos are also common, especially in conditional They’ll have a different approach, and will be happier to break
statements, where they can go undetected because they are your code in ways you couldn’t imagine. Only then will your
syntactically correct. Watch out for using a single equals sign code be ready for the wild frontier of the internet, and you’d
to check for equality, for example – although Python is pretty better wear your flameproof jacket for that release. n

Comment syntax
Different languages mark comments differently, and there seems to be of code on the same line, and they’re initiated by using a couple of
little consensus on what a comment should look like. However, there are characters before the comment. Block comments are used to wrap pieces
a couple of rules. Most languages offer both inline and block comments, of text (or code you don’t want interpreted/compiled), and usually have
for example. Inline are usually for a single line, or a comment after a piece different start and end characters.

# A hash is used for comments in many scripting languages. When # is followed by a ! it becomes a shebang # and is used to
Bash tell the system which interpreter to use, for example: #!/usr/bin/bash

BASIC REM For many of us, this is the first comment syntax we learn

C /* This kind of comment in C can be used to make a block of text span many lines */

C++ // Whereas this kind of comment is used after the // code or for just a single line

<!-- Though not a programming language, we’ve included this because you’re likely to have already seen the syntax, and
HTML therefore comments, in action -->

Java /** Similar to C, because it can span lines, but with an extra * at the beginning */
= heading Overview
As well as the hash, in Perl you can also use something called Plain Old Documentation. It has a specific format, but it does
Perl force you to explain your code more thoroughly
=cut
‘’’ As well as the hash, Python users can denote blocks of comments using a source code literal called a docstring, which is
Python a convoluted way of saying ‘enclose your text in blocks of triple quotes’, like this ‘’’

Coding Made Simple | 75


rubyracer”, “~> 0.11.4” group :development, :test do gem “rspec-rails”, “~> 2.13.0” $ gem install bundler $ gem install rails --version=3.2.12 $ rbenv rehash $ rails
ate_attributes(params[:task]) format.html { redirect_to @task, notice: ‘...’ } format.json { head :no_content } else format.html { render action: “edit” } format.json { ren
xec rails generate migration add_priority_to_tasks priority:integer $ bundle exec rake db:migrate $ bundle exec rake db:migrate $ bundle exec rails server validate
_at, ‘is in the past!’) if due_at < Time.zone.now #!/usr/bin/en python import pygame from random import randrange MAX_STARS = 100 pygame.init() screen = py
tars = for i in range(MAX_STARS): star = [randrange(0, 639), randrange(0, 479), randrange(1, 16)] stars.append(star) while True: clock.tick(30) for event in pygame
$numstars = 100; use Time::HiRes qw(usleep); use Curses; $screen = new Curses; noecho; curs_set(0); for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] = rand(80); $s
>clear; for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] -= $star_s[$i]; if ($star_x[$i] < 0) { $star_x[$i] = 80; } $screen->addch($star_y[$i], $star_x[$i], “.”); } $screen->refre
ment, :test do gem “rspec-rails”, “~> 2.13.0” $ gem install bundler $ gem install rails --version=3.2.12 $ rbenv rehash $ rails new todolist --skip-test-unit respond
ml { redirect_to @task, notice: ‘...’ } format.json { head :no_content } else format.html { render action: “edit” } format.json { render json: @task.errors, status: :unpro
rity_to_tasks priority:integer $ bundle exec rake db:migrate $ bundle exec rake db:migrate $ bundle exec rails server validate :due_at_is_in_the_past def due_at_is_
one.now #!/usr/bin/en python import pygame from random import randrange MAX_STARS = 100 pygame.init() screen = pygame.display.set_mode((640, 480)) c
star = [randrange(0, 639), randrange(0, 479), randrange(1, 16)] stars.append(star) while True: clock.tick(30) for event in pygame.event.get(): if event.type == pyg
Res qw(usleep); use Curses; $screen = new Curses; noecho; curs_set(0); for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] = rand(80); $star_y[$i] = rand(24); $star_s[$i]
rs ; $i++) { $star_x[$i] -= $star_s[$i]; if ($star_x[$i] < 0) { $star_x[$i] = 80; } $screen->addch($star_y[$i], $star_x[$i], “.”); } $screen->refresh; usleep 50000; gem “theru
ils”, “~> 2.13.0” $ gem install bundler $ gem install rails --version=3.2.12 $ rbenv rehash $ rails new todolist --skip-test-unit respond_to do |format| if @task.update_
.’ } format.json { head :no_content } else format.html { render action: “edit” } format.json { render json: @task.errors, status: :unprocessable_entity } $ bundle exec rails
exec rake db:migrate $ bundle exec rake db:migrate $ bundle exec rails server validate :due_at_is_in_the_past def due_at_is_in_the_past errors.add(:due_at, ‘is in th
ygame from random import randrange MAX_STARS = 100 pygame.init() screen = pygame.display.set_mode((640, 480)) clock = pygame.time.Clock() stars = for i in ran
drange(1, 16)] stars.append(star) while True: clock.tick(30) for event in pygame.event.get(): if event.type == pygame.QUIT: exit(0) #!/usr/bin/perl $numstars = 100;
oecho; curs_set(0); for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] = rand(80); $star_y[$i] = rand(24); $star_s[$i] = rand(4) + 1; } while (1) { $screen->clear; for ($i = 0; $i <
ar_x[$i] = 80; } $screen->addch($star_y[$i], $star_x[$i], “.”); } $screen->refresh; usleep 50000; gem “therubyracer”, “~> 0.11.4” group :development, :test do gem “rsp
sion=3.2.12 $ rbenv rehash $ rails new todolist --skip-test-unit respond_to do |format| if @task.update_attributes(params[:task]) format.html { redirect_to @task, noti

CODING
ction: “edit” } format.json { render json: @task.errors, status: :unprocessable_entity } $ bundle exec rails generate migration add_priority_to_tasks priority:integer $ b
exec rails server validate :due_at_is_in_the_past def due_at_is_in_the_past errors.add(:due_at, ‘is in the past!’) if due_at < Time.zone.now #!/usr/bin/en python impo
game.init() screen = pygame.display.set_mode((640, 480)) clock = pygame.time.Clock() stars = for i in range(MAX_STARS): star = [randrange(0, 639), randrange(0, 47
or event in pygame.event.get(): if event.type == pygame.QUIT: exit(0) #!/usr/bin/perl $numstars = 100; use Time::HiRes qw(usleep); use Curses; $screen = new Curs
$i] = rand(80); $star_y[$i] = rand(24); $star_s[$i] = rand(4) + 1; } while (1) { $screen->clear; for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] -= $star_s[$i]; if ($star_
i], “.”); } $screen->refresh; usleep 50000; gem “therubyracer”, “~> 0.11.4” group :development, :test do gem “rspec-rails”, “~> 2.13.0” $ gem install bundler $ gem
-skip-test-unit respond_to do |format| if @task.update_attributes(params[:task]) format.html { redirect_to @task, notice: ‘...’ } format.json { head :no_content } else form

MADE
rors, status: :unprocessable_entity } $ bundle exec rails generate migration add_priority_to_tasks priority:integer $ bundle exec rake db:migrate $ bundle exec rake d
ast def due_at_is_in_the_past errors.add(:due_at, ‘is in the past!’) if due_at < Time.zone.now #!/usr/bin/en python import pygame from random import randrange MA
e((640, 480)) clock = pygame.time.Clock() stars = for i in range(MAX_STARS): star = [randrange(0, 639), randrange(0, 479), randrange(1, 16)] stars.append(star) wh
e == pygame.QUIT: exit(0) #!/usr/bin/perl $numstars = 100; use Time::HiRes qw(usleep); use Curses; $screen = new Curses; noecho; curs_set(0); for ($i = 0; $i <
$star_s[$i] = rand(4) + 1; } while (1) { $screen->clear; for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] -= $star_s[$i]; if ($star_x[$i] < 0) { $star_x[$i] = 80; } $screen->add
em “therubyracer”, “~> 0.11.4” group :development, :test do gem “rspec-rails”, “~> 2.13.0” $ gem install bundler $ gem install rails --version=3.2.12 $ rbenv rehash $

SIMPLE
update_attributes(params[:task]) format.html { redirect_to @task, notice: ‘...’ } format.json { head :no_content } else format.html { render action: “edit” } format.json {
exec rails generate migration add_priority_to_tasks priority:integer $ bundle exec rake db:migrate $ bundle exec rake db:migrate $ bundle exec rails server validate
_at, ‘is in the past!’) if due_at < Time.zone.now #!/usr/bin/en python import pygame from random import randrange MAX_STARS = 100 pygame.init() screen = py
tars = for i in range(MAX_STARS): star = [randrange(0, 639), randrange(0, 479), randrange(1, 16)] stars.append(star) while True: clock.tick(30) for event in pygame
$numstars = 100; use Time::HiRes qw(usleep); use Curses; $screen = new Curses; noecho; curs_set(0); for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] = rand(80); $s
>clear; for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] -= $star_s[$i]; if ($star_x[$i] < 0) { $star_x[$i] = 80; } $screen->addch($star_y[$i], $star_x[$i], “.”); } $screen->refre
ment, :test do gem “rspec-rails”, “~> 2.13.0” $ gem install bundler $ gem install rails --version=3.2.12 $ rbenv rehash $ rails new todolist --skip-test-unit respond
ml { redirect_to @task, notice: ‘...’ } format.json { head :no_content } else format.html { render action: “edit” } format.json { render json: @task.errors, status: :unpro
rity_to_tasks priority:integer $ bundle exec rake db:migrate $ bundle exec rake db:migrate $ bundle exec rails server validate :due_at_is_in_the_past def due_at_is_
one.now #!/usr/bin/en python import pygame from random import randrange MAX_STARS = 100 pygame.init() screen = pygame.display.set_mode((640, 480)) c
star = [randrange(0, 639), randrange(0, 479), randrange(1, 16)] stars.append(star) while True: clock.tick(30) for event in pygame.event.get(): if event.type == pyg
Res qw(usleep); use Curses; $screen = new Curses; noecho; curs_set(0); for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] = rand(80); $star_y[$i] = rand(24); $star_s[$i]
rs ; $i++) { $star_x[$i] -= $star_s[$i]; if ($star_x[$i] < 0) { $star_x[$i] = 80; } $screen->addch($star_y[$i], $star_x[$i], “.”); } $screen->refresh; usleep 50000; gem “theru
ils”, “~> 2.13.0” $ gem install bundler $ gem install rails --version=3.2.12 $ rbenv rehash $ rails new todolist --skip-test-unit respond_to do |format| if @task.update_
.’ } format.json { head :no_content } else format.html { render action: “edit” } format.json { render json: @task.errors, status: :unprocessable_entity } $ bundle exec rails
exec rake db:migrate $ bundle exec rake db:migrate $ bundle exec rails server validate :due_at_is_in_the_past def due_at_is_in_the_past errors.add(:due_at, ‘is in th
ygame from random import randrange MAX_STARS = 100 pygame.init() screen = pygame.display.set_mode((640, 480)) clock = pygame.time.Clock() stars = for i in ran
drange(1, 16)] stars.append(star) while True: clock.tick(30) for event in pygame.event.get(): if event.type == pygame.QUIT: exit(0) #!/usr/bin/perl $numstars = 100;
oecho; curs_set(0); for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] = rand(80); $star_y[$i] = rand(24); $star_s[$i] = rand(4) + 1; } while (1) { $screen->clear; for ($i = 0; $i <
ar_x[$i] = 80; } $screen->addch($star_y[$i], $star_x[$i], “.”); } $screen->refresh; usleep 50000; gem “therubyracer”, “~> 0.11.4” group :development, :test do gem “rsp
sion=3.2.12 $ rbenv rehash $ rails new todolist --skip-test-unit respond_to do |format| if @task.update_attributes(params[:task]) format.html { redirect_to @task, noti
ction: “edit” } format.json { render json: @task.errors, status: :unprocessable_entity } $ bundle exec rails generate migration add_priority_to_tasks priority:integer $ b
exec rails server validate :due_at_is_in_the_past def due_at_is_in_the_past errors.add(:due_at, ‘is in the past!’) if due_at < Time.zone.now #!/usr/bin/en python impo
game.init() screen = pygame.display.set_mode((640, 480)) clock = pygame.time.Clock() stars = for i in range(MAX_STARS): star = [randrange(0, 639), randrange(0, 47
or event in pygame.event.get(): if event.type == pygame.QUIT: exit(0) #!/usr/bin/perl $numstars = 100; use Time::HiRes qw(usleep); use Curses; $screen = new Curs
$i] = rand(80); $star_y[$i] = rand(24); $star_s[$i] = rand(4) + 1; } while (1) { $screen->clear; for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] -= $star_s[$i]; if ($star_
i], “.”); } $screen->refresh; usleep 50000; gem “therubyracer”, “~> 0.11.4” group :development, :test do gem “rspec-rails”, “~> 2.13.0” $ gem install bundler $ gem
-skip-test-unit respond_to do |format| if @task.update_attributes(params[:task]) format.html { redirect_to @task, notice: ‘...’ } format.json { head :no_content } else form
rors, status: :unprocessable_entity } $ bundle exec rails generate migration add_priority_to_tasks priority:integer $ bundle exec rake db:migrate $ bundle exec rake d
ast def due_at_is_in_the_past errors.add(:due_at, ‘is in the past!’) if due_at < Time.zone.now #!/usr/bin/en python import pygame from random import randrange MA
e((640, 480)) clock = pygame.time.Clock() stars = for i in range(MAX_STARS): star = [randrange(0, 639), randrange(0, 479), randrange(1, 16)] stars.append(star) wh
e == pygame.QUIT: exit(0) #!/usr/bin/perl $numstars = 100; use Time::HiRes qw(usleep); use Curses; $screen = new Curses; noecho; curs_set(0); for ($i = 0; $i <
$star_s[$i] = rand(4) + 1; } while (1) { $screen->clear; for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] -= $star_s[$i]; if ($star_x[$i] < 0) { $star_x[$i] = 80; } $screen->add
em “therubyracer”, “~> 0.11.4” group :development, :test do gem “rspec-rails”, “~> 2.13.0” $ gem install bundler $ gem install rails --version=3.2.12 $ rbenv rehash $
s new todolist --skip-test-unit respond_to do |format| if @
nder json: @task.errors, status: :unprocessable_entity } $
:due_at_is_in_the_past def due_at_is_in_the_past errors.

Python | Contents
ygame.display.set_mode((640, 480)) clock = pygame.time.
e.event.get(): if event.type == pygame.QUIT: exit(0) #!/usr/
star_y[$i] = rand(24); $star_s[$i] = rand(4) + 1; } while (1) {
esh; usleep 50000; gem “therubyracer”, “~> 0.11.4” group
d_to do |format| if @task.update_attributes(params[:task])
ocessable_entity } $ bundle exec rails generate migration
_in_the_past errors.add(:due_at, ‘is in the past!’) if due_at
clock = pygame.time.Clock() stars = for i in range(MAX_

Python
game.QUIT: exit(0) #!/usr/bin/perl $numstars = 100; use
= rand(4) + 1; } while (1) { $screen->clear; for ($i = 0; $i <
rubyracer”, “~> 0.11.4” group :development, :test do gem
_attributes(params[:task]) format.html { redirect_to @task,
s generate migration add_priority_to_tasks priority:integer
he past!’) if due_at < Time.zone.now #!/usr/bin/en python
nge(MAX_STARS): star = [randrange(0, 639), randrange(0,
You’ve got the basics down, now
use Time::HiRes qw(usleep); use Curses; $screen = new advance your skills with Python
< $numstars ; $i++) { $star_x[$i] -= $star_s[$i]; if ($star_x[$i]
pec-rails”, “~> 2.13.0” $ gem install bundler $ gem install
ice: ‘...’ } format.json { head :no_content } else format.html Types of Python data ������������������������������������������� 78
bundle exec rake db:migrate $ bundle exec rake db:migrate
ort pygame from random import randrange MAX_STARS More Python data types ���������������������������� 80
79), randrange(1, 16)] stars.append(star) while True: clock.
ses; noecho; curs_set(0); for ($i = 0; $i < $numstars ; $i++)
Reliability by abstraction ���������������������������� 82
_x[$i] < 0) { $star_x[$i] = 80; } $screen->addch($star_y[$i],
m install rails --version=3.2.12 $ rbenv rehash $ rails new
Files and modules �������������������������������������������������������� 84
mat.html { render action: “edit” } format.json { render json: Neater code with modules ������������������� 86
db:migrate $ bundle exec rails server validate :due_at_is_
AX_STARS = 100 pygame.init() screen = pygame.display. Storage and persistence ��������������������������� 88
hile True: clock.tick(30) for event in pygame.event.get(): if
< $numstars ; $i++) { $star_x[$i] = rand(80); $star_y[$i] = Data organisation��������������������������������������������������������� 90
dch($star_y[$i], $star_x[$i], “.”); } $screen->refresh; usleep
$ rails new todolist --skip-test-unit respond_to do |format|
render json: @task.errors, status: :unprocessable_entity }
:due_at_is_in_the_past def due_at_is_in_the_past errors.
ygame.display.set_mode((640, 480)) clock = pygame.time.
e.event.get(): if event.type == pygame.QUIT: exit(0) #!/usr/
star_y[$i] = rand(24); $star_s[$i] = rand(4) + 1; } while (1) {
esh; usleep 50000; gem “therubyracer”, “~> 0.11.4” group
d_to do |format| if @task.update_attributes(params[:task])
ocessable_entity } $ bundle exec rails generate migration
_in_the_past errors.add(:due_at, ‘is in the past!’) if due_at
clock = pygame.time.Clock() stars = for i in range(MAX_
game.QUIT: exit(0) #!/usr/bin/perl $numstars = 100; use
= rand(4) + 1; } while (1) { $screen->clear; for ($i = 0; $i <
rubyracer”, “~> 0.11.4” group :development, :test do gem
_attributes(params[:task]) format.html { redirect_to @task,
s generate migration add_priority_to_tasks priority:integer
he past!’) if due_at < Time.zone.now #!/usr/bin/en python
nge(MAX_STARS): star = [randrange(0, 639), randrange(0,
use Time::HiRes qw(usleep); use Curses; $screen = new
< $numstars ; $i++) { $star_x[$i] -= $star_s[$i]; if ($star_x[$i]
pec-rails”, “~> 2.13.0” $ gem install bundler $ gem install
ice: ‘...’ } format.json { head :no_content } else format.html
bundle exec rake db:migrate $ bundle exec rake db:migrate
ort pygame from random import randrange MAX_STARS
79), randrange(1, 16)] stars.append(star) while True: clock.
ses; noecho; curs_set(0); for ($i = 0; $i < $numstars ; $i++)
_x[$i] < 0) { $star_x[$i] = 80; } $screen->addch($star_y[$i],
m install rails --version=3.2.12 $ rbenv rehash $ rails new
mat.html { render action: “edit” } format.json { render json:
db:migrate $ bundle exec rails server validate :due_at_is_
AX_STARS = 100 pygame.init() screen = pygame.display.
hile True: clock.tick(30) for event in pygame.event.get(): if
< $numstars ; $i++) { $star_x[$i] = rand(80); $star_y[$i] = Coding Made Simple | 77
dch($star_y[$i], $star_x[$i], “.”); } $screen->refresh; usleep
$ rails new todolist --skip-test-unit respond_to do |format|
Python | Data types

Different types of
Python data
Functions tell programs how to work, but it’s data that they operate
on. Let’s go through the basics of data in Python.

I
n this article, we’ll be covering the basic data types in string, in that they are a sequence. What makes them
Python and the concepts that accompany them. In later different is that the elements that make up a list can be of any
articles, we’ll look at a few more advanced topics that type. In this example, the elements are all strings, but you
build on what we do here: data abstraction, fancy structures could create another list that mixes different types, such as
such as trees, and more. [‘Bananas’, 10, ‘a’]. Lists are identified by the square brackets
that enclose them, and each item or element within them is
What is data? separated by a comma.
In the world, and in the programs that we’ll write, there’s an
amazing variety of different types of data. In a mortgage Working with data
calculator, for example, the value of the mortgage, the interest There are lots of things you can do with the different types of
rate and the term of the loan are all types of data; in a data in Python. For instance, you can add, subtract, divide and
shopping list program, there are all the different types of food multiply two numbers and Python will return the result:
and the list that stores them – each of which has its own kind >>> 23 + 42
of data. 65
The computer’s world is a lot more limited. It doesn’t know >>> 22 / 11
the difference between all these data types, but that doesn’t 2
stop it from working with them. The computer has a few basic If you combine different types of numbers, such as an int
ones it can work with, and that you have to use creatively to and a float, the value returned by Python will be of whatever
represent all the variety in the world. type retains the most detail – that is to say, if you add an int
We’ll begin by highlighting three data types: first, we have and a float, the returned value will be a float.
While we’re numbers. 10, 3 and 2580 are all examples of these. In You can test this by using the type() function. It returns
looking only at particular, these are ints, or integers. Python knows about the type of whatever argument you pass to it.
basic data types, other types of numbers, too, including longs (long integers), >>> type(8)
in real programs
floats (such as 10.35 or 0.8413) and complex (complex <type ‘int’>
getting the
numbers). There are also strings, such as ‘Hello World’, >>> type(23.01)
wrong type can
cause problems, ‘Banana’ and ‘Pizza’. These are identified as a sequence of <type ‘float’>
in which case characters enclosed within quotation marks. You can use >>> type(8 + 23.01)
you’ll see either double or single quotes. Finally, there are lists, such as <type ‘float’>
a TypeError. [‘Bananas’, ‘Oranges’, ‘Fish’]. In some ways, these are like a You can also use the same operations on strings and lists,
but they have different effects. The + operator concatenates,
that is combines together, two strings or two lists, while the *
operator repeats the contents of the string or list.
>>> “Hello “ + “World”
“Hello World”
>>> [“Apples”] * 2
[“Apples”, “Apples”]
Strings and lists also have their own special set of
operations, including slices. These enable you to select a
particular part of the sequence by its numerical index, which
begins from 0.
>>> word = “Hello”
>>> word[0]
‘H’
>>> word[3]
‘l’
>>> list = [‘banana’, ‘cake’, ‘tiffin’]
>>> list[2]
‘tiffin’
Indexes work in reverse, too. If you want to reference the last

78 | Coding Made Simple


Python | Data types
element of a list or the last character in a string, you can use
the same notation with a -1 as the index. -2 will reference the
second-to-last character, -3 the third, and so on. Note that
when working backwards, the indexes don’t start at 0.

Methods
Lists and strings also have a range of other special
operations, each unique to that particular type. These are
known as methods. They’re similar to functions such as
type() in that they perform a procedure. What makes them
different is that they’re associated with a particular piece of
data, and hence have a different syntax for execution.
For example, among the list type’s methods are append
and insert.
>>> list.append(‘chicken’)
>>> list
[‘banana’, ‘cake’, ‘tiffin’, ‘chicken’]
>>> list.insert(1, ‘pasta’)
>>> list
[‘banana’, ‘pasta’, ‘cake’, ‘tiffin’, ‘chicken’]
As you can see, a method is invoked by placing a period
between the piece of data that you’re applying the method to
and the name of the method. Then you pass any arguments identified by round brackets, as opposed to square brackets: The Python
between round brackets, just as you would with a normal (‘bananas’, ‘tiffin’, ‘cereal’). Dictionaries are similar to a list or interpreter is a
function. It works the same with strings and any other data a tuple in that they contain a collection of related items. They great place to
experiment with
object, too: differ in that the elements aren’t indexed by numbers, but by
Python code and
>>> word = “HELLO” ‘keys’ and are created with curly brackets: {}. It’s quite like an
see how different
>>> word.lower() English language dictionary. The key is the word that you’re data types work
‘hello’ looking up, and the value is the definition of the word. together.
There are lots of different methods that can be applied to With Python dictionaries, however, you can use any
lists and strings, and to tuples and dictionaries (which we’re immutable data type as the key (strings are immutable, too),
about to look at). To see the order of the arguments and the so long as it’s unique within that dictionary. If you try to use
full range of methods available, you’ll need to consult the an already existing key, its previous association is forgotten
Python documentation. completely and that data lost for ever.
>>> english = {‘free’: ‘as in beer’, ‘linux’: ‘operating system’}
Variables >>> english[‘free’]
In the previous examples, we used the idea of variables to ‘as in beer’
make it easier to work with our data. Variables are a way to >>> english[‘free’] = ‘as in liberty’
name different values – different pieces of data. They make it >>> english[‘free’]
easy to manage all the bits of data you’re working with, and ‘as in liberty’
greatly reduce the complexity of development (when you use
sensible names). Looping sequences
As we saw above, in Python you create a new variable with One common operation that you may want to perform on any
an assignment statement. First comes the name of the of the sequence types is looping over their contents to apply
variable, then a single equals sign, followed by the piece of an operation to every element contained within. Consider this
data that you want to assign to that variable. small Python program:
From that point on, whenever you use the name assigned list = [‘banana’, ‘tiffin’, ‘burrito’]
to the variable, you are referring to the data that you assigned for item in list:
to it. In the examples, we saw this in action when we print item
referenced the second character in a string or the third First, we created the list as we would normally, then we
element in a list by appending index notation to the variable used the for… in… construct to perform the print function
name. You can also see this in action if you apply the type() on each item in the list. The second word in that construct
function to a variable name: doesn’t have to be item, that’s just a variable name that
>>> type(word) gets assigned temporarily to each element contained within
<type ‘str’> the sequence specified at the end. We could just as well
>>> type(list) have written for letter in word and it would have worked
<type ‘list’> just as well.
That’s all we have time to cover in this article, but with the
Other data types basic data types covered, we’ll be ready to look at how you
There are two other common types of data that are used by can put this knowledge to use when modelling real-world
Python: tuples and dictionaries. problems in later articles.
Tuples are very similar to lists – they’re a sequence data In the meantime, read the Python documentation to
type, and they can contain elements of mixed types. The big become familiar with some of the other methods that it
difference is that tuples are immutable – that is to say, once provides for the data types we’ve looked at before. You’ll find
you create a tuple you cannot change it – and that tuples are lots of useful tools, such as sort and reverse! n

Coding Made Simple | 79


Python | Using Data

More Python
data types
Learn how different types of data come together to solve a real
problem as we write some code that counts words.

I
n the previous tutorial, we introduced Python’s most tm = open(‘timemachine.txt’, ‘r’)
common data types: numbers (ints and floats), strings, In this example, open() is passed two variables. The first is
lists, tuples and dictionaries. We demonstrated how they the name of the file to open; if it were in a different directory
work with different operators, and explained a few of their from the Python script, the entire path would have to be
most useful methods. We didn’t, however, give much insight given. The second argument specifies which mode the file
into how they might be used in real situations. In this article, should be opened in: r stands for read, but you can also use
we’re going to fix that. w for write or rw for read-write.
We’re going to write a program that counts the number of Notice we’ve also assigned the file to a variable, tm, so we
times each unique word occurs in a text file. Punctuation can refer to it later in the program.
marks will be excluded, and if the same word occurs but in With a reference to the file created, we also need a way to
different cases (for example, the and The), they will be taken access its contents. There are several ways to do this, but
to represent a single word. Finally, the program will print the today we’ll be using a for… in… loop. To see how this works,
results to the screen. It should look like this: try opening timemachine.txt in the interactive interpreter
the: 123 and then typing:
you: 10 >>> for line in tm:
a: 600 print line
... ...
As an example, we’ll be using The Time Machine, by HG The result should be every line of the file printed to the
Wells, which you can download from Project Gutenberg, screen. By putting this code in to a .py file, say cw.py, we’ve
saving it in the same folder as your Python file under the got the start of our Python program.
name timemachine.txt.
As the program description suggests, the first thing we’ll Cleaning up
need to do is make the text accessible from inside our Python The program description also specified that we should
program. This is done with the open() function: exclude punctuation marks, consider the same word but in
different cases as one word, and that we’re counting
individual words, not lines. As it stands, we have been able to
read only entire lines as strings, however, with punctuation,
strange whitespace characters (such as \r\n) and different
cases intact.
Looking at the Python string documentation (http://
docs.python.org/library), we can see that there are four
methods that can help us convert line strings into a format
closer to that specified by the description: strip(),
translate(), lower() and split().
Each of these are methods, and as such they’re functions
that are applied to particular strings using the dot notation.
For example, strip(), which removes specified characters
from the beginning and end of a string, is used like this:
>>> line.strip()
Hardly When passed with no arguments, it removes all
surprisingly, whitespace characters, which is one of the jobs we needed to
our counting get done.
program, after
The function translate() is a method that can be used for
being sorted,
removing a set of characters, such as all punctuation marks,
finds ‘the’ to
be the most from a string. To use it in this capacity, it needs to be passed
common word two arguments, the first being None and the second being
in The Time the list of characters to be deleted.
Machine, by >>> line.translate(None, ‘!”#$%&\’()*+,-./:;<=>?@[\\]^_`{|}~’)
HG Wells. lower() speaks for itself, really – it converts every character in

80 | Coding Made Simple


Python | Using Data
a string to lower-case. split() splits distinct elements inside a
string in to separate strings, returning them as a list.
By passing an argument to split(), it’s possible to specify
which character identifies the end of one element and the
start of another.
>>> line.split(‘ ‘)
In this example, we’ve passed a single space as the
character to split the string around. With all punctuation
removed, this will create a list, with each word in the string
stored as a separate element.
Put all of this in the Python file we started working on
earlier, inside the for loop, and we’ve made considerable
progress. It should now look like this:
tm = open(‘timemachine.txt’, ‘r’)
for line in tm:
line = line.strip() dict[word] = count Python’s
line = line.translate(None, ‘!”#$%&\’()*+,-./:;<=>?@ else: Standard Library
[\\]^_`{|}~’) dict[word] = 1 reference,
http://docs.
line = line.lower() This is a little bit confusing because dict[word] is being
python.org/
list = line.split(‘ ‘) used in two different ways. In the second line, it returns the
library, is an
Because all of the string methods return a new, modified value and assigns it to the variable count, while in the fourth invaluable source
string, rather than operating on the existing string, we’ve and seventh lines, count and 1 are assigned to that key’s for discovering
re-assigned the line variable in each line to store the work of value, respectively. what methods
the previous step. Notice, too, that if a word is already in the dictionary, we are available and
increment the count by 1, representing another occurrence. how to use them.
Uniqueness
Phew, look at all that work we’ve just done with data! By using Putting it together
the string methods, we’ve been able to remove all the bits of Another data type wrestled with, another step closer to our
data that we weren’t interested in. We’ve also split one large goal. At this point, all that’s left to do is insert some code to
string, representing a line, into smaller chunks by converting print the dictionary and put it all together and run the
it to a list, and in the process got to the exact, abstract program. The print section should look like this and be at the
concept we’re most interested in: words. very end of the file, outside of the line-looping code.
Our stunning progress aside, there is still some work to be for word,count in dict.iteritems():
done. We now need a way to identify which words are unique print word + “: “ + str(count)
– and not just in this line, but in every line contained within This for loop looks different to what you’ve seen before.
the entire file. By using the iteritems method of the dictionary, we can
The first thing that should pop into your head when access both the key (word) and value (count) in a single loop.
thinking about uniqueness is of a dictionary, the key-value What’s more, we’ve had to use the str() function to convert
store we saw in the previous article. It doesn’t allow duplicate count, an integer, into a string, as the + operator can’t
keys, so by entering each word as a key within a dictionary, concatenate an integer and a string.
we’re guaranteed there won’t be any duplicates. Try running it, and you should see your terminal screen
What’s more, we can use the value to store the number of filled with lines like:
times each word has occurred, incrementing it as the ...
program comes across new instances of each key. other: 20
Start by creating the dictionary, and ensuring that it sick: 2
persists for the entire file – not just a single line – by placing ventilating: 2
this line before the start of the for loop: ...
dict = {}
This creates an empty dictionary, which is ready to receive Data everywhere!
our words. That’s all we planned to achieve in this particular tutorial and
Next, we need to think about a way to get each word into it’s actually turn out to be quite a lot. As well as having had a
the dictionary. As we saw last time, ordinarily a simple chance to see how several different types of data and their
assignment statement would be enough to add a new word methods can be applied to solve a real problem, we hope
to the dictionary. We could then iterate over the list we you’ve noticed how important it is to select the appropriate
created above (using another for loop), adding each entry to type for representing different abstract concepts.
the dictionary with a value of 1 (to represent that it has For example, we started off with a single string
occurred once in the file). representing an entire line, and we eventually split this into
for word in list: a list of individual strings representing single words. This
dict[word] = 1 made sense until we wanted to consider unique instances, at
But remember, if the key already exists, the old value is which point we put everything into a dictionary.
overwritten and the count will be reset. To get around this, we As a further programming exercise, why not look into
can place an if-else clause inside the loop: sorting the resulting dictionary in order to see which words
if word in dict: occur most frequently? You might also want to consider
count = dict[word] writing the result to a file, one entry on a line, to save the fruits
count += 1 of your labour. n

Coding Made Simple | 81


Python | Abstraction

Reliability by
abstraction
Think your code is solid? Perhaps it’s a bit too lumpy. Creating
abstractions can make code much easier to maintain.

I
n the previous few tutorials, we have been looking at data. press this button once – much easier. This second approach
First, we introduced some of Python’s core data types, is what’s known as an abstraction. When working on
and then we demonstrated how they can be put to use problems, such as those involving Pythagoras’ theorem, we
when solving a real problem. The next data-related topic we don’t care about how to calculate the square root, only that
want to consider is abstraction, but before we get on to that, we can do it and get the correct result. We can treat the
we’re first going to look at abstraction in general and as it square root button on our calculator as a black box – we
applies to procedures. So, this time we’ll take a brief hiatus never look inside it, we don’t know how it does what it does,
from data, before returning to it in a later article. all that matters is that we know how to use it and that it gives
the correct result.
Square roots This a very powerful technique, which can make
To get our heads around the concept of abstraction, let’s start programming a lot easier, because it helps us to manage
by thinking about square roots and different techniques for complexity. To demonstrate how abstraction can help us,
finding them. One of these was discovered by Newton, and is consider the Python code below for finding the longest side of
thus known as Newton’s method. a right-angled triangle:
It says that when trying to find the square root of a import math
number (x), we should start with a guess (y) of its square def pythag(a, b):
root; we can then improve upon that result by averaging our a2b2 = (a * a) + (b * b)
guess (y) with the result of dividing the number (x) by our guess = 1.0
guess (y). As we repeat this procedure, we get closer and while (math.fabs((guess * guess) - a2b2) > 0.01):
closer to the square root. In most attempts, we’ll never reach guess = (((a2b2 / guess) + guess) / 2)
a definite result, we’ll only make our guess more and more return guess
accurate. Eventually, we’ll reach a level of accuracy that is The first thing to note is that it’s not in the least bit
good enough for our needs and then give up. Just to be clear readable. Sure, with a piece of code this short, you can read
about what is involved, take a look at the table below for how through it reasonably quickly and figure out what’s going on,
you would apply this method to find the square root of 2 (for but at a glance it’s not obvious, and if it were longer and
example, x). written like this, you’d have a terrible time figuring out what
It’s a lot of work just to on earth it was doing. What’s
find the square root of
a number. Imagine if when
“This is a very powerful more, it would be very
difficult to test the different
you were in school, every technique that makes parts of this code as you go

programming easier”
time you had to find a square along (aka incremental
root you had to do all these development, vital for
steps manually. Solving building robust software).
problems involving Pythagoras’ theorem, for instance, would For instance, how would you break out the code for testing
be much more unwieldy. whether or not a guess is close enough to the actual result
Luckily, assuming you were allowed to use calculators (and can you even identify it?), or the code for improving a
when you were at school, there’s another, much easier guess, to check that it works? What if this function didn’t
method to find square roots. Calculators come with a button return the expected results – how would you start testing all
marked with the square root symbol, and all you have to do is the parts to find where the error was?
Finally, there’s useful code in here that could be reused in
other functions, such as that for squaring a number, for
Find a square root taking an average of two numbers, and even for finding the
square root of a number, but none of it is reusable because of
the way it’s written. You could type it all out again, or copy and
Guess (y) Division (x/y) Average (((x/y) + y)/2) paste it, but the more typing you have to do, the more
1 2/1 = 2 (2 + 1)/2 = 1.5 obscure code you have to copy and paste, and the more likely
mistakes are to make it in to your programming.
1.5 2/1.5 = 1.33 (1.33 + 1.5)/2 = 1.4167
Let’s try writing that code again, this time coming up with
1.4167 2/1.4167 = 1.4118 (1.4118 + 1.4167)/2 = 1.4142 some abstractions to fix the problems listed above. We
haven’t listed the contents of each new function we’ve

82 | Coding Made Simple


Python | Abstraction
created, leaving them for you to fill in.
import math:
def square(x):
...
def closeEnough(x, guess):
...
def improveGuess(x, guess):
...
def sqrt(x, guess):
...
def pythag(a, b):
a2b2 = square(a) + square(b)
return sqrt(a2b2)
Here, we’ve split the code in to several smaller functions,
each of which fulfils a particular role. This has many benefits.
For starters, how much easier is the pythag() function to
read? In the first line, you can see clearly that a2b2 is the
result of squaring two numbers, and everything below that
has been consolidated in to a single function call, the purpose
of which is also obvious.
What’s more, because each part of the code has been split
into a different function, we can easily test it. For example,
testing whether improveGuess() was doing the right thing
would be very easy – come up with a few values for x and
guess, do the improvement by hand, and then compare your
results with those returned by the function.
If pythag() itself was found not to return the correct advantage of scope. closeEnough() and improveGuess() are Our final code
result, we could quickly test all these auxiliary functions to particular to the sqrt() function – that is to say, other for finding the
longest side of
narrow down where the bug was. functions are unlikely to rely on their services. To help keep
a triangle is
And, of course, we can easily reuse any of these new our code clean, and make the relationship between these
longer than
functions. If you were finding the square root of a number in functions and sqrt() clear, we can place their definitions what we had to
a different function, for instance, you could just call the sqrt() inside the definition of sqrt(): start, but it’s
function – six characters instead of four lines means there’s def sqrt(x, guess): more readable,
far less opportunity to make mistakes. def closeEnough(x, guess): more robust, and
One final point: because our sqrt code is now abstracted, ... generally better.
we could change the implementation completely, but so long def improveGuess(x, guess):
...
“This code can be ...
These functions are now visible only to code within the
improved by taking sqrt() definition – we say they’re in the scope of sqrt().

advantage of scope” Anything outside of it has no idea that they even exist. This
way, if we later need to define similar functions for improving
a guess in a different context, we won’t face the issue of
as we kept the function call and arguments the same, all code colliding names or the headache of figuring out what
that relies on it would continue to work properly. improveGuess1() and improveGuess2() do.
This means that if you come across a much more efficient
way of calculating square roots, you’re not stuck with working Layers of abstraction
through thousands of lines of code, manually changing every Hopefully, this example has demonstrated how powerful a
section that finds a square root; you do it once, and it’s done technique abstraction is. Bear in mind that there are many
everywhere. This code can be improved still further by taking layers of abstraction present in everything you do on a
computer that you never think of.
For instance, when you’re programming do you know how
Java Python represents integers in the computer’s memory? Or
how the CPU performs arithmetic operations such as
Abstraction

addition and subtraction?


C The answer is probably no. You just accept the fact that
typing 2 + 3 in to the Python interpreter returns the correct
Assembler result, and you never have to worry about how it does this.
You treat it as a black box.
Think how much longer it would take you to program if you
Object code had to manually take care of what data went in which
memory location, to work with binary numbers, and translate
There are layers of abstraction underneath everything alphabetic characters in to their numeric representations –
you do on a PC – you just don’t often think of them. thank goodness for abstraction! n

Coding Made Simple | 83


Python | Files

Files and modules


done quickly
It’s time to expand your library of functions and grab external data
with just two simple lines of Python.

F
or the majority of programming projects, you don’t get reversed alphabetical list of a folder’s contents. The
far before facing the age-old problem of how to get complexity of how data input and output can be
data into and out of your application. Whether it’s using accomplished is entirely down to your programming
punched cards to get patterns into a 19th century Jacquard environment. Every language will include functions to load
textile loom, or Google’s bots skimming websites for data to and save data, for instance, but this can either be difficult or
feed its search engine, dealing with external input is as easy depending on how many assumptions the language is
fundamental as programming itself. willing to make on your behalf. However, there’s always a
And it’s a problem and a concept that you may be more logical sequence of events that need to occur.
familiar with on the command line. When you type ls to list You will first need to open a file, creating one if it doesn’t
the contents of the current exist, and then either read
directory, for example, the
command is reading in the
“If the filesystem knows data from this file, or write
data to it, before explicitly
contents of a file, the current
directory, and then
the file is being changed, closing the file again so that
other processes can use it.
outputting the contents to it won’t allow access” Most languages
another, the terminal. require you to specify a
When you Of course, the inputs and outputs aren’t files in the sense read mode when you open a file, because this tells the
read a file, most most people would recognise, but that’s the way the Linux filesystem whether to expect file modifications or not. This
languages will filesystem has been designed – nearly everything is a file. This is important because many different processes may also
step through its helps when you want to save the output of a command, or want to access the file, and if the filesystem knows the file
data from the
use that output as the input to another. is being changed, it won’t usually allow access. However,
beginning to the
You may already know that typing ls >list.txt will redirect many processes can access a read-only file without worrying
end in chunks
you specify. In the output from the command to a file called list.txt, but you about the integrity of the data it holds, because nothing is
this example, can take this much further because the output can be treated able to change it. If you know about databases, it’s the same
we’re reading a exactly like a file. ls | sort -r will pipe (that’s the vertical bar kind of problem you face with multiple users accessing the
line at a time. character) the output of ls into the input of sort to create a same table.
In Python, as with most other languages, opening a file to
write or as read-only can be done with a single line:
>>> f = open(“list.txt”, “r”)
If the file doesn’t exist, Python will generate a “No such file
or directory” error. To avoid this, we’ve used the output from
our command line example to create a text file called list.txt.
This is within the folder from where we launched the
Python interpreter.

Environment variables
Dealing with paths, folders and file locations can quickly
become complicated, and it’s one of the more tedious issues
you’ll face with your own projects. You’ll find that different
environments have different solutions for finding files, with
some creating keywords for common locations and others
leaving it to the programmer.
This isn’t so bad when you only deal with files created by
your projects, but it becomes difficult when you need to know
where to store a configuration file or load a default icon.
These locations may be different depending on your Linux
distribution or desktop, but with a cross-platform language
such as Python, they’ll also be different for each operating
system. For that reason, you might want to consider using

84 | Coding Made Simple


Python | Files
environment variables. These are similar to variables with a
global scope in many programming languages, but they apply
to any one user’s Linux session rather than within your own
code. If you type env on the command line, for instance, you’ll
see a list of the environmental variables currently set for your
terminal session. Look closely, and you’ll see a few that apply
to default locations and, most importantly, one called HOME.
The value assigned to this environmental variable will be the
location of your home folder on your Linux system, and if we
want to use this within our Python script, we first need to add
a line to import the operating system-specific module. The
line to do this is:
import os
This command is also opening a file, but not in the same
way we opened list.txt. This file is known as a module in
Python terms, and modules like this ‘import’ functionality,
including statements and definitions, so that a programmer
doesn’t have to keep re-inventing the wheel.
Modules extend the simple constructs of a language to
add portable shortcuts and solutions, which is why other
languages might call them libraries. Libraries and modules
are a little like copying and pasting someone’s own research
and insight into your own project. Only it’s better than that, code to your project: Binary files
because modules such as os are used by everyone, turning f = open(os.environ[“HOME”]+”/list.txt”,”r”) have no context
the way they do things into a standard. This line will open the file list.txt in your home folder. without an
associated file
Python knows which home folder is yours, because the
Setting the standard os.environ function from the os module returns a string from
type and a way of
handling them.
There are even libraries called std, and these embed standard an environmental variable, and the one we have asked it to Which is why you
ways of doing many things a language doesn’t provide by return is HOME. But all we’ve done is open the file, we’ve not get the raw data
default, such as common mathematical functions, data types yet read any of its contents. This might seem counter- output when you
and string services, as well as file input/output and support intuitive, but it’s an historical throwback to the way that files read one.
for specific file types. You will find the documentation for what used to be stored, which is why this is also the way nearly all
a library does within an API. This will list each function, what it languages work. It’s only after a file has been opened that you
does, and what it requires as an input and an output. You can start to read its contents:
should also be able to find the source files used by the import f.readline()
(and by #include in other languages). On most Linux The above instruction will read a single line of the text file
systems, for example, /lib/python2.x will include all the and output this to the interpreter as a string. Repeating the
modules. If you load os.py into a text editor, you’ll see the command will read the next line, because Python is
code you’ve just added to your project, as well as which remembering how far through the file it has read. Internally,
functions are now accessible to you. this is being done using something called a pointer and this,
There are many, many different modules for Python – it’s too, is common to the vast majority of languages.
one of the best reasons to choose it over any other language, Alternatively, if you wanted to read the entire file, you could
and more can usually be installed with just a couple of clicks use f.read(). Because our file contains only text, copying the
from your package manager. contents to a Python string
But this is where the ugly
spectre of dependencies can
“If you load os.py into a is an easy conversion. The
same isn’t true of a binary
start to have an effect on your
project, because if you want
text editor, you’ll see the file. Rather than being
treated as text, the
to give your code to someone code you’ve just added” organisation of the bits and
else, you need to make sure bytes that make up a
that person has also got the same modules installed. binary file are organised according to the file type used by the
If you were programming in C or C++, for example, where file – or no file type at all if it’s raw data. As a result, Python (or
your code is compiled and linked against binary libraries, any other programming language) would be unable to extract
those binary libraries will also need to be present on any other any context from a binary file, causing an error if you try to
system that runs your code. They will become dependencies read it into a string. The solution, at least for the initial input, is
for your project, which is what package managers do when to add a b flag when you first open the file, because this
you install a complex package. warns Python to expect raw binary. When you then try to read
the input, you’ll see the hexadecimal values of the file output
The os module to the display.
Getting back to our project, the os module is designed to To make this data useful, you’ll need to do some extra
provide a portable way of accessing operating system- work, which we’ll look at next; but first, make sure you close
dependent functionality so that you can write multi-platform the open file, as this should ensure the integrity of your
applications without worrying about where files should be filesystem. As you might guess, the command looks like this:
placed. This includes knowing where your home directory f.close
might be. To see what we mean, add the following piece of And it’s as easy as that! n

Coding Made Simple | 85


Python | Modules

Neater code
with modules
Untangle the horrible mess of code that you’ve made and add
coherent structure to your programs.

I
n previous tutorials, we have mentioned how automatically parsed command line options. We could access
programming is all about managing complexity, and we’ve them by typing the module’s name, followed by the name of
introduced you to quite a few of the tools and techniques the function we wanted to execute:
that help programmers do this. From variables to function optparse.OptionParser()
definitions or object-orientation, they all help. One tool we’ve This was great from a readability perspective. In our cat
yet to cover, in part because you don’t start to come across it clone, we didn’t have to wade through lots of code about
until you’re writing larger programs, is the idea of modules parsing command line arguments; instead we could focus on
and name spaces. the code that dealt with the logic of echoing file contents to
Yet, if you’ve written a program of any length, even just a the screen and to the standard output pipe. What’s more, we
few hundred lines, this is a tool you’re no doubt desperate for. didn’t have to worry about using names in our own program
In a long file of code, you’ll have noticed how quickly it that might collide with those in the optparse module,
becomes more difficult to read. Functions seem to blur into because they were all hidden inside the optparse
one another, and when you’re trying to hunt down the cause namespace, and reusing this code was as easy as typing
of the latest error, you find it difficult to remember exactly import optparse – no messy copy and pasting here.
where you defined that all-important variable.
These problems are caused by a lack of structure. With all How modules work
your code in a single file, it’s more difficult to determine the Modules sound fancy, and you might think they’re
dependencies between elements of your program – that is, complicated, but – in Python at least – they’re really just plain
which parts rely old files. You can try it out for yourself. Create a new directory
on each other to and inside it create a fact.py file. Inside it, define a function to
“As your programs grow get work done – return the factorial of a given number:

in length, there are other and it’s more


difficult to
def factorial(n):
result = 1

problems that occur” visualise the flow


of data through


while n > 0:
if n == 1:
your program. result *= 1
As your programs grow in length, too, there are other else:
problems that begin to occur: for instance, you may find result *= n
yourself with naming conflicts, as two different parts of your n -= 1
program require functions called add (for example, adding return n
integers or adding fractions in a mathematics program), or Create a second Python file called doMath.py. Inside this,
you may have written a useful function that you want to share first import the module you just created and then execute the
with other programs that you’re writing, and the only tool you factorial function, printing the result to the screen:
have to do that is boring and error-prone copy and pasting. import fact
print fact.factorial(5)
Untangling the mess Now, when you run the doMath.py file, you should see
Modules are a great way to solve all of these problems, 120 printed on the screen. You should notice that the name of
enabling you to put structure back into your code, letting you the module is just the name of the file, in the same directory,
avoid naming conflicts, and making it easier for you to share with the extension removed. We can then call any function
useful chunks of code between programs. defined in that module by typing the module’s name, followed
You’ve no doubt been using them all the time in your code by a dot, followed by the function name.
as you’ve relied on Python built-in or third-party modules to
provide lots of extra functionality. As an example, remember The Python path
the optparse module we used before. The big question that’s left is, how does Python know where
We included it in our program along with the import to look to find your modules?
statement, like so: The answer is that Python has a pre-defined set of
import optparse locations that it looks in to find files that match the name
After putting this line at the top of our Python program, we specified in your import statements. It first looks inside all of
magically got access to a whole load of other functions that the built-in modules, the location of which are defined when

86 | Coding Made Simple


Python | Modules
By splitting
your code up
in to smaller
chunks, each
placed in its
own file and
directory, you
can bring order
to your projects
and make future
maintenance
easier.

you install Python; it then searches through a list of print food


directories known as the path. def show_choc():
This path is much like the Bash shell’s $PATH food = [“snickers”, “kitkat”, “dairy milk”]
environment variable – it uses the same syntax, and serves print food
exactly the same function. It varies, however, in how show_choc()
the contents of the Python path are generated. Initially, print food
the locations stored in the path consist of the following If you run that, you’ll see that outside the function the
two locations: variable food refers to a list of fruit, while inside the function,
The directory containing the script doing the importing. it refers to a list of chocolate bars. This demonstrates two
The PYTHONPATH, which is a set of directories pre- different scopes: the global scope of the current module, in
defined in your default installation. which food refers to a list of fruit, and the local scope of the
You can inspect the path in your Python environment by function, in which food refers to a list of chocolate.
importing the sys module, and then inspecting the path When looking up a variable, Python starts with the
attribute (typing sys.path will do the trick). innermost variable and works its way out, starting with the
Once a program has started, it can even modify the path immediately enclosing function, and then any functions
itself and add other locations to it. enclosing that, and then the module’s global scope, and then
finally it will look at all the built-in names.
Variable scope in modules In simple, single-file programs, it is a bad idea to put
Before you head off and start merrily writing your own variables in the global scope. It can cause confusion and
modules, there is one more thing that you need to know subtle errors elsewhere in your program. Using modules can
about: variable scope. help with this problem, because each module has its own
We have touched upon scope as a concept before, but as global scope. As we saw above, when we import a module, its
a quick refresher, scope refers to the part of a program from contents are all stored as attributes of the module’s name,
which particular variables can be accessed. For instance, a accessed via dot notation. This makes global variables
single Python module might contain the following code: somewhat less troublesome, although you should still be
food = [“apples”, “oranges”, “pears”] careful when using them. n

Python style
While many people think of Python as common problems, and the best ways to which you can start learning:
a modern language, it’s actually been format your code to make sure it’s http://python.net/~goodger/
around since the early 1990s. As with any readable for co-workers and anyone else projects/pycon/2007/idiomatic/
programming language that’s been working on the code with you (including handout.html
around for any length of time, people who your future self). www.python.org/dev/peps/
use it often have learned a lot about the If you’re interested in finding out more pep-0008
best ways to do things in the language – about these best practices in Python, Read these and you’re sure to gain
in terms of the easiest way to solve there are two very useful resources from some deeper insight into the language.

Coding Made Simple | 87


Python | Persistence

Embrace storage
and persistence
Deal with persistent data and store your files in Python to make your
programs more permanent and less transient.

S
torage is cheap: you can buy a 1TB external hard Easy! Notice how we used the format string function to
drive for around £50 these days, while even add a new line to the end of each string, otherwise we would
smartphones come with at least 8GB of storage, and end up with everything on one line – which would have made
many are easily expandable up to 64GB or more for only the it harder to use later.
price of a pair of jeans. Re-using the contents of this file would be just as simple.
It’s no surprise, then, that almost every modern Using the file as an iterator, load each line in turn into a list,
application stores data in one way or another, whether that’s stripping off the trailing new line character. We’ll leave you to
configuration data, cached data to speed up future use, saved figure this one out.
games, to-do lists or photos. The list goes on and on. When using files in your Python code, there are two things
With this in mind, this programming tutorial is going to that you need to keep in mind. The first is that you need to
demonstrate how to deal with persistent data in our language convert whatever you want to write to the file to a string first.
of choice – Python. This is easy, though, because you can just use the built-in
The most obvious form of persistent storage that you can str() function – for example, str(42) => “42”.
take advantage of in Python is file storage. Support for it is The second is that you have to close the file after you have
included in the standard library, and you don’t even have to finished using it – if you don’t do this, you risk losing data that
import any modules to take advantage of it. you thought had been committed to disk, but that had not yet
To open a file in the current working directory (that is, been flushed. You can do this manually with the close method
wherever you ran the Python script from, or wherever you of file objects. In our example, this would translate to adding
were when you launched the interactive shell), use the open() file.close() to our program. It’s better, however, to use the
function: with keyword:

“Almost every modern file = open(“lxf-


test.txt”, “w”)
with open(“lxf-test.txt”, “a”) as file:
feeds = [line.rstrip(“\n”) for line in f]
application stores data The first
argument to open
This simple piece of Python code handles opening the file
object and, when the block inside the with statement is
in one way or another” is the filename, finished, automatically closes it for us, as well. If you are
while the second unsure what the second line does, try looking up Python list
specifies which mode the file should be opened in – in this comprehensions – they’re a great way to write efficient,
case, it’s write, but other valid options include read-only (r) concise code, and to bring a modicum of functional style into
and append (a). your work.
In previous tutorials, we’ve shown you that this file object
is in fact an iterator, which means you can use the in keyword Serialising
to loop through each line in the file and deal with its contents, Working with files would be much easier if you didn’t have to
one line at a time. Before reviewing that information, however, worry about converting your list (or dictionary, for that
let’s look at how to write data to a file. matter) into a string first of all – for dictionaries in particular,
this could get messy. Fortunately, Python provides two tools
Writing to files to make this easier for us.
Suppose you’re writing your own RSS application to deal with The first of these tools is the pickle module. Pickle
your favourite feeds. You’ve already got some way to ask accepts many different kinds of Python objects, and can then
users to enter in a list of feeds (perhaps using raw_input(), or convert them to a character string and back again. You still
perhaps using a web form and CGI), but now you want to have to do the file opening and closing, but you no longer
store that list of feeds on disk so you can re-use it later when have to worry about figuring out an appropriate string
you’re checking for new updates. At the moment, the feeds representation for your data:
are just stored in a Python list: import pickle
feeds = [“http://newsrss.bbc.co.uk/rss/newsonline_uk_ ...
edition/front_page/rss.xml”, “http://www.tuxradar.com/rss”] with open(“lxf-test.txt”, “a”) as file:
To get the feeds into the file is a simple process. Just use pickle.dump(feeds, file)
the write method: …
for feed in feeds: with open(“lxf-test.txt”, “r”) as file:
file.write(“{0}\n”.format(feed)) feeds = pickle.load(file)

88 | Coding Made Simple


Python | Persistence
If you’re interested in persistent data in Python, a good next stopping point is the ZODB object database. It’s much
easier and more natural in Python than a relational database engine (www.zodb.org).

This is much easier, and it has other applications outside to keep track of how many unread items each feed had, and
of persisting data in files, too. For example, if you wanted to which item was the last to be read. You might do this with a
transfer your feed list across the network, you would first dictionary, for example:
have to make it into a character string, too, which you could tracker = { “bbc.co.uk”: { “last-read”: “foo”,
do with pickle. “num-unread”: 10, },
The problem with this is that it will only work in Python – “tuxradar.co.uk”: { “last-read”: “bar”,
that is to say, other programming languages don’t support “num-unread”: 5, }}
the pickle data format. If you like the concept of pickling
(more generically, serialising), there’s another option that You could then store the list of feeds and the tracking
does have support in other languages, too: JSON. details for each in a single file by using the shelve module,
You may have heard of JSON – it stands for JavaScript like so:
Object Notation, and is a way of converting objects into import shelve
human-readable string representations, which look almost shelf = shelve.open(“lxf-test”)
identical to objects found in the JavaScript programming shelf[“feeds”] = feeds
language. It’s great, because it’s human readable, and also shelf[“tracker”] = tracker
because it’s widely supported in many different languages, shelf.close()
largely because it has become so popular with fancy web There are a few important things that you should be aware
2.0 applications. of about the shelve module:
In Python, you use it in exactly the same way as pickle – in The shelve module has its own operations for opening and
the above example, replace pickle with json throughout, and closing files, so you can’t use the standard open function.
you’ll be writing interoperable, serialised code! To save some data to the shelf, you must first use a
standard Python assignment operation to set the value of a
Shelves particular key to the object you want to save.
Of course, some code bases have many different objects that As with files, you must close the shelf object once finished
you want to store persistently between runs, and keeping with, otherwise your changes may not be stored.
track of many different pickled files can get tricky. There’s Accessing data inside the shelf is just as easy. Rather than
another Python standard module, however, that uses pickle assigning a key in the shelf dictionary to a value, you assign a
underneath, but makes access to the stored objects more value to that stored in the dictionary at a particular key: feeds
intuitive and convenient: the shelve module. = shelf[“feeds”]. If you want to modify the data that was
Essentially, a shelf is a persistent dictionary – that is to stored in the shelf, modify it in the temporary value you
say, a persistent way to store key-value pairs. The great thing assigned it to, then re-assign that temporary value back to
about shelves, however, is that the value can be any Python the shelf before closing it again.
object that pickle can serialise. Let’s take a look at how you That’s about all we have space for this tutorial, but keep
can use it. Thinking back to our RSS reader application, reading, because we’ll discuss one final option for persistent
imagine that as well as the list of feeds to check, you wanted data: relational databases (for example, MySQL). n

Coding Made Simple | 89


Python | Databases

Data organisation
and queries
Let’s use SQL and a relational database to add some structure to
our extensive 70s rock collection. You do have one, right?

I
n the last tutorial, we looked at how to make data
persistent in your Python programs. The techniques we Relational database
looked at were flat-file based, and as useful as they are,
they’re not exactly industrial scale. As your applications grow Album name Free At Last
more ambitious, as performance becomes more important, Running time 65:58
or as you try to express more complicated ideas and Year 1972
relationships, you’ll need to look towards other technologies,
Artist_id 1
such as an object database or, even, a relational database.
As relational databases are by far the most common tool
for asking complex questions about data today, in this coding and good, but very wasteful. For every track on the same
tutorial we’re going to introduce you to the basics of relational album, we have to duplicate all the information, such as the
databases and the language used to work with them (which is album name, its running time, the year it was published, and
called SQL, or Structured Query Language). With the basics all the information about the artist, too, such as their name
mastered, you’ll be able to start integrating relational and the year they split. As well as being wasteful with storage
databases into space, this also makes the data slower to search, harder to

“Relational databases
your code. interpret and more dangerous to modify later.
To follow Relational databases solve these problems by letting us

are used to ask complex along, make sure


you have got
split the data and store it in a more efficient, useful form. They
let us identify separate entities within the database that
questions about data” MySQL or one
of its drop-in
would benefit from being stored in independent tables.
In our example, we might split information about the
replacements installed, and can also find a way to get access album, artist and track into separate tables. We would then
to the MySQL console: only need to have a single entry for the artist Free (storing the
mysql -uroot name and the year the band split), a single entry for the
If you’ve set a password, use the -p switch to give that as album Free At Last (storing its name, the year it was
well as the username. Throughout, we’ll be working on a small published and the running time), and a single entry for each
database to track our music collection. track in the database (storing everything else) in each of their
respective tables.
Relationships All that duplication is gone, but now all the data has been
Let’s start by thinking about the information we want to store separated, what happens when you want to report all the
in our music collection. A logical place to start might be information about a single track, including the artist who
thinking about it in terms of the CDs that we own. Each CD is produced it and the album it appeared on? That’s where the
a single album, and each album can be described by lots of ‘relational’ part of a relational database comes in.
other information, or attributes, including the artist who Every row within a database table must in some way be
created the album and the tracks that are on it. unique, either based on a single unique column (for example,
We could represent all this data in one large, a unique name for an artist, or a unique title for an album), or
homogeneous table – like the one below – which is all well a combination of columns (for example, the album title and
year published). These unique columns form what is known

Duplicated data as a primary key. Where a natural primary key (a natural set
of unique columns) doesn’t exist within a table, you can easily
add an artificial one in the form of an automatically
Album Free At Last Free At Last incrementing integer ID.
Artist Free Free We can then add an extra column to each table that
Track Little Bit of Love Travellin’ Man references the primary key in another table. For example,
Track time 2:34 3:23 consider the table above. Here, rather than giving all the
Album time 65:58 65:58 information about the artist in the same table, we’ve simply
Year 1972 1972 specified the unique ID for a row in another table, probably
Band split 1973 1973 called Artist. When we want to present this album to a user, in
conjunction with information about the artist who published

90 | Coding Made Simple


Python | Databases
it, we can get the information first from this Album table, then
retrieve the information about the artist, whose ID is 1, from
the Artist table, combining it for presentation.

SQL
That, in a nutshell, is what relational databases are all about.
Splitting information into manageable, reusable chunks of
data, and describing the relationships between those chunks.
To create these tables within the database, to manage the
relationships, to insert and query data, most relational
databases make use of SQL, and now that you know what a
table and a relationship is, we can show you how to use SQL
to create and use your own.
After logging into the MySQL console, the first thing we
need to do is create a database. The database is the top-level
storage container for bits of related information, so we need
to create it before we can start storing or querying anything
else. To do this, you use create database:
create database lxfmusic; MariaDB is a drop-in replacement for the MySQL database, and is quickly
Notice the semi-colon at the end of the command – all finding favour among distros including Mageia, OpenSUSE and even Slackware.
SQL statements must end with a semi-colon. Also notice that
we’ve used lower-case letters: SQL is not case-sensitive, and incremented for every row in the database, thus forming a
you can issue your commands in whatever case you like. primary key. You can find out more about the create table
With the database created, you now need to switch to it. statement in the MySQL documentation at http://dev.
Much as you work within a current working directory on the mysql.com/doc/refman/5.5/en/create-table.html.
Linux console, in MySQL, many commands you issue are
relative to the currently selected database. You can switch Inserts and queries
databases with the use command: Inserting data into the newly created tables isn’t any trickier:
use lxfmusic; insert into Album (name) values (“Free at Last”);
Now to create some tables: Once again, we specify the action and the object on which
create table Album ( we’re acting, we then specify the columns which we’re
Album_id int auto_increment primary key, inserting into, and finally the values of the data to be put in.
name varchar(100) Before we can insert an entry into the Track table,
); however, we must discover what the ID of the album Free At
Last is, otherwise we won’t be able to link the tables together
create table Track ( very easily. To do this, we use the select statement:
Track_id int auto_increment primary key, select * from Album where name = “Free At Last”;
title varchar(100), This command says we want to select all columns from
running_time int, the Album table whose name field is equal to Free At Last.
Album_id int Pretty self-explanatory really! If we’d only wanted to get the ID
); field, we could have replaced the asterisk with Album_id and
The most obvious things to note here are that we have it would have taken just that column.
issued two commands, separated by semi-colons, and that Since that returned a 1 for us (it being the first entry in the
we have split each command over multiple lines. SQL doesn’t database), we can insert into the Track table as follows:
care about white space, so you can split your code up insert into Track (title, running_time, Album_id) values
however you like, as long as you put the right punctuation in (‘Little Bit of Love’, 154, 1);
the correct places. The big thing to note is that we specified the running time
As for the command itself, notice how similar it is to the in seconds and stored it as an integer. With most databases,
create database statement. We specify the action we want you must always specify a data type for your columns, and
to take, the type of object that we’re operating on and then sometimes this means that you need to represent your data
the properties of that object. With the create database in a different manner than in your application, and you will
statement, the only property was the name of the database; need to write some code to convert it for display. That said,
with the create table statement, we’ve also got a whole load MySQL does have a wide range of data types, so many
of extra properties that come inside the parentheses and are eventualities are covered.
separated by commas. That’s all we have space for here, but don’t let your MySQL
These are known as column definitions, and each comma- education stop there. Now you’ve seen the basics, you’ll want
separated entry describes one column in the database. First, to investigate foreign keys and joins, two more advanced
we give the column a name, then we describe the type of data techniques that will enable you to be far more expressive with
stored in it (this is necessary in most databases), then we your SQL. You’ll also want to investigate the different types of
specify any additional properties of that column, such as relationship, such as one-to-one, one-to-many, many-to-one
whether it is part of the primary key. and many-to-many.
The auto_increment keyword means you don’t have to Finally, if you want to integrate MySQL with your
worry about specifying the value of Track_id when inserting programming language of choice, look out for an appropriate
data, as MySQL will ensure that this is an integer that gets module, such as the python-mysql module for Python. n

Coding Made Simple | 91


rubyracer”, “~> 0.11.4” group :development, :test do gem “rspec-rails”, “~> 2.13.0” $ gem install bundler $ gem install rails --version=3.2.12 $ rbenv rehash $ rails
ate_attributes(params[:task]) format.html { redirect_to @task, notice: ‘...’ } format.json { head :no_content } else format.html { render action: “edit” } format.json { ren
xec rails generate migration add_priority_to_tasks priority:integer $ bundle exec rake db:migrate $ bundle exec rake db:migrate $ bundle exec rails server validate
_at, ‘is in the past!’) if due_at < Time.zone.now #!/usr/bin/en python import pygame from random import randrange MAX_STARS = 100 pygame.init() screen = py
tars = for i in range(MAX_STARS): star = [randrange(0, 639), randrange(0, 479), randrange(1, 16)] stars.append(star) while True: clock.tick(30) for event in pygame.
$numstars = 100; use Time::HiRes qw(usleep); use Curses; $screen = new Curses; noecho; curs_set(0); for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] = rand(80); $s
>clear; for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] -= $star_s[$i]; if ($star_x[$i] < 0) { $star_x[$i] = 80; } $screen->addch($star_y[$i], $star_x[$i], “.”); } $screen->refre
ment, :test do gem “rspec-rails”, “~> 2.13.0” $ gem install bundler $ gem install rails --version=3.2.12 $ rbenv rehash $ rails new todolist --skip-test-unit respond
ml { redirect_to @task, notice: ‘...’ } format.json { head :no_content } else format.html { render action: “edit” } format.json { render json: @task.errors, status: :unpro
rity_to_tasks priority:integer $ bundle exec rake db:migrate $ bundle exec rake db:migrate $ bundle exec rails server validate :due_at_is_in_the_past def due_at_is_
one.now #!/usr/bin/en python import pygame from random import randrange MAX_STARS = 100 pygame.init() screen = pygame.display.set_mode((640, 480)) c
star = [randrange(0, 639), randrange(0, 479), randrange(1, 16)] stars.append(star) while True: clock.tick(30) for event in pygame.event.get(): if event.type == pyg
Res qw(usleep); use Curses; $screen = new Curses; noecho; curs_set(0); for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] = rand(80); $star_y[$i] = rand(24); $star_s[$i]
rs ; $i++) { $star_x[$i] -= $star_s[$i]; if ($star_x[$i] < 0) { $star_x[$i] = 80; } $screen->addch($star_y[$i], $star_x[$i], “.”); } $screen->refresh; usleep 50000; gem “theru
ils”, “~> 2.13.0” $ gem install bundler $ gem install rails --version=3.2.12 $ rbenv rehash $ rails new todolist --skip-test-unit respond_to do |format| if @task.update_
.’ } format.json { head :no_content } else format.html { render action: “edit” } format.json { render json: @task.errors, status: :unprocessable_entity } $ bundle exec rails
exec rake db:migrate $ bundle exec rake db:migrate $ bundle exec rails server validate :due_at_is_in_the_past def due_at_is_in_the_past errors.add(:due_at, ‘is in th
ygame from random import randrange MAX_STARS = 100 pygame.init() screen = pygame.display.set_mode((640, 480)) clock = pygame.time.Clock() stars = for i in ran
drange(1, 16)] stars.append(star) while True: clock.tick(30) for event in pygame.event.get(): if event.type == pygame.QUIT: exit(0) #!/usr/bin/perl $numstars = 100;
oecho; curs_set(0); for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] = rand(80); $star_y[$i] = rand(24); $star_s[$i] = rand(4) + 1; } while (1) { $screen->clear; for ($i = 0; $i <
ar_x[$i] = 80; } $screen->addch($star_y[$i], $star_x[$i], “.”); } $screen->refresh; usleep 50000; gem “therubyracer”, “~> 0.11.4” group :development, :test do gem “rsp
sion=3.2.12 $ rbenv rehash $ rails new todolist --skip-test-unit respond_to do |format| if @task.update_attributes(params[:task]) format.html { redirect_to @task, noti

CODING
ction: “edit” } format.json { render json: @task.errors, status: :unprocessable_entity } $ bundle exec rails generate migration add_priority_to_tasks priority:integer $ b
exec rails server validate :due_at_is_in_the_past def due_at_is_in_the_past errors.add(:due_at, ‘is in the past!’) if due_at < Time.zone.now #!/usr/bin/en python impo
game.init() screen = pygame.display.set_mode((640, 480)) clock = pygame.time.Clock() stars = for i in range(MAX_STARS): star = [randrange(0, 639), randrange(0, 47
or event in pygame.event.get(): if event.type == pygame.QUIT: exit(0) #!/usr/bin/perl $numstars = 100; use Time::HiRes qw(usleep); use Curses; $screen = new Curs
$i] = rand(80); $star_y[$i] = rand(24); $star_s[$i] = rand(4) + 1; } while (1) { $screen->clear; for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] -= $star_s[$i]; if ($star_
i], “.”); } $screen->refresh; usleep 50000; gem “therubyracer”, “~> 0.11.4” group :development, :test do gem “rspec-rails”, “~> 2.13.0” $ gem install bundler $ gem
-skip-test-unit respond_to do |format| if @task.update_attributes(params[:task]) format.html { redirect_to @task, notice: ‘...’ } format.json { head :no_content } else form

MADE
rors, status: :unprocessable_entity } $ bundle exec rails generate migration add_priority_to_tasks priority:integer $ bundle exec rake db:migrate $ bundle exec rake d
ast def due_at_is_in_the_past errors.add(:due_at, ‘is in the past!’) if due_at < Time.zone.now #!/usr/bin/en python import pygame from random import randrange MA
e((640, 480)) clock = pygame.time.Clock() stars = for i in range(MAX_STARS): star = [randrange(0, 639), randrange(0, 479), randrange(1, 16)] stars.append(star) wh
e == pygame.QUIT: exit(0) #!/usr/bin/perl $numstars = 100; use Time::HiRes qw(usleep); use Curses; $screen = new Curses; noecho; curs_set(0); for ($i = 0; $i <
$star_s[$i] = rand(4) + 1; } while (1) { $screen->clear; for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] -= $star_s[$i]; if ($star_x[$i] < 0) { $star_x[$i] = 80; } $screen->add
em “therubyracer”, “~> 0.11.4” group :development, :test do gem “rspec-rails”, “~> 2.13.0” $ gem install bundler $ gem install rails --version=3.2.12 $ rbenv rehash $

SIMPLE
update_attributes(params[:task]) format.html { redirect_to @task, notice: ‘...’ } format.json { head :no_content } else format.html { render action: “edit” } format.json {
exec rails generate migration add_priority_to_tasks priority:integer $ bundle exec rake db:migrate $ bundle exec rake db:migrate $ bundle exec rails server validate
_at, ‘is in the past!’) if due_at < Time.zone.now #!/usr/bin/en python import pygame from random import randrange MAX_STARS = 100 pygame.init() screen = py
tars = for i in range(MAX_STARS): star = [randrange(0, 639), randrange(0, 479), randrange(1, 16)] stars.append(star) while True: clock.tick(30) for event in pygame.
$numstars = 100; use Time::HiRes qw(usleep); use Curses; $screen = new Curses; noecho; curs_set(0); for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] = rand(80); $s
>clear; for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] -= $star_s[$i]; if ($star_x[$i] < 0) { $star_x[$i] = 80; } $screen->addch($star_y[$i], $star_x[$i], “.”); } $screen->refre
ment, :test do gem “rspec-rails”, “~> 2.13.0” $ gem install bundler $ gem install rails --version=3.2.12 $ rbenv rehash $ rails new todolist --skip-test-unit respond
ml { redirect_to @task, notice: ‘...’ } format.json { head :no_content } else format.html { render action: “edit” } format.json { render json: @task.errors, status: :unpro
rity_to_tasks priority:integer $ bundle exec rake db:migrate $ bundle exec rake db:migrate $ bundle exec rails server validate :due_at_is_in_the_past def due_at_is_
one.now #!/usr/bin/en python import pygame from random import randrange MAX_STARS = 100 pygame.init() screen = pygame.display.set_mode((640, 480)) c
star = [randrange(0, 639), randrange(0, 479), randrange(1, 16)] stars.append(star) while True: clock.tick(30) for event in pygame.event.get(): if event.type == pyg
Res qw(usleep); use Curses; $screen = new Curses; noecho; curs_set(0); for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] = rand(80); $star_y[$i] = rand(24); $star_s[$i]
rs ; $i++) { $star_x[$i] -= $star_s[$i]; if ($star_x[$i] < 0) { $star_x[$i] = 80; } $screen->addch($star_y[$i], $star_x[$i], “.”); } $screen->refresh; usleep 50000; gem “theru
ils”, “~> 2.13.0” $ gem install bundler $ gem install rails --version=3.2.12 $ rbenv rehash $ rails new todolist --skip-test-unit respond_to do |format| if @task.update_
.’ } format.json { head :no_content } else format.html { render action: “edit” } format.json { render json: @task.errors, status: :unprocessable_entity } $ bundle exec rails
exec rake db:migrate $ bundle exec rake db:migrate $ bundle exec rails server validate :due_at_is_in_the_past def due_at_is_in_the_past errors.add(:due_at, ‘is in th
ygame from random import randrange MAX_STARS = 100 pygame.init() screen = pygame.display.set_mode((640, 480)) clock = pygame.time.Clock() stars = for i in ran
drange(1, 16)] stars.append(star) while True: clock.tick(30) for event in pygame.event.get(): if event.type == pygame.QUIT: exit(0) #!/usr/bin/perl $numstars = 100;
oecho; curs_set(0); for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] = rand(80); $star_y[$i] = rand(24); $star_s[$i] = rand(4) + 1; } while (1) { $screen->clear; for ($i = 0; $i <
ar_x[$i] = 80; } $screen->addch($star_y[$i], $star_x[$i], “.”); } $screen->refresh; usleep 50000; gem “therubyracer”, “~> 0.11.4” group :development, :test do gem “rsp
sion=3.2.12 $ rbenv rehash $ rails new todolist --skip-test-unit respond_to do |format| if @task.update_attributes(params[:task]) format.html { redirect_to @task, noti
ction: “edit” } format.json { render json: @task.errors, status: :unprocessable_entity } $ bundle exec rails generate migration add_priority_to_tasks priority:integer $ b
exec rails server validate :due_at_is_in_the_past def due_at_is_in_the_past errors.add(:due_at, ‘is in the past!’) if due_at < Time.zone.now #!/usr/bin/en python impo
game.init() screen = pygame.display.set_mode((640, 480)) clock = pygame.time.Clock() stars = for i in range(MAX_STARS): star = [randrange(0, 639), randrange(0, 47
or event in pygame.event.get(): if event.type == pygame.QUIT: exit(0) #!/usr/bin/perl $numstars = 100; use Time::HiRes qw(usleep); use Curses; $screen = new Curs
$i] = rand(80); $star_y[$i] = rand(24); $star_s[$i] = rand(4) + 1; } while (1) { $screen->clear; for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] -= $star_s[$i]; if ($star_
i], “.”); } $screen->refresh; usleep 50000; gem “therubyracer”, “~> 0.11.4” group :development, :test do gem “rspec-rails”, “~> 2.13.0” $ gem install bundler $ gem
-skip-test-unit respond_to do |format| if @task.update_attributes(params[:task]) format.html { redirect_to @task, notice: ‘...’ } format.json { head :no_content } else form
rors, status: :unprocessable_entity } $ bundle exec rails generate migration add_priority_to_tasks priority:integer $ bundle exec rake db:migrate $ bundle exec rake d
ast def due_at_is_in_the_past errors.add(:due_at, ‘is in the past!’) if due_at < Time.zone.now #!/usr/bin/en python import pygame from random import randrange MA
e((640, 480)) clock = pygame.time.Clock() stars = for i in range(MAX_STARS): star = [randrange(0, 639), randrange(0, 479), randrange(1, 16)] stars.append(star) wh
e == pygame.QUIT: exit(0) #!/usr/bin/perl $numstars = 100; use Time::HiRes qw(usleep); use Curses; $screen = new Curses; noecho; curs_set(0); for ($i = 0; $i <
$star_s[$i] = rand(4) + 1; } while (1) { $screen->clear; for ($i = 0; $i < $numstars ; $i++) { $star_x[$i] -= $star_s[$i]; if ($star_x[$i] < 0) { $star_x[$i] = 80; } $screen->add
em “therubyracer”, “~> 0.11.4” group :development, :test do gem “rspec-rails”, “~> 2.13.0” $ gem install bundler $ gem install rails --version=3.2.12 $ rbenv rehash $
s new todolist --skip-test-unit respond_to do |format| if @
nder json: @task.errors, status: :unprocessable_entity } $
:due_at_is_in_the_past def due_at_is_in_the_past errors.

Coding Projects | Contents


ygame.display.set_mode((640, 480)) clock = pygame.time.
.event.get(): if event.type == pygame.QUIT: exit(0) #!/usr/
star_y[$i] = rand(24); $star_s[$i] = rand(4) + 1; } while (1) {
esh; usleep 50000; gem “therubyracer”, “~> 0.11.4” group
d_to do |format| if @task.update_attributes(params[:task])
ocessable_entity } $ bundle exec rails generate migration
_in_the_past errors.add(:due_at, ‘is in the past!’) if due_at
clock = pygame.time.Clock() stars = for i in range(MAX_

Coding projects
game.QUIT: exit(0) #!/usr/bin/perl $numstars = 100; use
= rand(4) + 1; } while (1) { $screen->clear; for ($i = 0; $i <
ubyracer”, “~> 0.11.4” group :development, :test do gem
_attributes(params[:task]) format.html { redirect_to @task,
s generate migration add_priority_to_tasks priority:integer
he past!’) if due_at < Time.zone.now #!/usr/bin/en python
nge(MAX_STARS): star = [randrange(0, 639), randrange(0,
Exciting and interesting coding
use Time::HiRes qw(usleep); use Curses; $screen = new projects for you to write
< $numstars ; $i++) { $star_x[$i] -= $star_s[$i]; if ($star_x[$i]
pec-rails”, “~> 2.13.0” $ gem install bundler $ gem install
ice: ‘...’ } format.json { head :no_content } else format.html Plot beautiful images 94
�������������������������������������������

bundle exec rake db:migrate $ bundle exec rake db:migrate


ort pygame from random import randrange MAX_STARS Functionality of find 98
�������������������������������������������������

79), randrange(1, 16)] stars.append(star) while True: clock.


ses; noecho; curs_set(0); for ($i = 0; $i < $numstars ; $i++)
Programming wc in Python 102
���������

_x[$i] < 0) { $star_x[$i] = 80; } $screen->addch($star_y[$i],


m install rails --version=3.2.12 $ rbenv rehash $ rails new
MicroPython: Light glove 106
���������������������

mat.html { render action: “edit” } format.json { render json: MicroPython: Robot wars 110
��������������������
db:migrate $ bundle exec rails server validate :due_at_is_
AX_STARS = 100 pygame.init() screen = pygame.display. Python: Build an Enigma box 114
�����
hile True: clock.tick(30) for event in pygame.event.get(): if
< $numstars ; $i++) { $star_x[$i] = rand(80); $star_y[$i] = UPS: Power loss protection 118
������������

dch($star_y[$i], $star_x[$i], “.”); } $screen->refresh; usleep


$ rails new todolist --skip-test-unit respond_to do |format| Practical Python 3 modules 120
��������

render json: @task.errors, status: :unprocessable_entity }


:due_at_is_in_the_past def due_at_is_in_the_past errors.
Tkinter: Build a money app 124
������������

ygame.display.set_mode((640, 480)) clock = pygame.time.


.event.get(): if event.type == pygame.QUIT: exit(0) #!/usr/
star_y[$i] = rand(24); $star_s[$i] = rand(4) + 1; } while (1) {
esh; usleep 50000; gem “therubyracer”, “~> 0.11.4” group
d_to do |format| if @task.update_attributes(params[:task])
ocessable_entity } $ bundle exec rails generate migration
_in_the_past errors.add(:due_at, ‘is in the past!’) if due_at
clock = pygame.time.Clock() stars = for i in range(MAX_
game.QUIT: exit(0) #!/usr/bin/perl $numstars = 100; use
= rand(4) + 1; } while (1) { $screen->clear; for ($i = 0; $i <
ubyracer”, “~> 0.11.4” group :development, :test do gem
_attributes(params[:task]) format.html { redirect_to @task,
s generate migration add_priority_to_tasks priority:integer
he past!’) if due_at < Time.zone.now #!/usr/bin/en python
nge(MAX_STARS): star = [randrange(0, 639), randrange(0,
use Time::HiRes qw(usleep); use Curses; $screen = new
< $numstars ; $i++) { $star_x[$i] -= $star_s[$i]; if ($star_x[$i]
pec-rails”, “~> 2.13.0” $ gem install bundler $ gem install
ice: ‘...’ } format.json { head :no_content } else format.html
bundle exec rake db:migrate $ bundle exec rake db:migrate
ort pygame from random import randrange MAX_STARS
79), randrange(1, 16)] stars.append(star) while True: clock.
ses; noecho; curs_set(0); for ($i = 0; $i < $numstars ; $i++)
_x[$i] < 0) { $star_x[$i] = 80; } $screen->addch($star_y[$i],
m install rails --version=3.2.12 $ rbenv rehash $ rails new
mat.html { render action: “edit” } format.json { render json:
db:migrate $ bundle exec rails server validate :due_at_is_
AX_STARS = 100 pygame.init() screen = pygame.display.
hile True: clock.tick(30) for event in pygame.event.get(): if
< $numstars ; $i++) { $star_x[$i] = rand(80); $star_y[$i] = Coding Made Simple | 93
dch($star_y[$i], $star_x[$i], “.”); } $screen->refresh; usleep
$ rails new todolist --skip-test-unit respond_to do |format|
Coding Projects | Fractals

Fractals: Plot
beautiful images
We show you how to draw some famous fractals, including your own
snowflakes, in various programming languages.

T
he subject of this tutorial is something very beautiful can define everything yourself, which will give you greater
and impressive: fractals. After learning the required control and a better understanding of the process while
theory, you’ll learn how to plot extremely beautiful requiring more code. Most of the scripts in this article don’t
images using various programming languages. We’ll cover use a module.
scripts in R, Perl, Python and LaTeX that you can easily port to
the programming language of your choice. Although fractals Inside the Mandelbrot
and chaos theory are areas of advanced mathematics, they The Mandelbrot set is one of the most famous fractals, so
can also be fun from time to time, and generate impressive let’s briefly explain how it works. The function that’s used is
images—even if you don’t understand all the presented called a quadratic polynomial. The form of a quadratic
theory you should enjoy the produced images! polynomial is f(x) = x*x + c, where c is a constant number.
A fractal is a natural phenomenon and a mathematical set. In order to start the iterations, you’ll need a starting number
Fractals present a repeating pattern that displays at every called x0, which is called the seed of the iteration. After
scale. This means that the same pattern can be revealed even calculating the f(x0), which is called x1 and equals x0*x0 + c,
if you zoom in multiple times, which is what makes fractals you will calculate f(x1), which is called x2 and equals x1*x1 + c
unique and pleasing to the eye. Most fractals begin from a and so on and so forth. Imagine now that c is a complex
mathematical equation that when drawn in a certain way number. A complex number is a number that can be
produces an interesting yet fairly complex plot. represented as a + bi, where a and b are real numbers and i is
Fractals are related to the dynamic systems and chaos the imaginary unit—all the presented algorithms that draw
area of advanced mathematics. Put simply, the chaos theory Mandelbrot sets change these two real numbers (a and b).
tells us that small changes to a given quantity can result in The imaginary unit i satisfies the equation i*i = −1. So, in order
huge changes to a function of it. The function is what’s the to create a Mandelbrot set, you will need to choose a seed
important thing here, because the way you plot the function and the constant complex value of c.
is what generates a fractal. Strictly speaking, chaos theory is
a field of mathematics that studies the way dynamical
systems behave. Dynamical systems are highly sensitive to
initial conditions, which is what causes the chaos. This means
that you can’t predict their behaviour even though they
behave deterministically because their behaviour is fully
related to their initial conditions. In other words, although the

Quick present determines the future, the approximate present can’t


determine the future! Chaos theory has applications in many
tip fields including computer security, meteorology, engineering,
Two advanced biology and computer science and the next section will
books that will
introduce you to various well-known fractals.
teach you most
of the theory of The term fractal was first introduced by the
Dynamic Systems mathematician, Benoît Mandelbrot, in 1975, so it’s no surprise
and Chaos are that the first and most famous fractal was named after
Introduction to Mandelbrot. The second most famous fractal is the Julia set
Applied Nonlinear
Dynamical Systems
while another known fractal is the Koch snowflake. The Koch
and Chaos by fractal starts from a line segment. In this tutorial, we’ll also
Stephen Wiggins introduce you to the Sierpinski triangle.
and Differential Each fractal has parameters that need to be set in order to
Equations and
produce it. When you’re using a module to create a fractal,
Dynamical Systems
by Lawrence Perko. you only need to define those parameters and you are ready The mandelSet.pl Perl script shows an easy way to
to go. On the other hand, if you prefer to do all the work, you draw a Mandelbrot fractal using plain text.

94 | Coding Made Simple


Coding Projects | Fractals
#!/usr/bin/env python3
Quick
import sys
tip
from PIL import Image You can learn
more about the
import random
Mandelbrot set
and the Julia
if len(sys.argv) == 2: set at https://
outputSize = int(sys.argv[1]) en.wikipedia.org/
else: wiki/Mandelbrot_
set and https://
print('Usage: ', sys.argv[0], 'ImageSize')
en.wikipedia.org/
Here we have the output from two executions of the sys.exit(0) wiki/Julia_set,
juliaSet.py script, using different values for the xa, xb, ya respectively.
and yb variables. The right fractal is a zoomed version of image = Image.new("RGB", (outputSize, outputSize)) Similarly you can
learn more about
the left fractal. xa = -2.5
the Koch snowflake
xb = 2.5 at https://
Strictly speaking, the Mandelbrot set consists of all of ya = -2.5 en.wikipedia.
those (complex) c-values for which the quadratic polynomial yb = 2.5 org/wiki/Koch_
x*x + c doesn’t escape to infinity. The phrase “does not nIterations = 128 snowflake.
escape to infinity” means that the value of x*x + c doesn’t
become bigger and bigger from iteration to iteration because while True:
when a quantity becomes bigger and bigger all the time it will cx = random.random() * (xb - xa) + xa
reach infinity at some point. This is more or less the way the cy = random.random() * (yb - ya) + ya
Mandelbrot set works, which is relatively simple. Although it c = cx + cy * 1j
sounds very theoretical, wait until you see the appealing plots z=c
that it generates. The Julia set is based on the Mandelbrot set for i in range(nIterations):
so the general idea is the same. if abs(z) > 2.0:
break
Using Perl z=z*z+c
Perl can help you create your own fractals. In order to make if i > 10 and i < 100:
things simpler, the presented Perl script will generate text break
output instead of a graphics file! The Perl code of mandelSet.
pl is the following: for y in range(outputSize):
#!/usr/bin/perl -w zy = y * (yb - ya) / (outputSize - 1) + ya
use Math::Complex; for x in range(outputSize):
zx = x * (xb - xa) / (outputSize - 1) + xa
sub MB { z = zx + zy * 1j
my ($fx, $c) = @_[0,0]; for i in range(nIterations):
for(1 .. 20) { if abs(z) > 2.0:
$fx = $fx * $fx + $c; break
return $_ if abs $fx > 2; z=z*z+c
} image.putpixel((x, y), (i % 8 * 32, i % 4 * 32, i % 8 * 32))
}
image.save("juliaPython.png", "PNG")
my $y = 0; The while loop in juliaSet.py uses the Mandelbrot set for
for ($y = 1; $y >= -1; $y -= 0.05) { finding a good Julia set point. The output is executed with:
my $x = 0;
for($x = -2; $x <= 0.5; $x += 0.0305) {
print MB($x + $y * i) ? ' ' : '#'
}
print "\n"
}
(See left for the text output of the Perl script.) The key
point of the Perl script is the use of complex numbers with
the help of the Math::Complex module. The quadratic
polynomial that is used is defined in the MB function using
the $fx variable. The Perl script is an easy way to impress
your friends and better understand the process. The Python
code, below, will add colour to the output and make it even
more impressive.
This is the

Using Python output of fr.R,


which uses the
This section will present two Python 3 scripts that draw the capabilities of
Julia set and the Mandelbrot set, respectively. The name of R to draw the
the first script, juliaSet.py, draws the Julia set: Mandelbrot set.

Coding Made Simple | 95


Coding Projects | Fractals

$ ./juliaSet.py 1600 #!/usr/bin/env Rscript


As you can see, (the output is pictured on the previous
page) it contains two images. The right image is a zoomed in MB <- function(z, c, trans, cond, max=50, response=dwell)
version of the left one. For the right one the values of both xb {
and yb were 0.5 and the values of both xa and ya were -0.5. active <- seq_along(z)
You can zoom in as much as you want using values such as dwell <- z
0.05 for xb and yb and -0.05 for xa and ya. Similarly, you can dwell[] <- 0
draw the Mandelbrot set with the help of mandelSet.py: for (i in 1:max)
#!/usr/bin/env python3 {
z[active] <- trans(z[active], c[active]);
from numpy import complex, array survived <- cond(z[active])
from PIL import Image dwell[active[!survived]] <- i
import colorsys active <- active[survived]
import sys if (length(active) == 0) break
}
if len(sys.argv) == 2: eval(substitute(response))
outputSize = int(sys.argv[1]) }
else:
print('Usage: ', sys.argv[0], 'ImageSize') re = seq(-2, 1, len=1000)
sys.exit(0) im = seq(-1.5, 1.5, len=1000)
c <- outer(re, im, function(x,y) complex(real=x, imaginary=y))
def iToRGB(i): x <- MB(array(0, dim(c)), c, function(z,c)z^2+c, function(z)
color = 255 * array(colorsys.hsv_to_rgb(i/255.0, i/100.0, abs(z) <= 2, max=50)
i/55.0)) png(filename="Rfractal.png", width=1024, height=1024)
return tuple(color.astype(int)) par(bg = "lightblue")
par(col = “"black")
def M(x, y): image(x, col=rainbow(100))
c0 = complex(x, y) dev.off()
c=0 This script deals with functions of complex numbers
for i in range(1, 1000): natively, which is handy and saves you from having to write
if abs(c) > 2: extra code or import a module. The third parameter of the x
return iToRGB(i) variable is the definition of the quadratic polynomial whereas
c = c * c + c0 the c variable holds the various values of the complex
return (10, 10, 10) constant. (See bottom of the previous page for the output of
the R code.) The rainbow() function inside the image()
img = Image.new('RGB', (outputSize, int(outputSize/2))) function is what generates such a colourful output. If you
pixels = img.load() want to get just two colours in the output, you can remove the
Quick for x in range(img.size[0]): call to the rainbow() function.
tip for y in range(img.size[1]):
The general idea pixels[x,y] = M((x - (0.75 * outputSize))/(outputSize/4), (y Plotting a Koch snowflake
is to use the - (outputSize/4))/(outputSize/4)) Koch snowflake starts with a line segment, so it’s more
programming related to geometry than mathematics. Each iteration
language you know img.save("mandelPython.png", "PNG") replaces the middle third of each line segment with a pair of
best. However,
The quadratic polynomial is defined inside the M() line segments that form an equilateral triangle that points
when having to
deal with lots of function using the c variable. This function takes two outward without the base. So now that you understand how a
mathematics, parameters, which are the real numbers of the complex Koch snowflake is constructed, it’s time to see the Python 3
software such constant of the quadratic polynomial—the c0 variable holds code of kochTr.py:
as R, Octave and
the value of the complex constant. The mandelSet.py script #!/usr/bin/env python3
MatLab can save
you a lot of time, takes one parameter which is the width of the final image in
because all three pixels and saves the final image as mandelPython.png: import os
packages have $ ./mandelSet.py 1600 import sys
native support for R has a big advantage over other programming languages: from turtle import *
most mathematical
it knows mathematics, which means that you can define any
formulas and
functions. function you want and plot it any way you like it pretty easily. def snowflake(length, levels):
Look at the following R script called fr.R: if levels == 0:
fd(length)
return
length /= 3.0
snowflake(length, levels-1)
left(60)
snowflake(length, levels-1)
These three outputs from the kochTr.py Python 3 script should give you a
better understanding of how a Koch snowflake is constructed.
right(120)
snowflake(length, levels-1)

96 | Coding Made Simple


Coding Projects | Fractals
left(60)
snowflake(length, levels-1) About the Sierpinski triangle
if len(sys.argv) == 3: The Sierpinski triangle is another Then, you remove the central one—this
length = int(sys.argv[1]) ingenious way to generate a fractal that triangle remains empty and is always
levels = int(sys.argv[2]) is based on geometry and works with visible because it will never be used in
penup() equilateral triangles, which are the process. Last, you do the same for
bk(length/2.0) subdivided recursively into smaller the remaining three equilateral triangles
equilateral triangles. for as many times as needed. The final
pendown()
The algorithm is easy to understand product of the Sierpinski triangle fractal
snowflake(length, levels)
and works as follows: you start with a is still composed of multiple equilateral
mainloop() equilateral triangle that you divide into triangles. You can see this in action at
else: four smaller equal equilateral triangles. the bottom of the page.
print('Usage: ', sys.argv[0], ‘Length Levels')
sys.exit(0)
The script uses turtle graphics to plot the final image. (See
bottom left for three distinct plots in order to get a better executed twice as follows:
understanding of the various phases of the process): $ time ./sierpinski.py 500 5
$ ./kochTr.py 300 2
$ ./kochTr.py 300 3 real 1m46.462s
$ ./kochTr.py 300 4 user 0m12.508s
It’s truly wonderful how such a simple idea generates such sys 0m3.427s
a glorious plot! $ time ./sierpinski.py 500 7

Oh Sierpinski triangle real 14m43.285s


The following Python 3 script, sierpinski.py, draws a user 1m25.576s
Sierpinski triangle: sys 0m21.511s
#!/usr/bin/env python3 You can also see the output of the time command for
each execution. The actual times don’t really matter—what
import turtle matters is that the first execution is significantly faster (about
import os eight times faster) than the second one due to the added
import sys complexity of the second execution. Nevertheless, the size of
the outer triangle is the same in both cases because the first
def S(side, level): parameter of both executions is the same. Additionally, due to
turtle.bgcolor("lightgreen") the way turtle graphics work, the process is animated and
if level == 1: therefore even more impressive than the actual outcome of
for i in range(3): the Python script.
turtle.fd(side) To finish, LaTeX has some ready to use packages that can
turtle.left(120) draw fractals including the Mandelbrot set:
else: \documentclass{article}
S(side/2, level-1) \usepackage{tikz}
turtle.fd(side/2) \usetikzlibrary{shadings}
S(side/2, level-1) \begin{document}
turtle.bk(side/2) \tikz\shade[shading=Mandelbrot set] (0,0) rectangle (15,15);
turtle.left(60) \end{document}
turtle.fd(side/2) You’ll need to compile the LaTeX code, saved as
turtle.right(60) mandelbrot.tex, in order to see the generated output with:
S(side/2, level-1) $ pdflatex mandelbrot.tex
turtle.left(60) And this will be output as a mandelbrot.pdf. As you can
turtle.bk(side/2) see, there’s lots of fun to be had with fractals! n
turtle.right(60)

if len(sys.argv) == 3:
s = int(sys.argv[1])
l = int(sys.argv[2])
S(s, l)
turtle.mainloop()
else:
print('Usage: ', sys.argv[0], 'Side Level')
sys.exit(0)
The first parameter of the S() function defines the size of
the final triangle whereas the second parameter to the S()
function is about the level of recursion of the triangle. See Here we’ve presented two Sierpinski triangles with different complexities.
(below) for the output from the previous script when However, the outermost triangles are exactly the same size.

Coding Made Simple | 97


Coding Projects | Functionality of find

Functionality of
find in Python
The find command line utility is incredibly useful for quickly finding files and
directories. In this tutorial we show you how to code your own version of it.

T
his tutorial will teach you how to implement the /home/mtsouk/docs/myFind.py
basic functionality of the find(1) command line $ find . -name python
utility in Python 3, which is a very popular and handy ./python
UNIX tool that helps you find files and directories on your ./python/python
Linux machine. $ find . -type d -name python
This tutorial will try to implement a small part of find, ./python
however once you understand the Python 3 code presented $ find . -type -name python
This image in this tutorial, you can add features on your own. find: Arguments to -type should contain only one letter
shows a small
The first command searches all directories starting from /
part of the man
page of the
The basics of find home/mtsouk, which is an absolute path because it starts
find(1) utility, This section will illustrate the use of the find utility using easy from the root directory ('/'), in order to find one or more files
which you can to understand examples. or directories with the exact name of myFind.py. If there is a
see by typing For instance, this example shows simple uses of find: match, the path of the file will be printed on the screen.
“man find”. $ find /home/mtsouk -name myFind.py Otherwise, according to the UNIX philosophy, find will print
no output.
If multiple matches are found, all matches will be printed.
The second find command searches the directory tree that
starts from the current directory for files or directories named
“python”, whereas the third command searches for
directories only. The last example presents an error message
from find because the -type option is not complete.
Please note that on UNIX systems the single dot (’.‘) points
to the current working directory whereas two dots (’..‘) point
to the parent directory. This is pretty handy when you do not
want to type full paths.
The find utility can do many more things, as it is a very
powerful command, but we can’t cover them all here. The
good thing is that once you have developed a Python 3
version, it is relatively easy to extend it in order to support
more options. The most difficult thing is developing a working
version in the first place.
Knowing what you are going to implement is extremely
important so always try to make clear what features your
programs will have as soon as possible!
The image on the left shows a small part of the man page
of the find(1) utility.

About __main__ and __name__


Although it is not absolutely necessary, it is considered good
practice for a Python 3 script to begin its execution by testing
the value of the __name__ variable. Look at the following code
saved as b.py:
if __name__ == ‘__main__':
print('This is b.py executed as ', __name__)
else:
print('This is b.py executed from: ', __name__)
What __name__ does is check whether the file is being

98 | Coding Made Simple


Coding Projects | Functionality of find
The time command line utility
The time(1) command line utility can help you measure the
performance of a program by showing useful information
about its execution. The time command line utility runs the
specified command and gives timing statistics after the
command finishes.
You can see how the output of the time command looks in
the image on the right.
The timing statistics have three parts: real, user and sys
times. Real is the actual time from start to finish. User is the
CPU time spent in user-mode code. Sys is the CPU time
spent in the kernel. Put simply, Sys is the time your program
was waiting for Linux to perform tasks for it, whereas User is
the time your program was running on a CPU. Adding User
and Sys times will show how much CPU time you used. If
your machine has multiple CPUs and your process uses
multiple threads, then the previous result might exceed the This image shows the performance differences between the Python 2.7.10
value of the Real time field. version of os.walk() and the Python 3.5.2 version of os.walk().

imported from another module or not. When a Python 3 the use of os.walk():
script runs as a standalone program, the value the __name__ #!/usr/bin/env python3 Quick
variable is: __main__. This is automatically defined by Python tip
3. The following output showcases the previous code: import os Hard symbolic
$ cat a.py import sys links are directory
entries pointing
import b
to the same inode
print("This is module a!") if len(sys.argv) >= 2: of an existing file.
$ python3 b.py directory = str(sys.argv[1]) An inode is an
This is b.py executed as __main__ else: index that uniquely
$ python3 a.py print('Not enough arguments!') identifies a file on
a given filesystem.
This is b.py executed from: b sys.exit(0)
The main
This is module a! advantage of hard
$ ls -l __pycache__/ for root, dirs, files in os.walk(directory): links is that they do
total 4 print('**’, root) not allow a file to
get deleted unless
-rw-r--r-- 1 mtsouk mtsouk 267 Oct 15 15:40 b.cpython-34. for file in files:
you delete all hard
pyc pathname = os.path.join(root,file) links that point to
$ file __pycache__/b.cpython-34.pyc if os.path.exists(pathname): it. All hard links
__pycache__/b.cpython-34.pyc: python 3.4 byte-compiled print(pathname) to a file including
After using b.py as a module, you might find a new Executing learnWalk.py generates the following kind the file itself are
considered “equal”.
directory named __pycache__ in your current directory. of output:
The __pycache__ directory contains Python 3 bytecode, $ ./learnWalk.py ~/code
which is used for speeding up the execution of Python 3 ** /home/mtsouk/code
programs. You can delete it if you want to, but Python 3 will /home/mtsouk/code/a.out
generate it again the next time you use the b.py module or ** /home/mtsouk/code/Haskell
any other module. ...
The file(1) command is a Linux command line utility that /home/mtsouk/code/C/sysProg/sparse.c
can determine the type of a file. /home/mtsouk/code/C/sysProg/filetype.c
So, the purpose of the __name__ variable is to let your As you can see, learnWalk.py visits everything starting
code know whether the Python code runs as a standalone from a root directory and prints any file or directory it finds in
program or not in order to act appropriately. Due to the the process, which is simple yet very effective. The os.path.
limited space we have, only the final version of the code will exists() method makes sure that a file actually exists before
use this technique. printing it.
Please make sure that you completely understand this
The os.walk() function technique before continuing with the rest of the tutorial.
The os.walk() function is extremely handy for recursively It is now time to present a first version of the Python 3
visiting and processing all files and directories in a directory implementation of the find utility.
tree, starting from a given root directory. It is very interesting
to note that os.walk() needs just one parameter, the name of A first Python 3 version of find
the directory you want to visit. Next, a for loop does the rest Now that you got all the necessary bits and pieces, it is time
of the job by iterating over all the subdirectories and files of to combine them to create a first version of the find utility,
the root directory that was given as the parameter to os. which will be called firstFind.py. This version accepts two
walk(). The following code, saved as learnWalk.py, illustrates command line arguments, the first one is the name of the

Coding Made Simple | 99


Coding Projects | Functionality of find

The final Python 3 version of find


The final version of find is called myFind.py – its main
difference from firstFind.py is that myFind.py accepts two
command line options (aka switches). The -d option tells
myFind.py to search for directories only whereas the -f
option tells myFind.py to search for files only. If you use
both switches or none of them, myFind.py will search for
both types!
It is compulsory that the first command line argument is
the directory name and that the second command line
argument will be the name of the file or directory you want
to search for. Therefore, the two switches will come at the
end of the command in no particular order. The code of
myFind.py is:
#!/usr/bin/env python3
This image directory that the search will start from and the second is the
shows sample name of the file to search for. import os
executions of The contents of firstFind.py are: import sys
the myFind. #!/usr/bin/env python3
py system def find(directory, filename, dirOnly, fileOnly):
tool, which are
import os if (dirOnly == 0 and fileOnly == 0):
mainly used
import sys dirOnly = 1;
for testing the
script. fileOnly = 1;
if len(sys.argv) >= 3:
directory = str(sys.argv[1]) for root, dirs, files in os.walk(directory):
filename = str(sys.argv[2]) if dirOnly == 1:
else: if os.path.basename(os.path.normpath((root))) ==
print('Not enough arguments!') filename:
sys.exit(0) print(root)
for file in files:
for root, dirs, files in os.walk(directory): pathname = os.path.join(root,file)
print('**’, root) if os.path.exists(pathname):
for file in files: if fileOnly == 1:
pathname = os.path.join(root,file) if file == filename:
if os.path.exists(pathname): print(pathname)
if file == filename:
print(pathname) def main():
Executing firstFind.py generates the following kind of dirOnly = 0;

Quick output:
$ ./firstFind.py . a.out


fileOnly = 0;
if len(sys.argv) == 3:
tip ** . directory = str(sys.argv[1])
If you move a file, ./a.out filename = str(sys.argv[2])
its soft links will
** ./Haskell elif len(sys.argv) == 4:
not follow. On the
other hand, if you ** ./python directory = str(sys.argv[1])
move or change the ** ./perl filename = str(sys.argv[2])
name of a file, its ** ./C option1 = str(sys.argv[3])
hard links will still ./C/a.out if option1 == “-d":
point to that file.
** ./C/system dirOnly = 1;
Additionally, soft
links can point to ** ./C/example if option1 == “-f":
other filesystems ** ./C/cUNL fileOnly = 1;
whereas hard links ** ./C/sysProg elif len(sys.argv) >= 5:
can only exist in the
$ ./firstFind.py directory = str(sys.argv[1])
same filesystem.
Both of them are Not enough arguments! filename = str(sys.argv[2])
created with the The previous output is a very practical way to test that option1 = str(sys.argv[3])
ln(1) command. firstFind.py actually works. The entries that begin with “**” option2 = str(sys.argv[4])
are directories – this kind of output is used for making sure if (option1 == “-d” or option2 == “-d"):
that firstFind.py visits all the desired directories – the final dirOnly = 1;
version of our system tool will not generate such output. if (option1 == “-f” or option2 == “-f"):
firstFind.py can also find the desired files. fileOnly = 1;
So far the firstFind.py script looks like it is working as else:
expected, so we can now continue and implement the print('Usage: ', sys.argv[0], ‘directory
missing functionality. The most important part of the missing filename [-df]')
functionality is the support for command line options, which sys.exit(0)
can be very tricky. # If the given path exists do your job

100 | Coding Made Simple


Coding Projects | Functionality of find
if os.path.isdir(directory):
find(directory, filename, dirOnly, fileOnly)
else:
print('Directory ', directory, ‘does not
exist!')

if __name__ == ‘__main__':
main()
else:
print("This is a standalone program not a
module!")
As you can see, the __name__ variable is usually
combined with a main() function; should you decide to
use myFind.py as a module, the presence of the main()
function will allow you to use the capabilities of myFind.py
from other programs.
As you can see a large part of main() deals with the
command line options. Although there exist modules that
allow you to deal with arguments and switches using less $ ./myFind.py This
code, this is the most easy to understand way. The core Usage: ./myFind.py directory filename [-df] screenshot
functionality of the program is implemented inside the shows a
find() function, which is more or less similar to the code in Comparing os.walk() and os.scandir() big part of
the online
firstFind.py. If you are using Python version 3.5 or newer, you can use the
documentation
The find() function also makes sure that only the desired os.scandir() function instead of os.walk() because os. of the os.walk()
kind of files are displayed. The call to os.path.basename() and scandir() is much faster than os.walk(), as it avoids calls to method, which
os.path.normpath() methods is needed in order to extract os.stat(). The good news is that if you are using Python 3.5 or implements
the last part of a path, which is the name of the directory, and newer, os.walk() automatically uses os.scandir() in its the core
compare it to the “filename” you want to search. implementation so you do not need to do any extra work to functionality
This happens because myFind.py cannot correctly your code. of the myFind.
match a string such as “code” to a full path such as /home/ This final part of the tutorial will test the speed differences py script.
mtsouk/code. between os.walk() and os.scandir() using the relatively simple
time(1) command. The tests will use Python version 3.5.2,
Testing your code! which uses os.scandir(), and Python version 2.7.10, which
Testing is very important, especially when your script deals does not use os.scandir(). In order to make the tests as
with systems files and directories. So, you will have to run
some tests to verify that myFind.py works as expected –
reliable as possible, you will need to search a big directory
tree such as /usr or /var. This section will use a modified
Quick
without testing, no tool can be deployed on a production version of the learnWalk.py script saved as testSpeed.py:
tip
system as it might compromise its security and its stability. import os Soft links are naive
pointers to files or
The first test is trying to find a file that does not exist, whille import sys
directories. A soft
the second test is about finding a file or directory that exists link is resolved each
in one instance, while the third test is about finding a filename if len(sys.argv) >= 2: time you access it.
that exists multiple times in the directory structure you are directory = str(sys.argv[1]) Soft links are not
searching. else: “equal” to the file or
the directory that
Because you cannot have the same filename on the same print('Not enough arguments!') they are pointing to.
directory twice, in the third case the filename should exist in sys.exit(0)
different directories. The last two tests will verify that myFind.
py is able to differentiate between directories and files when total = 0
used with the appropriate switches. The image at the top of for root, dirs, files in os.walk(directory):
page 114 shows myFind.py performing the tests we’ve just for file in files:
described. total = total + 1
The good thing with testing is that you are also learning print('Visited’, total, ‘files!')
how to use the code while you are testing it. The results shows the timing of various executions of the
Running myFind.py without any command line arguments two slightly different implementations, telling us that the
reveals the following helpful message: Python 3.5 version is significantly faster! n

Finding Documentation about os.walk()


As this tutorial uses some relatively complex documentation site, the pydoc3 command line use. There are times where a small option can
methods, it is very important to carefully read utility and the Python 3 shell. Most of the times make the difference between a working and a
the documentation of each method before the Python 3 documentation site has the most non-working program.
using it. up to date information. The important thing is Should you wish to learn more about the os.
There are various places where you can look trying to understand the presented information scandir() method, you can visit https://docs.
for documentation including the Python 3 and the subtleties of the methods you want to python.org/3/library/os.html#os.scandir.

Coding Made Simple | 101


Coding Projects | Programming wc

Programming
wc in Python
We show you what you need to know to develop a handy system tool in
Python 3 that will make your life easier.

T
he subject of this tutorial is programming the famous f = open(filename, ‘r')
wc command line utility in Python 3. wc(1) is a for word in f.read().split():
relatively simple utility with only three main command print(word)
line switches, which will also be implemented here. In other As wc(1) has to count the number of words per line and
words, when you implement such a famous utility, it is easy to not process them, you can use the following code instead:
decide what you want to support so you do not have to think nWords = len(line.split())
a lot about the features your program will have. The split() method separates the words of a line and the
len() method returns the number of words returned by split().
About wc Lastly, you can process a text file character by character
One of the oldest UNIX command line utilities, wc allows you using this Python 3 code:
to quickly find out information about a text file. The wc utility f = open(filename, ‘r')
counts the words, lines and characters of its input, which is for word in f.read().split():
usually one or more plain text files. for ch in word:
The more recent GNU wc(1) utility has more options than print(ch)
the original wc implementation. However, in order to count the number of characters a line
has, you do not need to process each line character by
Reading text files character, which would be too slow, so you just have to count
The most important task of the implementation is being able its length using the len() function.
to read a text file. The most convenient way to read the file is By combining the previous code, we can come up with a
line by line and processing each line individually. The following program that implements the central functionality of wc(1),
Python 3 code shows how to open and process a text file line which is character, word and line counting. This script will be
by line: called count3.py:
f = open(filename,‘r') #!/usr/bin/env python3
Quick for line in f:
line = line.rstrip() import os
tip print(line) import sys
A program that is The rstrip() function is called in order to remove the
executed without
new line character that is present at the end of each line. if len(sys.argv) >= 2:
being compiled by a
compiler is usually So far, you know how to read a text file line by line, which filename = str(sys.argv[1])
said to be a script. solves the problem of counting the lines of a text file. The else:
On the other hand, following program, saved as countLines.py, implements print('Not enough arguments!')
code that needs this functionality: sys.exit(0)
to be compiled
before execution is
#!/usr/bin/env python3 nLines = 0
said to generate a nWords = 0
program. However, import os nChars = 0
nowadays you can import sys f = open(filename,‘r')
refer to a text file
for line in f:
with Python code
as both a script and filename = str(sys.argv[1]) nLines = nLines + 1
a program. nLines = 0 nChars = nChars + len(line)
f = open(filename,‘r') nWords = nWords + len(line.split())
for line in f:
nLines = nLines + 1 print('Lines:’, nLines, ‘Words:’, nWords, ‘Chars:’, nChars)
print(nLines) Executing count3.py generates the following kind
You can also process a text file word by word using the of output:
following technique: $ ./count3.py count3.py

102 | Coding Made Simple


Coding Projects | Programming wc
About standard input, output and error
UNIX has the concept of standard streams of data. So, each input to another file:
program automatically gets access to three data streams: $ ./myWC.py < count3.py
input, output and error. 27 78 536
Each standard stream has a file descriptor associated with, 0, 1 The previous method does not work with multiple files. With
and 2 respectively. A file descriptor is just a number used for this you can take advantage of standard input, output and error
referring to an open file. as well as how to redirect standard error to standard output
The following command shows how to use a single file as an and ignore the standard error output with a redirection.

Lines: 22 Words: 55 Chars: 385 nLines = nLines + 1


$ wc count3.py nChars = nChars + len(line)
22 55 385 count3.py nWords = nWords + len(line.split())
The second command uses wc(1) to verify that the
count3.py script works correctly and remember: always test print('Lines:’, nLines, ‘Words:’, nWords, ‘Chars:’, nChars)
your code! By testing your code when learning how to All the job here is done by declaring the filename as ‘None’,
program you can gain a better understanding of how the code which is a special Python value that means that the filename
works. If there is an error with your code (and let’s face it, at variable has no value. Next you use sys.stdin to read from
some point there will be, especially when you’re starting out) standard input as if it was a regular file. Now, you can use
then it’s better to catch those errors early. The next section count3.py in two new ways (although the old one still works):
$ cat count3.py | ./count3.py
Quick
will make the code of count3.py even better.
Lines: 27 Words: 78 Chars: 536
tip
Reading from standard input $ ./count3.py A very good Python
3 book is “Dive Into
wc(1) can get its input from standard input; therefore you will 1234
Python 3”, which
need to learn how to do the same in Python 3. But, when do Lines: 1 Words: 1 Chars: 5 also be found online
you need to read from standard input? The following script $ ./count3.py count3.py at http://www.
will read from standard input when there is no filename given Lines: 27 Words: 78 Chars: 536 diveintopython3.
as a command line argument. $ cat count3.py count3.py | ./count3.py net. Two other
useful books
The other command line options will still be valid and Lines: 54 Words: 156 Chars: 1072 for experienced
working if they are present. The two simplest ways to create The last command proves that count3.py can even accept developers are
a pipe and pass the output of the first program to wc(1) are multiple files in the standard input. However, count3.py will “Fluent Python” by
the following: not read from standard input if it has a file to process, even if Luciano Ramalho
and “Effective
$ cat aTextFile | wc the filename does not exist:
Python” by Brett
$ ls | wc $ cat myWC.py | ./count3.py count3.py Slatkin. Although
Currently, if you try to execute the next command, you will Lines: 27 Words: 78 Chars: 536 reading books can
get an error message: $ wc myWC.py be very useful,
$ cat count3.py | ./count3.py 37 99 753 myWC.py nothing can beat
practice!
Not enough arguments! $ cat myWC.py | ./count3.py count3
An improved version of count3.py implements the Traceback (most recent call last):
desired functionality: File "./count3.py”, line 21, in <module>
#!/usr/bin/env python3 f = open(filename,‘r')
FileNotFoundError: [Errno 2] No such file or directory:
import os ‘count3’
import sys
if len(sys.argv) >= 2: Dealing with command line
filename = str(sys.argv[1]) arguments
else: The original wc(1) utility supports three main switches: -m for
filename = None counting characters only, -l for counting lines only and -w for
counting words only.
nLines = 0 As a result, our implementation should also support these
nWords = 0 three switches. Dealing with more than two command line
nChars = 0 options without a module to help is silly.
The next Python 3 code, saved as comLine.py, shows you
if filename == None: how to deal with both command line options and switches
for line in sys.stdin: with the help of a module that is called argparse:
nLines = nLines + 1 #!/usr/bin/env python3
nChars = nChars + len(line)
nWords = nWords + len(line.split()) import os
else: import sys
f = open(filename,‘r') import argparse
for line in f:

Coding Made Simple | 103


Coding Projects | Programming wc

parser = argparse.ArgumentParser() comLine.py: error: unrecognized arguments: 12


parser.add_argument("-m”, default = False, action="store_ Generally speaking, it is better to include the switches first
true”, help="Counting Characters”, required=False) and then the filenames. You can also get help:
parser.add_argument("-l”, default = False, action="store_ $ ./comLine.py -h
true”, help="Counting Lines”, required=False) usage: comLine.py [-h] [-m] [-l] [-w] [filenames [filenames ...]]
parser.add_argument("-w”, default = False, action="store_
true”, help="Counting Words”, required=False) positional arguments:
parser.add_argument('filenames’, default = None, filenames Filenames
help="Filenames”, nargs='*')
optional arguments:
args = parser.parse_args() -h, --help show this help message and exit
if args.filenames == None: -m Counting Characters
print('No filenames given!') -l Counting Lines
else: -w Counting Words
for f in args.filenames: As you can see comLine.py works just fine; therefore, we
print(f) can continue with the actual Python 3 implementation.
You can find more information about argparse at https://
if args.m == True: docs.python.org/3/library/argparse.html.
print('-m is on!')
else: The final version
print('-m if off!') Once you know all the previous things, implementing wc(1) in
Python 3 should be relatively easy and straightforward. The
if args.l == True: Python 3 code of myWC.py is the following:
print('-l is on!') #!/usr/bin/env python3
else:
print('-l if off!') import os
import sys
if args.w == True: import argparse
print('-w is on!')
else: def count(filename):
print('-w if off!') nLines = 0
The parser.add_argument() method adds a new switch nWords = 0
whereas, the args variable holds the values of the defined nChars = 0
switches. Executing comLine.py generates the following kind if filename == None:
of output: myText = sys.stdin.read()
$ ./comLine.py -l 1 chars = len(myText)
1 words = len(myText.split())
-m if off! lines = len(myText.split('\n'))
-l is on! return(lines-1, words, chars)
-w if off! else:
$ ./comLine.py -l -w f = open(filename,‘r')
-m if off! for line in f:
-l is on! nLines = nLines + 1
-w is on! nChars = nChars + len(line)
However, the next form will not work because it includes a nWords = nWords + len(line.split())
switch and then a filename: return(nLines, nWords, nChars)
$ ./comLine.py 1 2 3 -l 12
usage: comLine.py [-h] [-m] [-l] [-w] [filenames [filenames ...]] def main():

Processing command line arguments


When you execute a Linux command or a script #!/usr/bin/env python3 ‘2’, ‘-w']
you usually provide some text after the name of 1
the program, which are usually called command import os 2
line arguments, can be accessed in every import sys -w
programming language and Python 3 is no print('All arguments:’, str(sys.argv)) As you can see, the first print() command
exception. Traditionally, command line for i in sys.argv[1:]: displays all arguments, whereas the for loop
arguments on a UNIX system are stored using print(i) processes all arguments one by one while
an array or a similar data structure – the first If you name the previous Python code as ignoring the first one, which is the name of
element of the array, which has an index number aStrangeScriptName.py, make it executable and the script.
of 0, is usually the name of the program itself! run it, you will get the next output: However, as you saw in myWC.py, using a
You can process command line arguments in $ ./aStrangeScriptName.py 1 2 -w module such as argparse makes your life a
Python 3 as follows: All arguments: [’./aStrangeScriptName.py’, ‘1’, lot easier!

104 | Coding Made Simple


Coding Projects | Programming wc
characters = 0 The code is pretty clear – most of it deals with printing the
words = 0 desired information according to the switches given. Quick
lines = 0 The core functionality of myWC.py, which is counting tip
totalC = 0 characters, words and lines, needs less code than expected
A pipe is a handy
totalW = 0 and is implemented inside the count() function, which returns way for UNIX
totalL = 0 three values: number of characters, number of words and processes to
nFiles = 0 number of lines. communicate with
toPrint = ‘’ The rest of the stuff is handled inside the main() function. others. When a pipe
is used the output
parser = argparse.ArgumentParser() of a program
parser.add_argument("-m”, default = False, action="store_ Doing some testing becomes the input
true”, help="Counting Characters”, required=False) No program is ready for use until you extensively test it. The of another. In order
parser.add_argument("-l”, default = False, action="store_ following tests will be performed in order to make sure that to create a pipe,
you will need to
true”, help="Counting Lines”, required=False) myWC.py works as expected:
put a vertical bar
parser.add_argument("-w”, default = False, action="store_ $ ./myWC.py myWC.py on the command
true”, help="Counting Words”, required=False) $ ./myWC.py myWC.py myWC.py line between two
parser.add_argument('filenames’, default = None, $ ./myWC.py myWC.py myWC.py | ./myWC.py commands.
help="Filenames”, nargs='*') $ cat myWC.py | ./myWC.py -m -l
args = parser.parse_args() $ cat myWC.py myWC.py | ./myWC.py -l
if args.filenames == []: $ ls | ./myWC.py
(lines, words, characters) = count(None) Generally speaking, test cases can also be used for
if args.l == True: learning how to use a new command.
toPrint = ‘{:>10}’.format(lines)
if args.w == True: Doing some benchmarking
toPrint = toPrint + ‘{:>10}’.format(words) In order to have reliable benchmarks, you will need to process
if args.m == True: big text files using both wc(1) and myWC.py and find out
toPrint = toPrint + ‘{:>10}’.format(characters) which has the best performance.
if args.m == False and args.w == False and args.l ==
False: Changing the PATH variable
toPrint = ‘{:>10}’.format(lines) + ‘{:>10}’.format(words) This part of the tutorial will teach you how to create a new
+ ‘{:>8}’.format(characters) place where you can put your own Python 3 scripts and make
if toPrint != ‘': them available from anywhere on your Linux system. You will
print(toPrint) want to do this in order to be able to find and execute them
toPrint = ‘’ from anywhere on your Linux system without the need to use
else: their full path or put "./” in front of them. As the default shell
for f in args.filenames: on Linux machines is bash, this section will show how to
nFiles = nFiles + 1 change the PATH variable of the bash shell; if you use a
(lines, words, characters) = count(f) different shell you will need to make small changes to the
totalC = totalC + characters presented commands.
totalW = totalW + words First, let us check the current definition of the PATH
totalL = totalL + lines variable:
if args.l == True: $ echo $PATH
toPrint = ‘{:>10}’.format(lines) /usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
if args.w == True: So, create a directory named “bin” inside your home
toPrint = toPrint + ‘{:>10}’.format(words) directory and add its full path to the PATH variable:
if args.m == True: $ mkdir ~/bin
toPrint = toPrint + ‘{:>10}’.format(characters) $ export PATH="$HOME/bin:$PATH”
if args.m == False and args.w == False and args.l == $ echo $PATH
False: /home/mtsouk/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/
toPrint = ‘{:>10}’.format(lines) + ‘{:>10}’. games:/usr/games
format(words) + ‘{:>10}’.format(characters) Please note that the tilde character is an alias for your
if toPrint != ‘': home directory.
toPrint = toPrint + ' ' + ‘{:15}’.format(f) So, if your username is “python”, then your home directory
print(toPrint) will be most likely called /home/python, which will also be the
toPrint = ‘’ value of ~.
# Print totals Next, put aScript.py inside the bin directory and use the
if nFiles > 1: which(1) command to find it:
print('{:>10}’.format(totalL) + ‘{:>10}’.format(totalW) + $ mv aScript.py ~/bin/
‘{:>10}’.format(totalC) + ' ' + ‘{:15}’.format('total')) $ which aScript.py
/home/mtsouk/bin/aScript.py
if __name__ == ‘__main__': $ aScript.py
main() If you want to make the changes to the PATH variable
else: permanent, you should edit ~/.profile or ~/.bashrc – if you do
print("This is a standalone program not a not know how to do this, you should contact your local
module!") administrator for help. ■

Coding Made Simple | 105


MicroPython:
Coding Projects | MicroPython: Light glove

Light glove
The BBC
micro:bit is
a small and
unassuming
device, but this
tiny board can
power many
different projects
from simple
lights to powerful
robots.

M
icroPython might sound like programming Python
in a tiny font, but it is, in fact, a leaner The micro:bit hardware
implementation of Python 3 that’s been optimised Measuring just 5cm by 4cm it’s a small board, but it’s packed
for use on microcontrollers. It was originally created by with components, such as sensors in the form of an
Damien George in 2013 as a crowd-sourced project for accelerometer and compass. There’s a 5x5 single-colour LED
funding a language development, hardware testing and matrix on which we can display text or pictures and two push
development platform, which is now known as the pyboard. button inputs along with five input/output rings that can be
The original funding target was smashed many times over used with crocodile clips to connect to other components.
and the project grew to incorporate other devices, such as There is also a 20-pin edge connector that will break out all of
Quick the popular ESP8266 – the low-cost Wi-Fi chip with full TCP/ the IO ports when used with an adaptor. Powering the
tip IP stack and MCU (Micro Controller Unit) – which is now fully micro:bit is a 32-bit ARM Cortex M0 CPU with built-in
compatible with MicroPython.We’ve also seen MicroPython Bluetooth Low Energy (BLE). This CPU is nowhere near as
All of the code for
this project can make it onto the micro:bit. Early in the development of the powerful as a Pi, and it’s not meant to be, but it provides
be downloaded BBC micro:bit project, many programming languages were enough power for the platform.
from GitHub as an suggested, but Python was considered the best option largely In this tutorial, the first of a two-part look at MicroPython,
archive – https://
thanks to the growing trend for using it in education alongside we’ll get to know the hardware and software and use it to
github.com/lesp/
LXF-MicroPython/ the Raspberry Pi. The Python Software Foundation was create an interactive wearable light glove that will react to the
archive/master.zip contacted and because of its involvement, led by Nicholas movements of the wearer thanks to the accelerometer built
We have also Tollervey with development from Damien George and many into the micro:bit. We’ll also demonstrate how to use
included high members of the Python community, it’s now on micro:bit. MicroPython by creating projects that are flashed to the
resolution circuit
It makes sense to use the micro:bit for this tutorial as it’s micro:bit and can be used again and again, even without a
diagrams of the
connections made the most accessible way to start with MicroPython as the computer connected. We shall also introduce how to use
in the projects. board comes with plenty of supporting documentation and MicroPython interactively with the micro:bit hardware,
projects to gently introduce the platform. enabling ideas and logic to be tried out instantly.

106 | Coding Made Simple


Coding Projects | MicroPython: Light glove
MicroPython Boards
In this tutorial, we focused on the BBC micro:bit which is supported by micro:bit, but it still follows
for our introduction to MicroPython. But this is the standards that are required for it to be
not the only board to support the language, considered a Python language. You can read
rather there are many more alternatives: more about it at https://micropython.org.
The pyboard The original board developed in Wipy This is a MicroPython-powered board for
2013 by Damien George is a smaller Internet of Things (IoT) applications. This board
development board that shares some similarities comes with a Cortex M4 processor and a Texas
to the micro:bit, such as a 3-axis accelerometer. Instruments CC3200 MCU (Micro Controller
It also uses a STM32F405RG micro controller, Unit) for Wi-Fi connectivity. The Wipy board also
Cortex M4 CPU that’s clocked at 168MHz, and features 25 IO pins, a real time clock and hash/
has 192KiB of RAM for your projects. But what if encryption engines for SHA, MD5, DES and AES,
your project is bigger? Fear not as the pyboard which makes it a good board for IoT research
comes with a microSD card slot! Additionally, the projects. Programming the Wipy is done via a
pyboard comes with 29 IO pins. computer and use a standard text editor to write special editor called Pymakr. You can read more
There’s no dedicated MicroPython editor for your code. The version of MicroPython used with about it at https://www.pycom.io/solutions/
this board, rather you plug the board into your the pyboard is a little more complex than that py-boards/wipy1.

For this project, you’ll need quite a few bits and bobs master.zip.) Next, we create an infinite loop that will
including soldering equipment. The list includes: a USB continuously run the code: while True: . In order to turn on
battery pack and USB-to-micro USB lead, an 8-24 pixel the LED we need to supply it with power and to do that we’ll
WS2812B ‘neopixel’ ring, two crocodile clips, one LED (any turn pin 0 on with:
colour), five M4 countersunk machine screws that are 12mm pin0.write_digital(1)
length, five nuts and washers for the screws and hookup wire By using write_digital we can turn a pin on or off, just like
(solid core). a switch. We then use sleep to create a delay between turning
But our first job is to get our system ready to use the LED on and the next step which is to turn the LED off:
MicroPython, by installing the simple code editor Mu, which is sleep(1000)
designed for beginner programmers. Installing this is trivial, If this sleep were not between them, then the change
all you need to do is download the application from would happen instantly and we wouldn’t see it.
http://bit.ly/Mu4microbit then navigate to your The way sleep is defined in MicroPython is different to
Downloads folder. Right-click on the application and select Python in that sleep(1000) means to sleep for 1 second.
Properties then go to Permissions and change the Whereas typical Python code uses sleep(1) for the same
permissions so that the file can be executed as an application. effect. We now write the code that will turn Pin 0 off, which
Now you can double-click on the application and it will open turns off the power to the LED:
the Mu editor. Mu has been designed for those new to coding pin0.write_digital(0)
to just get hands on and code as quickly as possible. The Our final line of code is another sleep to create the desired
editor is rather sparse compared to others but it focuses on blink effect:
the key features: loading and saving files, flashing code onto sleep(1000)
your micro:bit and something called REPL which we shall Now click ‘Save’ and name the file blink.py followed by
investigate later. Essentially, Mu isn’t about confusing the user clicking on ‘Flash’ to upload the code to your micro:bit. In a
with pointless icons and menus. Mu is your first steps into few seconds, you will see your LED blink into life.
MicroPython, and it’s there to help you, eg both MicroPython
and Python are whitespace sensitive, which means they use REPLing down code
indentation to identify code that’s inside a loop or a function REPL is short for Read-Eval-Print Loop and is also known as a
etc. In some editors the user is forced to add that indentation shell. In REPL, we can enter commands and algorithms etc
manually, but Mu automatically indents your code for you. and the computer will evaluate the input and print the correct
The same is true with auto completion; by typing the first few
letters of an instruction, eg the name of an I/O pin, we see a
drop-down list of all potential matches, which is very handy
when writing code involving sensors and other inputs. So let’s
get started with Mu.

Are the lights on?


Our first test is to light up an LED, which we shall attach to pin
0. Using the crocodile clips, connect pin 0 of the micro:bit to
the long leg of the LED. Then connect the micro:bit’s GND pin
to the short leg of the LED. Now connect your micro:bit to
your computer using a USB lead. In the Mu editor we’ll write a
few lines of code to blink our LED. We start this code by
importing the microbit library that’s used to enable access to
the micro:bit and its many components: from microbit import
* . (Note: All the code we’ve used can be downloaded here: Mu is a simple editor which focuses on getting beginners to create cool
https://github.com/lesp/LXF-MicroPython/archive/ projects with a clear user interface and plenty of support.

Coding Made Simple | 107


Coding Projects | MicroPython: Light glove
response. How this works for MicroPython is that we can To consolidate our knowledge of MicroPython for the
have a direct ‘conversation’ with a connected micro:bit, issue micro:bit we’ll create a motion-controlled light ring that will
commands and control the board in real time. Using REPL is use accelerometer data for three axis x, y and z. This data is
remarkably simple with Mu. To start, all we need to do is taken from the micro:bit’s built-in accelerometer and then
ensure that our micro:bit is connected to our computer. used to create a mix of colours using a red, green and blue
Then click on REPL and you’ll see the bottom section of colour mix on our light ring. Officially called a WS2812B ring,
the Mu editor change and display a console interface, but it’s commonly called a ‘Neopixel ring’ with Neopixel being
typically with ‘>>>’ to indicate that it’s ready to be used. If the brand name.
there are any garbage characters on screen, click twice on
the REPL icon to reload. Running rings
Using the same circuit as we created in our previous test, Our WS2812B ring requires a little soldering. We need to
let’s turn the LED at Pin 0 on. In REPL type the following: solder three wires: one to each of the IN, VCC and GND pins.
pin0.write_digital(1) remember to press Enter to run the Give yourself plenty of spare wire as we’ll need to connect it
command. Your LED will now come to life. to your micro:bit. Strip 2cm of the sleeving from the wires so
We now turn power on to a pin and check the state of a that bare wire is shown. If you can’t solder, then now is a great
pin. In this case, we’ll supply power to pin 0 to do this, which time to learn, pop along to your local Hackspace or
can be used with external inputs, such as switches or buttons. Makerspace and someone will show you how.
For this test remove the crocodile clip from the long leg of the The wires from our WS2812B ring need to be connected
LED and attach it to the 3V pin of your micro:bit. The 3V pin to our micro:bit. The best way to do this is by using the M4
and 0 should now be directly connected with a single clip. machine screw. Slide a screw through pin 0 and, with your
In the REPL type the following to print the state of pin 0: finger, hold the screw in place and flip the board over.
pin0.read_digital() . This will report “1” , short for “True”, Now slide a nylon washer over the screw before winding the
which means that pin 0 has power, so our imaginary switch/ bare wire from our WS2812B’s In connection around the
button has been tripped. screw. At this point, try to keep the wire tight as you wind.
Speaking of buttons, the micro:bit has two, so let’s use Next, you’ll need to take an M4 nylon nut and use it to squash
one. Buttons are marked A and B, and we can check the the wire between the nut and the washer, ensuring that the
state of a button by checking if it’s currently pressed. If the wire is not touching anything else. Your wire should be held
button is held down, then REPL will respond “True”, if not then firmly in place, but don’t overtighten as it may damage the
we see “False”: board. Repeat this process for the 3V pin and GND pin. Now
button_a.is_pressed() plug in your micro:bit to your computer running Mu.
We can also check to see how many times a button has It’s now time to start the code for this project by creating a
been pressed since the micro:bit was turned on with new file in Mu. As ever in Python we need to import some
button_a.get_presses() . This should return a low number. extra libraries:
Now press the A button lots of times and repeat the previous from microbit import *
line of code and you will see the number has increased. import neopixel
Now for our last REPL exercise, we’ll try using the 5x5 LED First, we import all of the microbit library, giving us
matrix, which can be used to display scrolling text with, for access to all of the components present on the board.
example display.scroll("LXF ROOLZ") . Alternatively, we can Next, we import the neopixel library, which is used to work
use REPL to show simple images, such as a smiling face with with our WS2812B ring. Now we need to create an object
display.show(Image.HAPPY) , a cute little rabbit display. that will store the pin used to connect the WS2812B ring to
show(Image.RABBIT) or a less cuddly skull display. our micro:bit.
show(Image.SKULL) . np = neopixel.NeoPixel(pin0, 24)
With our walkthrough of REPL complete, click on the REPL In this case, pin0 is connected to the WS2812B In pin.
icon to close the shell. We now move on to our project. You’ll We also need to tell the code that we have 24 pixels in our
need to remove any crocodile clips and components from the ring. If you are using a different-sized WS2812B ring then
micro:bit in preparation for the project. count the pixels and replace 24 with your value, but 24 is
really the maximum safe limit.
We now enter into the main loop for the project, this loop
will run its contents until the power is turned off.
while True:
Inside of the loop, all of our code needs to be indented by
four spaces automatically. Our first task is to get the raw data
Our simple test for our x axis:
circuit is the first
reading_x = accelerometer.get_x()
to be made with
To do this we use accelerometer.get_x() function which
our micro:bit.
We’re using it will return a value between -1024 and 1024 and store it inside
to check that a variable.
our hardware Next, we use an if condition:
and software if reading_x < 0:
is working reading_x =
correctly before We do this to check that the value of variable reading_x
proceeding to and if it is less than zero, it will change the value to zero.
take on more We shall reveal why we do this later in the code. In order to
complex projects.

108 | Coding Made Simple


Coding Projects | MicroPython: Light glove
range, which controls how many times it iterates:
for i in range(24):
In this case, we’ve set it so that it iterates once for each
pixel in the ring, so 24 times.

Coding our colours


Inside of the for loop we create three new variables, red, green
and blue. In each variable, we will store the values of our x,y
and z axis data, which we collected and converted earlier.
red = reading_x
green = reading_y
Our WS2812B ring only requires three connections: 3V blue = reading_z
power, a Ground connection and a data connection to Pin 0. We now refer back to the np object that we created
This pin sends data to the ring to control the pixel colours. earlier in this tutorial.
np[i] = (red, green, blue)
np.show()
use reading_x with our WS2812B ring, we need to convert This object takes a positional argument, the pixel that we
the raw reading into something more palatable. wish to change and as you can see that value is [i] . In other
The accelerometer data can range from -1024 to 1024. words, it will iterate the value each time the for loop iterates,
But the WS2812B pixels only work between values of 0 and starting with 0 and ending at 23. The object also requires the
255, so if we give them a value greater than 255 this will colour data for the pixel, which we pass as a tuple containing
cause an error. So we need to divide the value of the variable the red, green and blue data. Last, in order to see the change
by 10, giving us a maximum value of 102.4, but this is a float of colour we need to tell the neopixels to show the updated
value and the neopixel function only works with integers, colour data.
so we convert the answer into an integer before storing it in With our code complete, now is the time to flash the code
the variable. Now you might be thinking “Why divide by 10, onto our micro:bit. Click on ‘Flash’ to upload the code, it
it gives a really low number?” True, it does, but it also means should take about 30 seconds to complete. Once ready your
that we are not pushing the pixels too hard, which means we micro:bit will reboot and the WS2812B ring will come to life.
have a longer battery life, and a less stressed micro:bit: Now unplug your micro:bit from the computer and attach a
reading_x = int(reading_x /10) USB battery using a USB to micro USB cable. You can also
We now repeat these steps for the y and z axis: use elastic bands to secure the battery and WS2812B to your
reading_y = accelerometer.get_y() arm. Now is the time to fling your arm around and pretend
reading_y = int(reading_y /10) that you are Iron Man! n
if reading_y < 0:
reading_y = 0
reading_z = accelerometer.get_z()
reading_z = int(reading_z /10)
if reading_z < 0:
reading_z = 0
To ensure that we can see the axis data, we print the
values of the three variables to the Python shell, which is
accessible via the REPL console while the micro:bit is
connected to your computer.
print(reading_x,reading_y,reading_z)
In order to control the WS2812B ring we need to use a for
loop, still inside of our while True loop. This for loop has a

A growing community
Single board computers and microcontrollers all activities for the festival goers is the conference can be part of the MicroPython community, all
have one thing in common—they need a badge. In recent years conference badges have you need to do is head over to http://forum.
community to keep them alive. There are many become more than “name holder”, rather they micropython.org and sign up.
boards on offer, some with huge communities, come with hackable hardware.
such as those following the Arduino and Pi. EMF Camp has a tradition of hackable badges
With MicroPython, there’s a strong and 2016 was no exception. The TiLDA mk3
community of Python enthusiasts, of which debuted in 2016 and it was powered by
there are many across the world, and whose MicroPython. But the TiLDA mk3 came with
interests also reach into the world of physical extras such as a colour LCD screen,
computing/hardware hacking. This was most accelerometer, Wi-Fi, micro SD storage, an app
evident at Electromagnetic Fields 2016, also store and crocodile clip connections. This badge
known as EMF Camp. This festival provides a was the result of months of work by a dedicated
Glastonbury-like event for those interested in MicroPython hardware hacking community and
maker activities. But one of the most common is a reflection of what can be achieved. You too

Coding Made Simple | 109


MicroPython:
Coding Projects | MicroPython: Robot wars

Robot wars
Here we show you how to use two micro:bits and some MicroPython code
to build radio-controlled robots to create your own robot battles!

W
e introduced MicroPython, in a previous tutorial interprets movement.
[see page 122], by learning how to create our own 4 Establishing radio communication from the controller to

Iron Man-inspired light glove that reacted to input, the robot.


in the form of coordinate data, taken from an accelerometer 5 Configuring the robot ‘brain’ to receives radio signals and

built into the micro:bit. For this tutorial, we shall build react accordingly.
something even better!
One of the most popular projects for beginner hardware Prepping for the project
hackers is creating a robot. We’ve seen many different For this tutorial, you’ll need to own two micro:bits (after all,
versions, typically using various models of the Raspberry Pi you need two sides to have a war), a USB battery pack, two
as the brains of the robot attached to many different motor USB-to-micro USB leads, Kitronik motor driver board and a
control boards and robot chassis. But since the release of the robot kit. You can find robot kits for a cheap price on eBay
micro:bit, we’re seeing even more robot kits and accessories and you’ll need one that includes, two motors, chassis, a pack
come to the market. Since the micro:bit doesn’t come with of four AA batteries, two wheels and a trolley caster (with
Wi-Fi and there’s no support for Bluetooth using front wheel balance).
MicroPython, how can we control a robot? The answer is that Our robot will be controlled by a micro:bit steering wheel.
we have a simple radio system in the BBC micro:bit that can This wheel will read data from the built-in accelerometer and
be used to send brief messages or data. communicate the information to another micro:bit attached
In this tutorial, we’ll introduce the following steps to to our robot. We will code all of this project in MicroPython,
building and programming a robot: using the Mu application. Released by the Python Software
1 Building a robot chassis from a kit. Foundation to enable anyone to use the leaner
2 Controlling motors using a driver control board. implementation of Python 3, MicroPython was originally
3 Making a controller unit that detects user input and created by Damien George.
Using MicroPython, two micro:bits, a motor driver board
and a cheap robot chassis we’ll take our first steps with
MicroPython robotics with the micro:bit. We covered installing
Mu, the MicroPython editor in the previous tutorial, but here
Quick is a quick reminder. Installing Mu on a Linux machine is trivial,
tip all you need to do is download the application from
All of the project https://s3-us-west-2.amazonaws.com/ardublockly-
code can be builds/microbit/linux/mu-2016-11-06_11_36_15 then
found in our
GitHub repository
navigate to your Downloads folder. Right-click on the
here: https:// application and select Properties then go to Permissions and
github.com/ change the permissions so that the file can executed as an
lesp/LXF222- application. Now you can double-click on the application and
micropython-
it will open the Mu editor.
robot/archive/
master.zip. We’ve broken the tutorial down into sections to make the
whole process easier to follow, so let’s start building a robot!

The finished
robot car is really
simple to make
thanks largely to
an off-the-shelf
chassis and a Mu is the Micro Python editor for the micro:bit. It offers a
motor driver built simple to use interface that handles code suggestions and
for the micro:bit. indentation for the user.

110 | Coding Made Simple


Coding Projects | MicroPython: Robot wars
Micro:bit Radio
For this tutorial, we used a radio link to connect import radio radio.config(power=7)
two micro:bits, which enabled strings of data to radio.config(channel=99) Transmission power ranges from -30, -20, -16,
be sent between devices. This used the default radio.on() -12, -8, -4, 0, 4dBm with each of these seven
radio settings for ease of use. But what if we So now we can change the channel from 0 to values relating to a configuration value of 0 to
wanted to create multiple robots for battle in an 100. This must be done for every micro:bit that 7 respectively.
arena? This is where channels come into play. you wish to have on a certain channel. If you would like to know more about sending
The radio class has many different If you would like your radio signal to go further, radio signals using the MicroPython then head
configuration options available to the user, but then you’ll need to increase the power of the over to an excellent official resource here:
the most basic is channel. To change the channel transmission. This is also a configuration option https://microbit-micropython.readthedocs.
of the radio we must use: and is handled with: io/en/latest/radio.html.

Our project uses two micro:bits, the ‘brains’ of the robot acknowledged:
and a controller unit used to send the commands over a radio display.show(Image.ARROW_W) Quick
connection. We shall start by coding the controller. So in Mu radio.send('left') tip
make sure you click on ‘New’ to start with a new blank Here we’ve updated the LED matrix on the controller The micro:bit
document. Also remember to save often: micro:bit to show the direction of travel. The display class can be a little
from microbit import * contains lots of images that we can show. So to illustrate that tricky to power
properly. Ideally,
import radio we are turning left we update the display to show an arrow
it’s powered via the
pointing ‘west’, which is the left-hand side of the micro:bit. JST connectors and
Coding the controller The radio function handles communicating with our robot a 3V source, but a
We first import two libraries, the entire micro:bit library, brain and it sends a string of data over the radio to our 5V USB powerbank
is also acceptable.
which gives us access to the sensors and display present on awaiting robot brain. With the string being the direction that
We used a cheap
the board, and import radio , a library that enables short we wish the robot to travel. powerbank from a
range radio communication between micro:bits. In order to But what if the gesture was right? Well, here we use an pound shop.
use the radio we first must turn it on, this must be done for else if, known as elif in Python. Elif will be checked if the first
every micro:bit that we wish to use in the project. (See also condition is False, or previous elif conditions also returned
Micro:bit Radio, above, for more information): False. We go down the elif until one returns as True. So if we
radio.on() gestured to go right then the following code is run:
We now scroll a message across the LED matrix of our elif gesture == "right":
controller micro:bit. This message advises the user on how to display.show(Image.ARROW_E)
control the robot. We also set the scrolling speed using a radio.send('right')
delay. This delay will control how quickly the matrix is We repeat this for tilting the micro:bit up and down:
updated. The default is 150ms, but we have reduced it to elif gesture == "up":
50ms as 150ms was too slow. display.show(Image.ARROW_N)
display.scroll("Turn the wheel to drive the robot",delay=50) radio.send('forward')
In order to constantly check the driver’s input, we need to elif gesture == "down":
use an infinite loop, which in MicroPython is display.show(Image.ARROW_S)
while True: radio.send('reverse')
Inside of the loop we need to determine the driver’s input. Our final elif condition to test is our emergency brake. Just
This is collected by checking the status of the accelerometer. in case we need it we can press the ‘B’ button on our micro:bit
In the previous tutorial, we gathered and used the individual to stop the robot. This only works if the board is held flat!
x,y and z co-ordinates generated by moving the micro:bit to elif button_b.was_pressed():
control our WS2812B LEDs. But for this project we can display.show(Image.SURPRISED)
simplify the accelerometer data by using ‘gestures’. The
micro:bit can determine 11 gestures, such as up, down, left,
right and shake etc. But it can also measure acceleration
forces, measured in G:
gesture = accelerometer.current_gesture()
print(gesture)
Here we create a variable called gesture and store the
current gesture. We also print the contents of our gesture Our controller
variable to the Python shell, REPL, for debugging purposes. is a micro:bit
We have the gesture stored in a variable and now we shall held in place on
test to see if the gesture matches one of those required to a DIY steering
control our robot. For this we shall use an if...elseif test: wheel using Blu-
Tack. Turning
if gesture == "left":
the micro:bit
This first test is to see if the controller has been turned
as you would
left. So we check the contents of our gesture variable against controlling a car
the hard-coded value "left" . So if the gesture is left, we need will successfully
to provide the driver with feedback to say that this has been control the robot.

Coding Made Simple | 111


Coding Projects | MicroPython: Robot wars
Here we used a namely microbit and radio. We also ensure that the radio is
USB power pack turned on ready to receive a signal:
to power our from microbit import *
micro:bit, but you import radio
can also use the radio.on()
official 3V AAA
To signify that the robot is loading and preparing for use
power pack.
we’ll create a short animation using a for loop. For loops are
used to iterate a set number of times, eg in this for loop we
will set a range of 3 which will cause the loop to iterate
three times:
for i in range(3):
What will happen inside the loop is that we shall display a
small heart on the LED matrix, wait half a second, or 500ms
using Micro Python’s sleep function, to ensure that the
image is visible to the user:
display.show(Image.HEART_SMALL)
radio.send('brakes') sleep(500)
So that is all of the code for our controller. Make sure that Then we swap the image for that of a larger heart and
you save the code to your computer. Now plug in your repeat the same sleep to create a ‘beating’ effect on the
micro:bit and click on ‘Flash’ to upload the code to your LED matrix.
micro:bit. After a few seconds, you will see the instructions display.show(Image.HEART)
scrolling across the LED matrix. Now hold the micro:bit like a sleep(500)
steering wheel and you will see an Up arrow appear, indicating
that the radio unit is sending the command forward to our Coding the robot
robot. Turn the miro:bit left and right, now turn it upside down With the robot startup code written, we now move on to
for reverse gear. Finally, hold the micro:bit flat and press B to the main loop that’s responsible for continually checking for
apply the brake. radio signals. Again, we use an infinite loop to contain the
To create a more ‘realistic’ feel for steering the robot we code necessary:
used an old circular frame, which also transports cables/ while True:
wires through the post, to create a makeshift steering wheel. Inside the loop, we create a new variable called incoming
With a few cable ties to hold the micro:bit and our USB this will store the incoming radio messages, sent by our
battery securely in place, we were ready to go for a drive. controller micro:bit.
incoming = radio.receive()
Building the robot In order to interpret and process the commands being
With the controller complete, we now move on to creating our sent over the radio, our robot needs to first understand what
robot, and our first task is to build the robot a body. Our robot to do for a specific command, and here we once again use an
uses a common robot chassis found in an online auction if...elif conditional test. We check that the value of our
house for roughly £10. There was a little soldering involved, incoming variable is the same as a hardcoded value, for
namely the terminal connections on each motor. This is a example ‘left' :
simple task but if you can’t solder or don’t have the kit, pop if incoming == ‘left':
along to your local makerspace/Raspberry Jam or LUG So if the instruction was to turn left, then we update the
meeting for help. LED matrix of our robot brain micro:bit to show the direction
The wires from your motors are connected to a Kitronik of travel. In this case, we update to show an arrow pointing
motor driver board. Each motor is connected to its own east, as when looking at the robot head-on, the arrow
terminal. Looking at our robot from the front, Motor 1 is on pointing east is also pointing in a left direction.
the left of our chassis and Motor 2 is on the right. Both of the display.show(Image.ARROW_E)
wires from one motor are connected to the two terminals for
Motor 1 on the driver board. Do the same for your second
motor ensuring that it connects to Motor 2. Also ensure that
the terminals grip the wire snugly. Now connect your AA
battery box to the power terminal, and check that you match
the polarity. Typically the AA battery box has red and black
Quick wires, where red is ‘+’ and black is ‘-’. Don’t put the batteries in
tip just yet. Now secure the battery box, motors and driver board
to your chassis using the screws in the kit or for a quick hack
There are many
use cable ties. For now, keep the robot brain micro:bit out of
different types of
motors available. the robot chassis as we need to program it.
We used standard Ensure that you are using the micro:bit intended to be the
DC motors, but you brain of our robot car. Don’t use the robot controller micro:bit
can also find cheap, that we flashed earlier. Connect your micro:bit to your
micro gear motors
that enable smaller
computer and load the Mu application. Create a new file and
robots to be built. remember to save often. We start coding the robot by Our robot car has a brain and a heart! The heart
importing the same libraries as we did for the controller, animation indicates that the robot is ready for action.

112 | Coding Made Simple


Coding Projects | MicroPython: Robot wars
Our chassis
To control the motors, we need to control the GPIO pins
has all manner
that they are connected to via the motor driver board. As you
of holes for
can see, next to the terminals on the motor driver board there
attaching
are ‘P’ numbers. These are the GPIO pins used for the components, but
terminals. To drive the motor in one direction one pin must be the motor pylons
high, and the other low. In other words, only one pin can be on can only go in
and the other must be off. To reverse the direction of the this area due
motor we need to reverse that polarity: to the careful
pin8.write_digital(0) balance needed
pin12.write_digital(1) for our robot.
pin16.write_digital(0)
pin0.write_digital(1)

Motor control
To turn the robot left we need to tell one motor to go forward,
and the other to go backwards. For our example, motor one is
the left motor (looking from the front of the robot) and it’s
connected to pins 12 and 8. Our right motor is connected to
motor two which is controlled by pins 16 and 0. So to turn the
robot left, motor one needs to go forwards and motor two
backwards. We do this by sending power to the respective
GPIO pins using write_digital .
The code to turn the motors right is a reverse of what we
set for turning left. Showing that the circuit can easily switch pin12.write_digital(1)
polarity on the fly: pin8.write_digital(0)
elif incoming == ‘right': pin16.write_digital(1)
display.show(Image.ARROW_W) pin0.write_digital(0)
pin8.write_digital(1) Here is the code for reversing our robot:
pin12.write_digital(0) elif incoming == ‘reverse':
pin16.write_digital(1) display.show(Image.ARROW_S)
pin0.write_digital(0) pin12.write_digital(0)
Here is the code for moving the robot forwards: pin8.write_digital(1)
elif incoming == ‘forward': pin16.write_digital(0)
display.show(Image.ARROW_N) pin0.write_digital(1)
Our last condition to test is our emergency brake. This will
set all of the GPIO pins connected to the motors to off:
elif incoming == ‘brakes':
display.show(Image.SURPRISED)
pin12.write_digital(0)
pin8.write_digital(0)
pin16.write_digital(0)
pin0.write_digital(0)
Save the code and click on ‘Flash’ to upload the code to
your micro:bit. Now remove the microbit from your computer
and place it in your motor driver board’s slot. Once you insert
the batteries, you should see the heartbeat animation start.
Now power up your controller; we used a USB phone battery
for ours. After the scrolling instructions, you will be able to
Motor 1 is the motor on the left of this picture, and Motor drive your robot around the room. If your robot behaves a
2 is on the right. You can also see the wires routed through little differently then you may need to swap the wires from
a space in the chassis to the motors. each motor to their motor terminals. n

Why you need a controller


In this tutorial, we used a motor driver board to heart is a DRV8833 motor controller that uses L9110S, and all of them are compatible with the
interface our micro:bit with two motors—but an H bridge or ‘flip flop’ circuit to control the micro:bit but you will need to break out more
why did we need that controller? The controller direction of the current. Remember in the GPIO pins from the micro:bit as the three
is simply there to buffer the micro:bit as motors tutorial we changed the polarity of the motors to provided aren’t enough.
require a considerable amount of current in change direction? Well, that’s the H bridge circuit You can purchase adaptors that convert the
order for them to start moving. in operation. edge connector of the micro:bit for use with
This is current that the micro:bit is unable to But do you need to buy the Kitronik kit? You breadboards and common electronics, reducing
provide without potentially damaging the unit. can make your own by buying a motor control the cost of your robot builds and enabling you to
We used a Kitronik motor driver board, but at its board, such as the DRV8833, L293D or the build multiple robots for your new army!

Coding Made Simple | 113


Coding Projects | Build an Enigma box

Python: Build
an Enigma box
We explore how to set up an authentic version of the Enigma Cipher
machine used by the German military during World War II.

Image credit: Greg Goebel, Public Domain


A four rotor Enigma machine. Different machines were used by different branches of the German military.

A
lan Turing famously said: “Some people thought we for running as an Enigma machine due to the fact it supports
were at war with the Germans. Incorrect. We were at Python and has a hardware random number generator.
war with the clock” or at least that’s what Benedict In this project, we will explore how to download the
Cumberbatch says as Alan Turing in the 2014 film, The py-enigma library to the Raspberry Pi as well as how to
Imitation Game. Regardless, Cumberbatch (as Turing) was configure the Engima machine in a way similar to the
referring to the Enigma machine which was being used by operators in World War II. We will also explore the workings of
the Germans to encode military radio messages during Enigma devices in order to understand how the Pi will encode
World War II and to date had proved near impossible for the your messages.
Allies to crack.
In technical terms, Enigma machines were known as Enigmatic myths
‘electro-mechanical rotor cipher machines’. They resembled The Enigma machine was invented sometime after World War
large typewriters and an operator would configure the I, although its inventor, German engineer Arthur Scherbius,
Quick machine according to pre-agreed settings and encode a initially saw only lacklustre interest from private companies.
tip message using the keyboard. For each letter that was With the advent of World War II, the military of several
pressed the mechanical parts would complete an electric countries started taking an interest in the machine and began
A working
replica of the circuit. The corresponding encoded letter would then light up adapting it by beefing up its security. Just as different
Turing-Welchman on the machine. Each key press shuffles at least one rotor countries adapted Enigma to their needs, different military
Bombe is at the one place forward, which means the same letter is never departments within Germany used variations of the machine
Bletchley Park
encoded the same way twice. as well.
Museum – http://
bit.ly/Turing- Thanks to programmer Brian Neal’s py-enigma library, The py-enigma library is capable of emulating the German
WelchmanBombe. it’s now possible to reproduce the machine using the ‘Heer’ and ‘Luftwaffe’ (Army and Airforce respectively)
programming language, Python. The Raspberry Pi is perfect Enigma machines, by default. It’s also capable of emulating

114 | Coding Made Simple


Coding Projects | Build an Enigma box
The key to Enigma
Py-Enigma closely matches the settings for the below text by way of example to get started:
original Enigma machine but adds the option to # My sample key settings file
choose your own ‘Umkehrwalze'(reflector). # First number represents the day of the month
These were hardwired into the original machines 29 II IV V A P J AV BS CG DL FU HZ IN KM
and usually weren’t changed in the field. For OW RX B
more information on what the reflector is and 28 IV II I C S M FA GX HL IQ KZ ME NS PR
does see http://users.telenet.be/d. TB WC B
rijmenants/en/enigmatech.htm#reflector 27 II IV V F V P PK QH RV SA UJ WO XC ZB
but for now we suggest using type ‘B’ which was DL GM B
the one used by the German Army. You can adapt the keyfile to choose different
The easiest way to store key settings is settings and/or Enigma machines. See: http://
through use of a key file. Open Terminal on your py-enigma.readthedocs.io/en/latest/keyfile.
Pi or connect via SSH and type: html for more information. Once you have
sudo nano keyfile.key pasted in the settings you need, save and exit by Copy of the keysheet used by the
This will create a blank file. You write the pressing Ctrl + X, Y, then return. Make sure that Germany Army in October 1944. Py-Enigma
settings in the format Day, columns, rotor everyone with whom you want to exchange doesn’t use the ‘Kenngruppen’, so you can
settings, letter pairings and reflector. Paste in the messages has a copy of the keyfile. ignore these if you wish.

the Kriegsmarine (Naval) Enigma, which had a more most common letters to work out which are ‘E’, ‘T’, ‘A’ etc until Quick
sophisticated design. For the purposes of this project, we are the rest of the message could be deciphered. tip
going to concentrate on the simplest implementation of The cunning of enigma was achieved through using
You can use the Pi
Enigma used by the Army and Airforce. Another common multiple rotors. Each of the rotors had notches at different
to create a truly
misconception about Enigma is that it was single-handedly points along the alphabet ring. This resulted in a different random message
cracked by the codebreakers of Bletchley Park. It was, in fact, substitution alphabet being used as the rotors turned. The key with this
initially broken by a Polish cryptographer called Marian rotor on the extreme right would move one letter forward command: sudo
cat /dev/hwrng | tr
Rejewski. He designed the first clockwork ‘bombe’ machines each time a key was pressed and the others less frequently
-dc ‘A-Z’ | fold -w 3
which were used to test various Enigma settings and crack depending on the rotor settings. Provided a message was | head -n 1
the code. This represented a huge leap forward as previously short enough, the word ‘DEUTSCHLAND’ for instance could
the Polish had to resort to perforated cardboard sheets, be encoded any number of ways in the same message
known as Zygalski sheets, to try various permutations. Turing making it near impossible to decode.
designed a number of more sophisticated versions of the Allied attempts at breaking the code were frustrated even
Polish Cipher Bureau’s bombe, which, as shown in The further by the ‘Steckerbrett’ (plugboard), which was
Imitation Game film, worked in combination with a ‘crib’, positioned at the front of the machine below the keys. Letters
which is some known text in a message (a good example were wired together in pairs through cables before the text
being the word ‘wetter’ (weather)), that can be used to was encoded. For instance, the letter ‘F’ could be paired with
decode German messages. the letter ‘J’. A ‘steckered’ (connected) pair of letters such as
these would mean each time the letter ‘F’ was pressed, the
Anatomy of Enigma signal would be diverted to the letter ‘J’ before going through
The Enigma machine used by the Army and Airforce the rotors, which would hugely increase the encryption
consisted of several parts: the keyboard, which when pressed strength of the message.
completed an electrical circuit which would light up the One final feature of the Enigma was the ‘Umkehrwalze’
encoded letter, eg when encrypting a message starting WET (reflector). This reflector could not be easily changed but, as
the operator would first press the ‘W’ key, and the ‘Z’ lamp the name suggests, made sure that the encryption and
might light up, so ‘Z’ would be the first letter of the ‘ciphertext’. decryption process were the same. This meant that two
The operator would then press ‘E’ and note down the operators who had set up their Enigmas with the same
ciphertext letter and so on. Each key press would turn at least settings could easily encode and decode each other’s
one of the rotors once. The rotors formed the core of the messages. One drawback of the reflector is that a letter
powerful code behind Enigma. Operators would place three
rotors out of a possible five on a spindle inside the machine. Monument to
Each rotor had 26 electrical contact pins on one side to Marian Rejewski
represent each of the letters of the alphabet, and the rotors in Bydgoszcz,
Poland. Note
were labelled using Roman Numerals from I to V so they were
the ornamental
easy to tell apart. When placed in an Enigma, each rotor can
Enigma machine
be set to one of 26 possible positions. This was known as the
next to him.
Ringstellung (literally the ‘ring setting') and allowed one letter
to be encoded as another.
By itself, a single rotor would offer little protection for your
message. It would be set up in such a way that, eg when you
press the letter A, it would complete a circuit so that the letter
‘T’ would light up on the Enigma. The letter ‘B’ might be ‘Q’
and so on. This is known as a simple substitution alphabet
and it would be broken very easily simply by examining the Image credit: Wojsyl, CC BY-SA 3.0

Coding Made Simple | 115


Coding Projects | Build an Enigma box
encrypted in the same way making them vulnerable to
cracking. For this reason, an operator would decide on a
‘message key’ for each message. First, the Enigma machine
would be set up exactly as outlined in the key sheet. The
operator would then choose three letters at random eg
‘DAX’ and transmit these to the receiver. The convention at
the time was to repeat the message key twice eg ‘DAXDAX’.
The operator would then change the rotor positions on
their Enigma to match the message key and send the
Image credit: RadioFan, CC BY-SA 3.0

message itself.
To decode a message, first the receiving operator would
only have to input the encoded message key into Enigma to
work out their counterpart is using the message key ‘DAX’.
They could then change the positions of their rotors and
decrypt the message itself.

Breaking enigma
Enigma rotor detail on display at the National Cryptology Museum. The
The reflector was a major Achilles heel for Enigma as no letter
internal wiring for each separate rotor eg Rotor V was the same from machine
could be encoded as itself. That meant, eg if you believed that
to machine.
the word ‘ENGLAND’ was somewhere inside a message you
could never be encoded as itself, which is a weakness the could eliminate any group of letters containing those letters.
Allies exploited. The Allies also made use of ‘cribs’, where at least some of the
Enigma operators were handed a ‘key sheet’ by an officer message was known to crack the day key, eg the Germans
containing the Enigma settings for that day. First, the choice usually transmitted a weather report around 06:00 daily
and positioning of the rotors eg IV, V and I would be listed. which followed a predictable format and would contain the
Next, would be the initial position of the rotors either as word ‘WETTER’ (weather).
letters or numbers eg ‘A F P’ or ‘1 6 16’. The Plugboard settings Certain features chosen by the Germans to increase

Image credit : Tony Sale, http://www.codesandciphers.org.uk


would follow. The Enigma machine allowed for up to 13 security actually weakened Enigma. Rotor positions were not
pairings but the Army standard was 10. allowed to be the same two days running, which meant that if
Finally, the ‘Kenngruppen’ would be listed. These were a the day key had been cracked a whole range of possible rotor
series of letters that allowed operators to identify on which positions could be eliminated. The same held true for
particular day the message was sent. This is one area where
the py-enigma library on the Pi diverges from the original
Enigma machine as its key sheets simply place the numbered
day of the month at the start. (See The Key to Enigma box, on
the previous page, for more information.)
The Germans quickly realised that if thousands of Example of a daily key sheet. For security reasons,
messages were sent every day using the same settings then Officers would often tear a strip off the sheet to give
eventually the rotors would all revolve fully and see messages Operators the settings for that day only.

Enigma encryption
To encode messages you’ll first need to navigate $ sudo python pyenigma.py --key-file /home/pi/ $ sudo python pyenigma.py --key-file /home/pi/
to where the handy enigma command line keyfile.key --start='APJ' --day=29 keyfile.key --start='UVX' --day=29
program is stored. Connect via SSH or open --text='UVXUVX' --text='HPZXUWHMICMHUFCXOTU'
Terminal on the Pi and use the cd command to This gives the text output ‘QMMZIY’. This decodes to the original message, which
do this eg $ cd /home/pi/bgneal-enigma- Next use the message key to change the is a phrase worthy of the cheesiest of spy novels
f3af458a5d2d . starting position of the rotors and encrypt the ‘Meet me at Midnight’.
Next, examine your key sheet and determine actual message, for instance:
which day’s settings you want to use. Decide on $ sudo python pyenigma.py --key-file /home/pi/
three random letters to use as the message key. keyfile.key --start='UVX' --day=29 --text='MEET
Image credit: Matt Crypto, CC BY-SA 3.0

You’ll next run a command to encrypt the ME AT MIDNIGHT'


message key. Leave the rotors in the same This gives the text output of:
starting position as in your keyfile for now: ‘HPZXUWHMICMHUFCXOTU’
$ sudo python pyenigma.py --key-file Decryption works using the same procedure
yourkeyfilename --start='ABC' in reverse. First set Enigma to the day’s key
--day=DAYOFMONTH --text='MESSAGE KEY settings to obtain the message key:
TEXT' $ sudo python pyenigma.py --key-file /home/pi/
For instance, if it’s the 29th day of the month, keyfile.key --start='APJ' --day=29
the initial rotor positions in your keyfile are ‘APJ’ --text='QMMZIY'
and you want to use the message key ‘UVX’ you Next, use the message key ‘UVX’ to decrypt Cables connected letters on the plugboard.
would write: the actual message: Here A is paired with O and Y with J.

116 | Coding Made Simple


Coding Projects | Build an Enigma box
plugboard settings. Despite the wisdom of using a message
key, German operators would sometimes become quite lazy
and repeat keys or use keys grouped together on a keyboard.
Indeed, the name for these ‘cillies’ may have come from the
predictable day key ‘CIL’.
Aware of these shortcomings the German ‘Kriegsmarine’
increased the strength of Enigma by adding three more rotors
for a total of eight. It also avoided sending predictable
messages so the German Naval Enigma remained largely

Image credit: Antoine Taveneaux, CC BY-SA 3.0.


impenetrable throughout the war. Submarine commanders
were also given Enigma code books printed with red ink on
paper that dissolved easily in water to prevent capture.
Ian Fleming, who gathered information for his James Bond
novels while stationed at Bletchley, ventured a plan to capture
Naval Enigma books which would do even 007 proud. His
suggestion was to disguise some British commandos as
downed German airmen and have them float around in the
middle of the Channel on a captured fighter plane looking A replica of the Turing-Welchman Bombe at the Bletchley Park Museum.
helpless. Fleming believed a German U-Boat would inevitably The bombe could try thousands of rotor positions per hour, which made
surface to assist their supposed countrymen at which point cracking Enigma much easier than doing it by hand.
the Commandos would pop the hatch and raid the sub. The
plan was shelved indefinitely for being too risky but does give Enigma during World War II should be reason enough not to
some insight into how valuable Enigma intelligence was. rely on it to store any truly private information. For a more
Due to the National Secrets Act, the incredible in-depth history of how the Allies cracked Enigma, visit the
achievements of the code breakers of Bletchley Park went Bletchley Park website at http://www.bletchleypark.org.
unrecognised until the Seventies. The British Government uk/content/hist/worldwartwo/enigma.rhtm. For more
took advantage of this after World War Two by selling Enigma information on py-enigma specifically or if you wish to
machines to its former overseas colonies and happily congratulate Brian on his masterpiece of coding, visit
decoded messages for decades. http://py-enigma.readthedocs.io/en/latest.
Neal hasn’t rested on his laurels but has taken the time to
Enigmatic issues compile a Python library for two other cipher machines. The
As the py-enigma software can easily be run from the first is the M-209 which is a Cipher Machine employed by the
command line there are few ways that this project can go US Military during World War II. (See https://bitbucket.org/
wrong. As we’ve previously discussed, there were several bgneal/m209/ to download the library.) Neal has also
different types of Enigma machines so if you want to created a library for the PURPLE Machine, which was used by
exchange messages, it’s important that you decide to use the the Japanese Foreign Office before and during World War II.
same kind. The military M3 (three-rotor) machine is perhaps (See https://bitbucket.org/bgneal/purple for more
the most well known and easiest to use. While this is an information.) Enigma, M-209 and Purple can happily co-exist
excellent project to do for fun, the fact that the Allies broke on the Raspberry Pi, so feel free to have fun with all three. n

Set up your Engima machine

1 Download Py-Enigma 2 Prepare keyfiles 3 Encrypt & decrypt


Open Terminal or connect via SSH and run Use either a specialised website or make up Once you have either your plain text message
this command to download the library: your own settings for the rotors and ready to send or have received an encrypted
$ wget https://bitbucket.org/bgneal/enigma/ plugboard. This would also be a good time to message, the steps are the same. (Follow the
get/f3af458a5d2d.zip decide on the kind of Enigma machine you steps that are outlined in the Enigma
Alternatively, use your Pi’s web browser to want to mimic (three-rotor, four-rotor etc) Encryption box, left, to encode or decode
download the file. Next, unzip the file by Once you’ve generated enough keys make messages.) For extra security, you may want
running $ unzip f3af458a5d2d.zip and use sure to provide a paper copy to everyone with to try doing as the Germans did and use
$ cd bgneal-enigma-f3af458a5d2d to be whom you want to exchange messages. (See the ‘day key’ to encode the key for each
taken into the newly extracted folder. The Key to Enigma, on the previous spread.) message separately.

Coding Made Simple | 117


UPS: Power
Coding Projects | UPS: Power loss protection

loss protection
Nick Peers reveals how to set up and configure a simple UPS add-on to
provide your Pi with emergency battery power, should the lights go out.

Y
our Raspberry Pi is particularly sensitive to power A less-powerful option, but one that can still provide over
Quick outages. Added to the inconvenience of suddenly an hour of emergency power, is the PiZ-UpTime. This costs
tip losing access to your Pi or half an hour’s work, there’s £28 plus UK shipping from www.robotshop.com/uk and is
The instructions for the possibility your shutdown will corrupt your microSD card, the unit we used in this tutorial. Although optimised for the
downloading and forcing you to wipe it and start again from scratch. Pi Zero, it will work with the Pi 2 and Pi 3 too, albeit for a
using the Python This is where a battery rides to the rescue. It provides your shorter period than the Pi-UptimeUPS, which can deliver
scripts can be
Pi with an independent source of power when the main over 10 hours via its two batteries.
found at http://
bit.ly/python-ups. supply is interrupted, whether through a power cut, tripped Both models come as a single circuit board with a battery
For more FAQs, visit MCB or simply by accidentally yanking out the power cable. holder. They can both be connected to your Pi via its GPIO
http://alchemy- While it’s possible to jury rig your own battery supply, why go pins (Pi Zero users will need to solder or add these
power.com/faq. to all that trouble when a ready-made uninterruptible power themselves), and both offer pass-through pins so you can use
supply (UPS) is waiting for you? them in conjunction with other add-ons, secure in the
knowledge they’ve been designed to supply power to both
Your own Pi UPS your Pi and any add-ons in the event of power failure.
The solution comes from the folk at Alchemy Power, who Of course, it’s not always practical or desirable to fit GPIO
have developed two UPSes for Pi and Pi Zero users. Its main pins to your Pi Zero, which is where the PiZ-UpTime scores
solution is the Pi-UpTimeUPS, which works with any Pi that points. Not only can it be plugged into a GPIO pin header, but it
has a 40-pin GPIO header, including the Pi Zero. Its form can be connected relay-style between your power supply and
factor is aimed at the Pi, however, and comes with a hefty the Pi Zero itself using a micro USB cable (supplied).
price tag: £43 per unit, plus a one-time shopping cost of £16
from the US via distributor Farnell (http://uk.farnell.com). Physical installation
Power down your Pi, unplug the power supply and then fit the
UPS board to your Pi, either via the GPIO pin header or – in
the case of the PiZ-UpTime where you’re not using the GPIO
header – by unplugging the power from the Pi Zero and
connecting the PiZ-UpTime to the Pi Zero’s power socket
using the supplied cable.
While plugging
Once done, connect the battery – these tend to be
your PiZ-Uptime
supplied with some level of charge, so the moment you install
into your Pi’s
GPIO pins is the
it, your Pi will leap into life. Be sure to shut down safely from
best way to use here – ssh into your Pi if necessary and issue the following:
it, you can also $ sudo shutdown -h now
connect it via the Now connect your Pi’s power supply to the ‘In’ port on the
Pi’s power port. Pi-UpTimeUPS or PiZ-UpTime so it can start charging the

Source the right battery


Batteries aren’t supplied, and it’s crucial you use In contrast, the PiZ-UpTime uses just a single your Pi (and any connected add-ons) will be
the correct ones. The Pi-UpTimeUPS uses 18650 14,500 Li-ion battery – capacity 700mAh to able to run on battery power – we got well over
non-protected batteries. There’s room for two, 2,000mAh. Don’t be fooled by their appearance an hour out of an 800mAh Xtar-branded battery
but you can get by with just one. Recommended – they may look like regular AA batteries but that we purchased on eBay (£9 for two).
capacities are 2,000-3,500mAh per battery. In they’re not, so don’t be tempted to use standard It’s worth noting that the unit will perform a
return, the UPS can deliver both 5V power via a batteries. Both types are available from a range hard shutdown when the battery’s capacity runs
micro USB port (using pin 2) and 3.3V (700mA) of sources, including eBay, Amazon and Maplin. dangerously low, thus prioritising the battery’s
of power via the Pi-UpTimeUPS itself. Remember, the higher the capacity, the longer health over a few extra seconds of power.

118 | Coding Made Simple


Coding Projects | UPS: Power loss protection
Understand the LEDs
The PiZ-Uptime and Pi-UptimeUPS comes with charged. When charging is complete, the yellow
multiple LEDs to help you fathom what’s going on. LED lights up instead.
There’s an orange LED that indicates the battery It’s possible to disable these LEDs using a jumper
level. This starts off practically invisible, but glows on the board, which can save you a bit more power.
brighter as the battery level drops to provide you Of course, this might be practical if you’ve
with an early warning system. You’ll also find a connected the board via the GPIO pins and have
small red LED that lights up after the hardware the shutdown scripts in place. If you’re forced to
reset switch has been pushed to indicate the connect the PiZ-Uptime to your Pi using the
power reboot sequence. supplied micro USB cable, you’ll need to shut down
Three more LEDs can be found along the side of the Pi Zero manually in the event of power failure,
the hardware. The blue LED will light up when which might be an issue if – for example – you
running on battery to indicate low battery (under suffer a power cut and you have no network access.
3V of power). The green LED indicates mains power Thankfully, choose a reasonable battery and you’ll The LEDs on the PiZ-Uptime give
is connected – when it is, the blue LED switches have plenty of time to get things running again you information on power level, the
function to indicate that the battery is being before panic need set in. charging state and more.

battery as well as provide emergency power when required. # print(“Time is %s “ % (time.ctime()))


This follows the standard CCCV charging method except If you want to skip the two-minute warning when battery
when the battery has been depleted, in which case low- levels run low, change the subprocess.call line to the following:
current charging is first used to bring the battery up to a level subprocess.call(“shutdown -h now &”, shell=True)
where it can be safely CCCV charged. Save any changes and exit. Now test the script:
As you’d expect, the board has onboard circuitry to $ sudo python GPIO-shutdown-sample.py
prevent both overcharging of the battery as well as deep Disconnect power from the Pi, which should continue to
discharging – a hard shutdown is performed before the latter run from the UPS battery. The time should be displayed every
can occur. There’s also a temperature monitor that can shut 10 seconds and when the battery below a certain level, you’ll
down the charging process if it becomes too hot. Note the be informed the Pi will be shutting down in two minutes (or
reset button on the front or side of the board. Use this after a immediately if you decided to skip the delay). In our tests, our
controlled shutdown to restart your Pi without first having to Pi Zero with external Wi-Fi adaptor ran for up to an hour before
unplug the power or disconnect the battery. shutting down – ample time for getting the power back up.
The battery level is monitored on GPIO pin 26 – a jumper
on the board can be set to disable this if the pin is already in Permanent protection
use elsewhere. However, if you want to be able to perform a The above script must be run manually on every boot – for
controlled shutdown when the battery level is low, you’ll need permanent, automatic protection reconnect your power and
this pin connected. This is the biggest drawback of the PiZ- move on to the final stage. The GPIO-crontab script is
Uptime’s USB connection option, because it can’t provide this required to ensure the GPIO pins are tracked and a controlled
functionality unless connected via the GPIO pins. Instead, shutdown is performed once the battery falls below the
make use of the LEDs to keep an eye on things (see the box). accepted threshold. Set it up thus:
To make use of the shutdown scripts, first update the $ sudo cp ~/ups/GPIO-crontab.txt /usr/local/bin/uptime-gpio.
underlying OS powering your Pi, typically like so: py
$ sudo apt-get update $ sudo chmod 755 /usr/local/bin/uptime-gpio.py
$ sudo apt-get upgrade && sudo apt-get autoclean $ sudo crontab -e
Next, create a folder and download the required files: Choose your editor if prompted, then add the following
$ mkdir ups line to have the script run silently once every two minutes
$ cd ups (change */2 to */1 to run it every minute):
$ wget http://alchemy-power.com/wp-content/ */2 * * * * python /usr/local/bin/uptime-gpio.py
uploads/2017/06/GPIO-shutdown-sample.zip Save the cron file, exit and reboot. Now test the battery
$ wget http://alchemy-power.com/wp-content/ again – this time, two minutes after the low-battery warning is
uploads/2017/08/GPIO-crontab.zip reached, your Pi should automatically shut itself down.
Next, unzip the two Python scripts: Congratulations, you’ve just ensured your Pi will never again
$ unzip GPIO-shutdown-sample.zip && unzip GPIO-crontab. suffer due to a sudden power outage!
zip
When the first script is run, it will sleep for 10 seconds
before checking the battery levels again. If the battery levels
are low, it will trigger a controlled shutdown within two
minutes. You can see how the script works by examining it in
nano, where a explanation accompanies each command:
A pair of scripts
$ nano GPIO-shutdown-sample.py
are provided for
If you want to lengthen the battery level check, you’ll need
making use of the
to change the ‘schlaf’ value as shown in the script. The script PiZ-Uptime’s ability
will also display a time stamp on-screen every time it wakes to monitor battery
to check the battery level. You can disable this by usage via the GPIO
commenting out line 78 as follows: header.

Coding Made Simple | 119


Coding Projects | Using Python 3 modules

Practical Python
3 modules
We explain everything you need to know to start using the three most
practical Python 3 modules.

T
his tutorial will present you the most important execution of the chmod command:
Python 3 modules using small yet fully working code $ ls -l makeMeExecutable.py
examples. These three modules are os and sys, which -rw-r--r-- 1 mtsouk mtsouk 49 Oct 12 20:38
help you write system tools, and tkinter which helps you makeMeExecutable.py
develop graphical user interfaces. $ chmod 755 makeMeExecutable.py
Even if you are not familiar with Python 3, you will learn $ ls -l makeMeExecutable.py
many tips and tricks about how to take advantage of the -rwxr-xr-x 1 mtsouk mtsouk 49 Oct 12 20:38
capabilities of Python 3 in order to create useful scripts using makeMeExecutable.py
fewer lines of code than you would expect. If you do not completely understand Linux file permissions
Without further ado, lets get started! keep reading this book as we will talk about them in more
detail later on. For the moment, you can learn more about the
Quick Making a Python 3 script executable chmod(1) command by visiting its manual page:
tip There are various ways to execute your Python 3 code $ man 1 chmod
There exist many including autonomous scripts or by using the Python 3 So, unless there are any syntax errors inside
good books that interpreter. You can get into the Python interpreter by makeMeExecutable.py, you are ready to execute it:
can help you learn executing the Python 3 binary without any command $ ./makeMeExecutable.py
Python 3 including
line parameters: Hello Python 3!
“Programming
Python, 4th edition”, $ python3 The reason for executing using ./ in front of the
“Python Cookbook, Python 3.4.2 (default, Oct 8 2014, 10:45:20) command has to do with the definition of the PATH
3rd edition” and [GCC 4.9.1] on linux environment variable, which will also be explained later on.
“Learning Python,
Type “help”, “copyright”, “credits” or “license” for more The same tutorial will teach you how to group your own
5th edition”. You can
start with “Learning information. Python 3 scripts and make them available from anywhere on
Python”, continue >>> print("Hello Python 3!") your Linux system.
with “Programming Hello Python 3! Now, you are able to turn any Python 3 code into an
Python” and Although the Python interpreter is the perfect place to try autonomous program!
then get “Python
new things and learn new commands, it is not the most
Cookbook”,
which is for more efficient way to execute Python code! The best way to About Python 3 standard modules
experienced Python execute Python 3 code is by creating autonomous scripts All versions of Python come with a plethora of modules
3 developers. that can run as if they were regular Linux commands, such as that help you write useful programs without having to start
ls, wc, awk and grep. This section will illustrate how to turn the from scratch, using code that has been tested for you in
following Python 3 code into an autonomous Python 3 script: advance! You can find the full list of modules included in the
print("Hello Python 3!") Python 3 standard library by visiting https://docs.python.
Imagine that you have the previous single line code saved org/3/library.
as makeMeExecutable.py. The first thing that you will need to Essentially, the two most important and useful Python 3
do is put the following line in front of everything else in modules are os and sys. It is highly unlikely that you can write
makeMeExecutable.py: a useful Python 3 script without using at least one of them.
#!/usr/bin/env python3
The /usr/bin/env utility adds some useful things to your Finding documentation
Linux environment before executing the python3 binary. Next, Python 3 offers a very rich documentation system both on
you will need to use the chmod command to change the file the web, which is usually more accurate and up to date, and
permissions of makeMeExecutable.py and make it an on your Linux machine. This section will talk about the
executable file. The following output shows the file pydoc3 tool, which is the Python documentation tool, as well
permissions of makeMeExecutable.py before and after the as the help() command that can be executed in the Python 3

120 | Coding Made Simple


Coding Projects | Using Python 3 modules
interpreter. First, let us try and get more information about
the sys module:
$ pydoc3 sys
The image on page 138 shows a small part from the
output of the previous command. If the module cannot be
found, you will get an error message similar to the following:
$ pydoc3 doesNoExist
No Python documentation found for ‘doesNoExist’.
Use help() to get the interactive help utility.
Use help(str) for help on the str class.
Additionally, you can find information about a specific
method, which in this case is the open() method from the os
module, as follows:
$ pydoc3 os.open
If you are inside the Python 3 interpreter and want to find
out how the print() function works, you can do the following:
>>> help(print)
You can also get the exact same information with the
pydoc3 utility.
Last, there is a way of listing the properties and the
methods that a module exports, which is also useful for
remembering method names:
>>> import sys
>>> dir(sys)
['__displayhook__’, ‘__doc__’, ‘__excepthook__’, ‘__
interactivehook__’,
...
‘stdout’, ‘thread_info’, ‘version’, ‘version_info’, ‘warnoptions']
Please note that the previous output is a Python list. Now
it is time to learn the last trick related to documentation. You
can access the documentation of a module under a property
named __doc__, which can be seen in the previous list:
>>> print(sys.__doc__) This is a small part of the web page that lists all Python 3 modules that are
included in the Python Standard Library – it is good to make yourself familiar
This module provides access to some objects used or
with the contents of this page.
maintained by the
interpreter and to functions that interact strongly with the print them on the standard output. Programs that run on
interpreter. UNIX systems, including Linux, usually have three “files” open
... all the time, which are called standard input, standard
Each time you want to learn how a method works, output and standard error – though one exception to this
remember the parameters of a method, or just find more rule are server processes. The first one is used for getting
information about a particular module, you should visit input, the second for printing output and the last one for
its documentation. printing error messages. As everything on UNIX systems is a
file, it is not strange that even standard input, output and
Developing the cat utility in Python 3 error information can be handled as files when needed. So,
This section will use the things you already know to develop a when you execute the print() command in Python 3, its
Python version of the cat utility, which concatenates files and output is automatically printed on standard output –
however, as you will see in a while, there are some alternatives Quick
to the print() command, especially when dealing with files. tip
Enough with the theory, it is time to see the When you want
implementation of the cat utility, saved as myCat.py: to make a simple
#!/usr/bin/env python3 script to learn how
to use a module,
do not name your
import sys
own script after the
import os name of the Python
module you want
for filename in sys.argv[1:]: to learn because
with open(filename, ‘rb') as infile: this will perplex
Python when it
for line in infile: tries to execute the
sys.stdout.buffer.write(line) “import” command
The most important thing in this program is the open() – Python 3 will
statement. The first argument of open() is the name of the try to import your
This image shows a naive graphical application that
script instead of the
just draws a line on the screen without allowing the user file you want to read. The second argument, which is the ‘rb’
desired module!
to interact with it. string, tells Python 3 to open the file for reading only ('r')

Coding Made Simple | 121


Coding Projects | Using Python 3 modules

using the binary format ('b'). Opening a file for writing is done
using ‘w’ instead of ‘r’ but there is a very important point here:
if you try to open an existing file for writing, Python will first
erase the file before you can start writing to it, so be
extremely careful. As not all files are plain text files, opening a
file in binary format is considered a safer approach.
Additionally, myCat.py uses sys.stdout.buffer.write() instead
of print() for writing text on the screen, which is a better way
of doing things. Without going into too much detail, using sys.
stdout is better because you have more power on where the
output is going to be displayed. Nevertheless, most of the
time using print() in enough.
This version of cat accepts multiple command line
arguments and processes them one by one using a for loop.
Although myCat.py is not a complete implementation of
cat(1), it does a pretty good job! As you can see, you can do
great things and create useful system tools, which are
programs that deal with the Linux system itself, even with the
simplest Python 3 code. The image on page 139 shows the
myCat.py utility in action which, as you can see, can also
process itself!
You will see more Python 3 code related to file input and
output in other tutorials in this section of the book.

The tkinter module


The tkinter module along with its various components is the
definitive Python 3 module from creating graphical user
interfaces. So, each time you want to develop a graphical user
interface in Python 3 you should consider tkinter.
The functionality of tkinter comes in the form of Widgets,
which are Python 3 classes with the options and the methods
that help you configure them and allow them to do useful
things according to their functionality and purpose.
The Canvas widget helps you draw things, the Entry
widget allows you to get user input, the ScrolledText widget
This image shows a small part from the output of the “pydoc3 sys” command, helps you deal with large amounts of text and the
which returns the documentation of the sys module. Checkbutton widget is used for turning on and off
selections. The following Python 3 code, saved as dummyGUI.
py, creates a dummy GUI in order to illustrate the use of the
tkinter module:
#!/usr/bin/env python3

from tkinter import *


root = Tk()
c = Canvas(root, width=800, height=500)
c.pack()
c.create_line(100, 100, 500, 500, width = 3)
root.mainloop()
As you can see, you need to define the size of the window
that is going to be created in pixels before doing any drawing
– in this particular case the create_line() method does the
drawing. The root.mainloop() method starts the tkinter event
loop, which means that the script starts displaying things and
accepting user and system events including information
about the position of the mouse and the various keys that
you press on the keyboard. Even if dummyGUI.py does not
handle any events, the events are still there; they are just
being ignored. Executing dummyGUI.py generates output
similar to that at the top of this page.
The next script, saved as aGui.py, creates something
more useful:
This figure shows the output of the aGui.py script, which gets two integers #!/usr/bin/env python3
from the use, adds them and displays the result on the screen.

122 | Coding Made Simple


Coding Projects | Using Python 3 modules
Where does Python 3 look for modules?
The sys.path variable, which is a list of ‘/usr/lib/python3/dist-packages'] >>> import notInThePath
strings, holds the search path that Traceback (most recent call last):
Python 3 uses for finding a module in Python 3 stops searching for a File “<stdin>”, line 1, in <module>
order to import it: module in two cases: as soon as it finds ImportError: No module named
>>> import sys it in the aforementioned list of strings or ‘notInThePath’ Generally speaking,
>>> print(sys.path) when all the strings in the lists are Python 3 error messages are very
['’, ‘/usr/lib/python3.4’, searched without success. In the first informative and up to the point so you
‘/usr/lib/python3.4/plat-x86_64-linux- case, the desired module is loaded should get used to reading them
gnu’, without any other message whereas in because most of the times they
‘/usr/lib/python3.4/lib-dynload’, the second case an error message is reveal the problem and help you find
‘/usr/local/lib/python3.4/dist-packages’, printed on your screen: the solution. Quick
tip
Learning how to
program cannot be
from tkinter import * Although the process of developing many small scripts learnt by reading
might look slow, it is considered a good practice to learn how tutorials – tutorials
are a good starting
def callback(): a Python module operates using small examples to make point but after that,
sum = int1.get() + int2.get() sure that you understand what you are doing. you will need to try
result.config(text=sum) When you become more experienced, you might go a little and write your own
faster but the general learning process remains the same! programs, which
will be simple at
root = Tk() Depending on what you want to develop, the presented
first but will get
c = Canvas(root, width=400, height=200) modules might not be suitable for your task, which means more complex
c.pack() that you will have to look at the other standard Python 3 with time.
modules for help. ■
# Two Scale Widgets
int1 = Scale(root, from_=0, to=100, orient=HORIZONTAL)
int1.set(40)
int1.pack()
int2 = Scale(root, from_=0, to=100, orient=HORIZONTAL)
int2.set(10)
int2.pack()

# The Add button


b = Button(root, text="Add”, command=callback)
b.pack()
# This shows the result
result = Label(root, text=”.“)
result.pack()

root.mainloop()
What aGui.py does is allow you to enter two integers, add
them and display the result on the screen, which is pretty
impressive for such a small amount of Python 3 code!
The general structure of aGui.py is similar to the structure
of dummyGUI.py. However, aGui.py uses a few widgets. The
reason for using two Scale widgets for getting user input is
that you do not want the user to be able to enter invalid input,
as the Scale widget makes sure that you will get the kind of
input you want. However, please note that the value of the
Scale widget is automatically updated as you move the bar.
After entering the two integers, you will have to press the
“Add” button, which calls a function named callback() that
does two jobs: the first one is to add the two integers and the
second one is to present the result on your screen using a
Label widget. When you define the Label widget, you also
define a variable that holds its text – in this case the name of
the variable is “text”, which is used inside the callback() This Figure shows the myCat.py script in action. The script can also process
function to update the text of the Label. itself but it will fail when you ask it to process a file that does not exist!

Coding Made Simple | 123


Coding Projects | Money app

Tkinter: Build
a money app
Discover everything you need to know to start managing your money with
Python 3 and build an app to look after the pounds…

T
his tutorial will teach you how to develop a relatively myData[key] = val
simple application with a graphical user interface that You will need to import the csv package in order to use csv.
keeps track of your money on a monthly basis. The writer() or csv.reader().
application will allow you to insert new data but it will not There exist alternative ways to load and save data such as
allow you to delete old data. Although the idea is simple, the using XML format or using a database such as SQLite;
created script is pretty useful and handy and will be however, the plain text file has many advantages including the
developed using Tkinter, which is the most popular Python 3 fact that you can easily see and make changes to its contents.
module for programming GUIs. The first time you start the application, the text file with
The entire program should use a single variable for the data will be created using the following code:
keeping track of your money. The variable must be able to try:
hold the data for every month of each supported year. As aFile = open(dataFile)
always, use the simplest data structure that does your job, in aFile.close()
this case this is a dictionary. The Python 3 code for the loadData()
definition of the variable, which is called myData, is: except IOError:
# The variable that holds the data for k in Years:
myData = {} for m in Months:
In other words, you just create an empty dictionary. The print(k+m)
data is saved on disk in CSV format, which is directly related myData[k+m] = 0
to the format of the dictionary data structure. The keys of the saveData()
dictionary will look like the following: This code presents a pretty clever use of exception
2016Nov handling where the script performs the appropriate action
2016Jul depending on the result of the open() call in the try block. If
2016Sep the open() call fails, which means that the data file is not there,
Currently, the application supports the years of 2015 and you will initialise the contents of myDate and call the function
2016 only, as defined in the Years variable, just change the that saves the data on disk in order to create the file. If the file
definition of Years to add support for more years. You can add is there, the loadData() function is called.
more years without changing any Python code.

Saving and loading data


The app would be incomplete without a way to save and load
existing data. The following function, named saveData(), saves
the contents of myData on disk in CSV format:
def saveData():
w = csv.writer(open(dataFile, ‘w’))
for key, val in myData.items():
w.writerow([key, val])
The format of the data file is similar to the following:
$ head finances.txt
2015May,100
2016Nov,-50
$ wc finances.txt
24 24 268 finances.txt
The next Python 3 function, named loadData(), reads the
previously created CSV text file and stores its data to the
myData variable:
def loadData(): Figure 1: The initial screen of the application, which is
for key, val in csv.reader(open(dataFile)): pretty simple and easily used by average users.

124 | Coding Made Simple


Coding Projects | Money app
Demystifying Tkinter
Tkinter is a great toolkit for creating graphical Tkinter is beautifully integrated with Python 3 library. Behind the scenes an event loop is
user interfaces so it is time to learn more about with the help of a software layer that is on top of running that watches for events to happen
how it works. Tkinter is a standard Python 3 Tk‚ this layer lets Python code use Tk for building in order to call the appropriate registered
module, so scripts written in Tkinter work a user interface while allowing Python to handle callback handlers.
immediately on most Python 3 installations, that user events. So GUI calls go from Python to Although Tk is not object oriented, the tkinter
uses the Tk library and offers powerful ready to Tkinter to Tk, whereas GUI events go the other layer exports the API of Tk as Python classes
use Widgets that can help you perform many way around! because Python is object oriented!
tasks by writing small amounts of code. Please Tkinter is a combination of Python code and The good thing is that Python developers do
note that the Tk library is also used by Perl and C code. The C code implements an extension not need to learn too many new things to use
the Tcl programming language. module named _tkinter, which talks to the Tk Tkinter, so get going!

Nevertheless, you can still copy and paste its text. The
Python code that creates the user interface is the following: Quick
root = Tk() tip
root.title(‘My Financials’) The Frame Widget
c = Canvas(root, width=1000, height=1000) Tkinter offers the
c.pack() Frame Widget,
which is a
rectangular region
selectYear = StringVar() on the screen, that
selectYear.set(‘2016’) can help you group
yearsMenu = OptionMenu(root, selectYear, *Years) other widgets and
yearsMenu.pack() place them on
screen according to
selectMonth = StringVar()
your wills. Its use is
selectMonth.set(‘Sep’) more complicated
monthsMenu = OptionMenu(root, selectMonth, *Months) than the Grid
monthsMenu.pack() Manager.

amount = Entry(root)
amount.pack()

text = Text(c, borderwidth=10, background=’lightgray’)


text.pack(side=RIGHT, expand=True)

Figure 2: To enter new data you need to select the desired


quitButton = Button(root, text=”Quit!”,
year and month, then write the amount in the Entry Widget.
Last, you need to press the “Insert Data” button. command=closeWindow)
quitButton.pack()
Now that we have the two functions, we are ready to inputButton = Button(root, text=”Insert Data”,
proceed with the design of the graphical interface. The name command=insertData)
of the file with the Python code will be myFinancials.py. inputButton.pack()
displayData = Button(root, text=”Print Totals”,
The User Interface command=displayData)
You will need three buttons: one for quitting the application, displayData.pack()
one for inserting new data and the last one for displaying
summary information. Additionally you will need three input mainloop()
Widgets: one for selecting the year, one for selecting the There is a subtle point here, which is related to the
month and the last one for selecting the amount of money. If OptionMenu Widget. When you define an OptionMenu Widget
the amount is negative, then it is considered an expense, you also declare a variable that is going to be used for
otherwise it is an income. For getting the amount of money accessing this particular OptionMenu Widget. So,
you will need an Entry Widget. myFinancials.py has two such variables named selectYear
The list of supported years and the list with the names of and selectMonth, which are first used for defining the default
the twelve months are hard coded in the Python 3 code. Two value of the OptionMenu Widget using the set() method. The
OptionMenu Widgets will be used for selecting the desired insertData() function also uses the get() method of selectYear
year and the desired month in order to avoid silly mistakes and selectMonth in order to get their current value. Figure 1
during input; both OptionMenu Widgets are created using the (left) shows the initial screen of the application, which is as
data from the two hard coded lists, named Years and Months. simple as possible.
Last, you will need a Text Widget for displaying the
summary information, the good thing is that the Text Widget Functionality
allows you to edit, copy or paste its text. If you want to turn off Now we’ll add the code that works the callback functions of
the editing capabilities of a Text Widget you should do the the three Button Widgets. The following is the Python 3 code
following after creating it: of the insertData() function:
aTextWidget = Text(root) def insertData():
aTextWidget.configure(state=’disabled’) text.delete(‘1.0’, END)

Coding Made Simple | 125


Coding Projects | Money app
myAmount = amount.get() As you can see, before exiting, you make an additional call
print(myAmount) to the saveData() function. As you do not have lots of data, the
yearTemp = selectYear.get() cost of calling saveData() too often is insignificant.
print(‘Year: ‘, yearTemp)
monthTemp = selectMonth.get() Using the application
Quick print(‘Month: ‘, monthTemp) The app is easy to use, the difficult part is the management of
tip myData[yearTemp+monthTemp] = your money! Figure 2 (previous page) shows how to insert
The Grid Manager int(myData[yearTemp+monthTemp]) + int(myAmount) data into myFinancials.py whereas Figure 3 (below) shows
Tkinter offers the amount.delete(0, END) the analytical information that myFinancials.py presents for
Grid Manager, used saveData() each month of every year when you press the Print Totals
in thirdGUI.py, which
As you can see, the insertData() function makes a call to button. To hide months with a zero balance, you can change
is automatically
created and used saveData() before exiting. The following is the Python 3 code the implementation of displayData() as follows:
when you call the of the displayData() function: def displayData():
grid() method. def displayData(): text.delete(‘1.0’, END)
The Grid Manager text.delete(‘1.0’, END) balance = 0
creates a master
widget that is split
balance = 0 tempData = []
into rows and tempData = [] for k in Years:
columns. Please for k in Years: for m in Months:
note that rows and for m in Months: balance += int(myData[k+m])
columns are made
balance += int(myData[k+m]) if int(myData[k+m]) != 0:
large enough to fit
the largest widget. tempStr = m + ‘ ‘ + k + ‘: ‘ + str(myData[k+m]) tempStr = m + ‘ ‘ + k + ‘: ‘ + str(myData[k+m])
tempData.append(tempStr) tempData.append(tempStr)
for f in tempData: for f in tempData:
text.insert(‘1.0’, f) text.insert(‘1.0’, f)
text.insert(‘1.0’, “\n”) text.insert(‘1.0’, “\n”)
balance = ‘\t\tBalance: ‘ + str(balance) balance = ‘\t\tBalance: ‘ + str(balance)
text.insert(‘1.0’, balance) text.insert(‘1.0’, balance)
text.insert(‘1.0’, “\n”) text.insert(‘1.0’, “\n”)
return 0 return 0
The first command of the displayData() function deletes All the work is done by the if statement that determines
the existing text of the Text Widget. Last, you will see the whether a value of the myData dictionary is zero or not. This
Python 3 code of the closeWindow() function that is the one change makes it easier to see the useful information, but
that terminates the application: some people want to see the full output. You can see the
def closeWindow(): relevant code in action in the secondGUI.py script, which is
saveData() presented in Figure 4 (right). Tkinter has many abilities but
root.destroy() you don’t have to use every one of them, most of the time you
should choose the simplest solution.

A tale of two versions


This section will offer two variations of the GUI without
changing the actual functionality of the program or the
Widgets that are used. This is mainly a great example of the
capabilities and the flexibility of Tkinter.
The following Python code, saved as secondGUI.py,
generates a different version of the user interface which
mostly has to do with the position of the various Widgets:
root = Tk()
Figure 3: This root.title(‘My Financials’)
Figure shows
c = Canvas(root, width=1000, height=1000)
the way the
c.pack()
analytical report
is printed when
you press the quitButton = Button(root, text=”Quit!”,
“Print Totals” command=closeWindow)
button. quitButton.pack(side=TOP)
inputButton = Button(root, text=”Insert Data”,

About Python 2
command=insertData)
inputButton.pack(side=LEFT)
displayData = Button(root, text=”Print Totals”,
As the code in this tutorial is written for and you get this error: command=displayData)
Python 3, if you try to execute any of the $ ./secondGUI.py
displayData.pack(side=RIGHT)
scripts using Python 2.7.x, the code will Traceback (most recent call last):
not run; instead, it will generate an error File “./secondGUI.py”, line 3, in
message because the from tkinter <module> selectYear = StringVar()
import * command or the import tkinter from tkinter import * selectYear.set(‘2016’)
command will not work in Python 2.7.x ImportError: No module named tkinter yearsMenu = OptionMenu(root, selectYear, *Years)
yearsMenu.pack(side=RIGHT)

126 | Coding Made Simple


Coding Projects | Money app
selectMonth = StringVar()
selectMonth.set(‘Sep’)
monthsMenu = OptionMenu(root, selectMonth, *Months)
monthsMenu.pack(side=LEFT)

amount = Entry(root)
amount.pack(side=BOTTOM)
text = Text(c, borderwidth=10, background=’lightgray’)
text.pack(side=RIGHT, expand=True)

mainloop()
Figure 4 (below) shows the GUI that is generated by the
code of secondGUI.py. Now for a grid arrangement:
root = Tk()
root.title(‘My Financials v3’)

text = Text(root, borderwidth=10, background=’lightgreen’)


text.grid(row=2, column=1) Figure 5: This is the third version of the user interface of the application, which
uses a grid to place the various Tkinter Widgets on the window.

selectYear = StringVar()
selectYear.set(‘2016’) grid because even small mistakes can dramatically change
yearsMenu = OptionMenu(root, selectYear, *Years) the look of your application. If you ever want to create a Quick
yearsMenu.grid(row=1, column=0) calculator using Tkinter, this is definitely the way to go! tip
selectMonth = StringVar() Figure 5 (above) shows the third version of the GUI for the Tkinter Resources
selectMonth.set(‘Sep’) myFinancials.py application, which is saved as thirdGUI.py. You can learn
monthsMenu = OptionMenu(root, selectMonth, *Months) more about
monthsMenu.grid(row=1, column=2) JSON saved your data Tkinter by reading
Programming
amount = Entry(root) As JSON is a very popular format, the last section will Python, 4th edition
amount.grid(row=1, column=1) demonstrate how to use the JSON format to save your data and by visiting
and how to load it afterwards. The following Python 3 code, https://wiki.
quitButton = Button(root, text=”Quit!”, saved as jsonSaveLoad.py, is an autonomous example: python.org/
moin/TkInter
command=closeWindow) #!/usr/bin/env python3
and https://docs.
quitButton.grid(row=0, column=0) python.org/3/
inputButton = Button(root, text=”Insert Data”, import sys library/tk.html.
command=insertData) import json However, the
inputButton.grid(row=0, column=1) best way to learn
Tkinter is by writing
displayData = Button(root, text=”Print Totals”, if len(sys.argv) >= 2: applications and
command=displayData) filename = sys.argv[1] trying new things.
displayData.grid(row=0, column=2) else:
This time you arrange the buttons using a different print(‘Not enough arguments!’)
technique that involves the use of a grid that helps you put sys.exit(0)
everything in the desired place. Your grid has three rows with
three columns each. However, as you may expect, the Text d1 = {‘key1’: 123, ‘key2’: 324}
Widget takes all the space of the third row. with open(filename, ‘w’) as fp:
This is a more precise method, which requires more json.dump(d1, fp)
Python 3 code. You will need to be extra careful when using a with open(filename, ‘r’) as fp:
d2 = json.load(fp)

print(‘d1:’, d1)
print(‘d2:’, d2)
You use the json.dump() method to save the contents of
the d1 dictionary on disk in JSON format. Afterwards, you use
the json.load() function to read a JSON file and assign its
contents to a new variable named d2. Executing
jsonSaveLoad.py generates the following output and file:
$ ./jsonSaveLoad.py testFile
d1: {‘key1’: 123, ‘key2’: 324}
d2: {‘key1’: 123, ‘key2’: 324}
$ ls -l testFile
-rw-r--r-- 1 mtsouk mtsouk 26 Sep 7 16:07 testFile
$ cat testFile; echo
{“key1”: 123, “key2”: 324}
Figure 4: This Figure shows the output of the secondGUI. So, storing data in JSON format is pretty similar to using a
py script, which illustrates how some simple commands CSV file. From here we hand over to you, enjoy expanding your
can change the appearance of a Tkinter application. basic money app with more features! n

Coding Made Simple | 127


SUBSCRIBE AND SAVE UP TO 61%
Every issue of your subscription, delivered direct to
your door. Print & digital editions available.

NEAT StoRAGE
Store up to 13 issues of your magazine subscription in a coordinating slipcase or binder.

myfavouritemagazines.co.uk
Discover great guides & Specials
From photography to music and technology to gaming,
there’s something for everyone.

A magazine subscription is the perfect gift they’ll love receiving


month after month. Choose from over 55 magazines and make
great savings off the shop price!
Our guides & binders also make great gifts and we have a wide
choice of gift vouchers too.

No hidden costs Shipping included in all prices We deliver to over 100 countries Secure online payment
Discover another of our great bookazines
From science and history to technology and crafts, there
are dozens of Future bookazines to suit all tastes
CODING
MADE
SIMPLE
Everyone can code with these
plain-English guides – you’ll learn
core programming concepts and
create code to be proud of!

Dozens of expert tutorials


• Pick up the basics with Python
• Teach kids to code using Scratch
• Learn to code on the Raspberry Pi

132
pages of tips,
tricks and
tutorials

Learn the basics of coding with Scratch, Discover everything you need to
the visual programming language know to start coding today
9000

Find out how you can develop on the Get started with our exciting and
low-cost Raspberry Pi system easy-to-understand tutorials

You might also like