My First Raspberry Pi Game – Part 02 – Saying hello

Parts: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12.

Writing your first ever computer program on the Raspberry Pi. See Part 1 for how to get and set up the Pi.

Today we will find out how to write a computer program, and how to run it.

We’re going to write one of the simplest programs you can write – we’re going to get the computer to say hello to us.

First, we need a text editor to write down our program. Click the weird aeroplane-y thing in the bottom left – that brings up the menu (like the Start button on Windows), then choose Accessories, then Leafpad. Leafpad is the text editor we will be using.

Leafpad will start, and show you an empty page. This is where we will write our program.

Type in exactly this:

print "Hello, world!"

and then click the File menu at the top of the Leafpad window and choose Save As. Click the word “pi” on the left and then click in the empty box next to the word Name, and type the name of our program, which is:

redgreen.py

“redgreen” is the name and the “.py” means this is a program written in the language Python. We’ll be finding out more about Python as we go on.

Click the Save button.

Our program is finished! Now we need to run it.

Click the aeroplane-y thing again, then Accessories, then LXTerminal. A terminal is a program you use to run other programs.

When LXTerminal has started, your cursor will appear next to a $ sign. This means it is ready for you to tell it what to do.

Type exactly this:

python redgreen.py

What this means is run the program called “python”, and pass the name of our program (redgreen.py) to it. This is how you run Python programs.

Now press the RETURN key.

If all goes well, our program will talk back to us, and say what we told it to say:

Hello, world!

Let’s look again at our program.

It’s just one “statement”, a print statement. A statement is something to do.

We pass one “argument” to print, “Hello, world!”. An argument is some information you give to a statement.

“print” doesn’t mean print to the printer, but write to the screen. So our program did exactly what we told it to do – it wrote our message to the screen.

Next time, we’ll map out the whole of our real program – a simple game.

Update: congratulations to sparkboy123 on getting this working!

My First Raspberry Pi Game – Part 01 – Before we start

Parts: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12.

In this series I intend to guide you through writing your first ever computer program.

We will write our own game on the Raspberry Pi, which is a cheap-as-chips computer designed for learning about computers.

Get a Raspberry Pi

To follow along, here’s what you will need:

  • A Raspberry Pi (about £25) – I got it from RS
  • An SD card (about £10) – be careful – not all of them work. I use: Kingston Technology 16GB
  • If your TV supports it, an HDMI cable (about £1) – I got: HDMI to HDMI Connector. If your TV doesn’t support HDMI, get a composite cable, but it won’t look as good or work as well.
  • A power supply (about £4) e.g. a smartphone charger (micro USB, at least 5V, 1A) – I got Micro USB Mains Charger but my existing HTC Wildfire S charger worked too.
  • USB keyboard and mouse (about £7) – I had them lying around, but a quick search suggests this one might be ok: CiT USB Keyboard and Mouse.

(Total cost, very approximately: £47)

Install “Raspian”

To use the Pi you will need to install some software onto your SD card.

To do this you will need a PC or laptop. If you don’t have one, or you’d prefer not to download and install software to an SD card, check out The Pi Hut. They sell SD cards that already have Raspian installed on them.

Raspian is the name of the software we will use to start up and run our Raspberry Pi. You need to download it and install it onto your SD card before you can put the SD card into the Pi and turn it on. To do this, you’ll need a way of writing to the SD card. Lots of laptops (and some desktops) have built-in SD card readers, or you can get a USB reader (I got this one: SD Card Reader USB 2.0).

To install Raspian “wheezy” (wheezy is the name of the latest version) go to the Raspberry Pi download page at www.raspberrypi.org/downloads and click the link in the Raspian “wheezy” section next to the words “Direct download”. Follow the instructions on how to install Raspian to your SD card here: elinux.org/RPi_Easy_SD_Card_Setup.

(There are also some helpful instructions here: reviews.cnet.co.uk/desktops/how-to-get-started-with-the-raspberry-pi-50009845/.)

Start the Pi

Once you’ve got an SD card with Raspian on it, insert it into your Pi (the SD card slot is underneath, which surprised me a bit). Plug the Pi into your TV by connecting the HDMI cable to it and plugging the other end into the TV’s HDMI port. Plug your keyboard and mouse into the 2 USB slots.

Take a deep breath, and plug the power supply into the micro-USB port.

If all goes well, some lights will appear on the Pi, you will be able to switch your TV to HDMI mode and your screen will show some writing and possibly pictures of raspberries. Wait for it all to settle down, and (hopefully) eventually you’ll see the setup screen.

First time setup

The first time your Pi boots it will ask you to do some setup. Read the raspi-config menu items and see whether there’s anything you want to change. You might want to change your keyboard and language settings, but I didn’t need to change anything at all. I just pressed TAB and then right-arrow to move onto the word Finish, then pressed RETURN.

There’s more information about how to set everything up at elinux.org/RPi_raspi-config, and there’s a nice detailed video here: First boot and Raspi-config.

Wait a bit more, and eventually you should see a huge raspberry, with a mouse cursor and desktop. If so, you’re ready for the next part!

Update: a real person really following this series!:

Bash associative array examples

Quick reference of things I discovered about how to use associative arrays in bash. Note: bash version 4 only.

Play my Android game Rabbit Escape! Get it on Google Play

Update: see also Bash Arrays.

Basics

$ declare -A MYMAP     # Create an associative array
$ MYMAP[foo]=bar       # Put a value into an associative array
$ echo ${MYMAP[foo]}   # Get a value out of an associative array
bar
$ echo MYMAP[foo]      # WRONG
MYMAP[foo]
$ echo $MYMAP[foo]     # WRONG
[foo]

Creating

$ declare -A MYMAP     # Explicitly declare
$ MYMAP[foo]=bar       # Or this line implicitly makes it an associative array (in global scope, bash 4.2+ only)
$ MYMAP[baz]=quux      # Can add multiple values one by one
$ MYMAP[corge]=grault
$ declare -A MYMAP=( [foo]=bar [baz]=quux [corge]=grault ) # Initialise all at once
$ echo ${MYMAP[foo]}
bar
$ echo ${MYMAP[baz]}
quux
$ declare -A MYMAP                              # Or declare separately
$ MYMAP=( [foo]=bar [baz]=quux [corge]=grault ) # Then initialise
$ echo ${MYMAP[foo]}
bar
$ echo ${MYMAP[baz]}
quux

Variables as keys

$ K=baz
$ MYMAP[$K]=quux       # Use a variable as key to put a value into an associative array
$ echo ${MYMAP[$K]}    # Use a variable as key to extract a value from an associative array
quux
$ echo ${MYMAP[baz]}   # Obviously the value is accessible via the literal key
quux

Quoting keys

$ declare -A MYMAP
$ MYMAP[foo A]="bar B"         # Quoting keys makes no difference
$ MYMAP["corge X"]="grault Y"  # Quoting keys makes no difference
$ echo ${MYMAP["corge X"]}     # You can access by quoting
grault Y
$ echo ${MYMAP[corge X]}       # Or not bother
grault Y
$ echo ${MYMAP[foo A]}
bar B

$ MYMAP['waldo 1']="fred 2"    # Single quotes also make no difference
$ echo ${MYMAP['waldo 1']}
fred 2
$ echo ${MYMAP[waldo 1]}
fred 2

$ K=plugh
$ MYMAP['$K']=xyzzy   # Except single quotes prevent variable expansion, as usual
$ echo ${MYMAP[plugh]}

$ echo ${MYMAP['$K']}
xyzzy

Missing keys

$ MYMAP[foo]=bar
$ echo ${MYMAP[missing]}   # Accessing a missing value gives ""

$ # Testing whether a value is missing from an associative array
$ if [ ${MYMAP[foo]+_} ]; then echo "Found"; else echo "Not found"; fi
Found
$ if [ ${MYMAP[missing]+_} ]; then echo "Found"; else echo "Not found"; fi
Not found

Looping

$ declare -A MYMAP=( [foo a]=bar [baz b]=quux )
$ echo "${!MYMAP[@]}"  # Print all keys - quoted, but quotes removed by echo
foo a baz b

$ # Loop through all keys in an associative array
$ for K in "${!MYMAP[@]}"; do echo $K; done
foo a
baz b

$ for K in ${!MYMAP[@]}; do echo $K; done     # WRONG
foo
a
baz
b

$ # Looping through keys and values in an associative array
$ for K in "${!MYMAP[@]}"; do echo $K --- ${MYMAP[$K]}; done
foo a --- bar
baz b --- quux

$ # Loop through all values in an associative array
$ for V in "${MYMAP[@]}"; do echo $V; done
bar
quux

Clearing

$ declare -A MYMAP
$ MYMAP[foo]=bar
$ echo ${MYMAP[foo]}
bar
$ declare -A MYMAP    # Re-declaring DOES NOT clear an associative array
$ echo ${MYMAP[foo]}
bar
$ unset MYMAP         # You need to unset and re-declare to get a cleared associative array
$ declare -A MYMAP
$ echo ${MYMAP[foo]}

Deleting keys

$ MYMAP[foo]=bar
$ echo ${MYMAP[foo]}
bar
$ unset ${MYMAP[foo]} # WRONG
$ echo ${MYMAP[foo]}
bar
$ unset MYMAP[foo]    # To delete from an associative array, use "unset" with similar syntax to assigning
$                     # BUT see next section if key contains spaces
$ echo ${MYMAP[foo]}

$ MYMAP[baz]=quux
$ echo ${MYMAP[baz]}
quux
$ K=baz
$ unset MYMAP[$K]       # Can unset using a variable for the key too
$                       # BUT see next section if variable may contain spaces - always better to quote
$ echo ${MYMAP[baz]}

Deleting keys containing spaces

$ declare -A MYMAP
$ MYMAP[foo Z]=bar
$ echo ${MYMAP[foo Z]}
bar
$ unset MYMAP[foo Z]     # WRONG
bash: unset: `MYMAP[foo': not a valid identifier
bash: unset: `Z]': not a valid identifier
$ unset MYMAP["foo Z"]    # You must quote keys containing spaces when you unset in an associative array
$ echo ${MYMAP[foo Z]}

$ MYMAP[foo Z]=bar
$ unset MYMAP['foo Z']    # Single quotes work too
$ echo ${MYMAP[foo Z]}

$ MYMAP[baz A]=quux
$ echo ${MYMAP[baz A]}
quux
$ K="baz A"
$ unset MYMAP[$K]         # WRONG
bash: unset: `MYMAP[baz': not a valid identifier
bash: unset: `A]': not a valid identifier
$ unset MYMAP["$K"]       # You must quote variables whose values may contain spaces when you unset in an associative array
$ echo ${MYMAP[baz A]}

$ MYMAP[baz A]=quux
$ unset MYMAP['$K']       # Curiously, single quotes work here too, although I'd suggest avoiding them
$ echo ${MYMAP[baz A]}

Length

$ declare -A MYMAP=( [foo a]=bar [baz b]=quux )
$ echo ${#MYMAP[@]}  # Number of keys in an associative array
2
$ echo $#MYMAP[@]  # WRONG
0MYMAP[@]
$ echo ${#MYMAP}   # WRONG
0

Numeric indexing

$ declare -A MYMAP=( [foo a]=bar [baz b]=quux )
$ KEYS=("${!MYMAP[@]}")      # Make a normal array containing all the keys in the associative array
$ echo ${KEYS[0]}            # Find a key via an index
foo a
$ echo ${MYMAP[${KEYS[0]}]}  # Find a value via an index
bar

$ # Loop through using an index
$ for (( I=0; $I < ${#MYMAP[@]}; I+=1 )); do KEY=${KEYS[$I]};  echo $KEY --- ${MYMAP[$KEY]}; done
foo a --- bar
baz b --- quux

Scope

$ unset MYMAP
$ function createmap() { MYMAP[foo]=bar; }  # Implicit creation puts it in the global scope
$ echo ${MYMAP[foo]}

$ createmap
$ echo ${MYMAP[foo]}
bar
$ unset MYMAP
$ function createmaplocal() { declare -A MYMAP; MYMAP[foo]=bar; }  # Explicit creation puts it in the local scope
$ echo ${MYMAP[foo]}

$ createmaplocal
$ echo ${MYMAP[foo]}

Checking Bash version

$ bash --version   # Must be at least version 4 to have associative arrays
GNU bash, version 4.2.24(1)-release (x86_64-pc-linux-gnu)
...

Links

Lambda functions timeline

I did a talk at work about lambda functions (anonymous functions), and something possessed me to make a timeline of when they were introduced into various languages. Some languages were born with them, and some grew them later – in the latter case I give the language version and date in which they were introduced.

It’s probably entirely wrong, but here it is:

Dates when lambda functions were introduced into various programming languages

Note that C# had varying levels of support for lambda functions in different versions. I used the version (3.0) in which Wikipedia describes its support as “full”.

Goodness in programming languages, part 3 – not doing the same thing more than once

Posts in this series: Syntax, Deployment, Metaprogramming, Ownership

I’m going to use a word here – don’t stop reading: Metaprogramming. Does the language provide what you need to avoid repeating yourself?

Repeating boilerplate code, algorithms and most importantly ideas, slows you down, makes maintenance difficult, and allows all kinds of mistakes to creep in. If a language provides the ability to abstract, name and re-use all the different types of structure it contains, you can avoid harmful repetition.

Here are some things I like:

  • Python, JavaScript and Scheme’s ability to treat functions like any other object. A massive step towards sharing code is being allowed to pass around something that can be called without worrying about what it is.
  • Scheme’s ability to define an algorithm independently of types. In Scheme, there is never a need to write another version of the same function because it deals with different types of thing.
  • Python’s ability to read and modify classes just like any other object. Want a class just like your current one, except it logs every method call? Write a function that copies and modifies the class definition.
  • Scheme’s ability write code about code. In Scheme, code is just some nested lists. It’s trivial to build and modify code without stepping out of the language.
  • C++’s ability to write code that runs at compile time. If you can stand the syntax and (lack of) debugging, C++ template metaprogramming allows you to build C++ code at compile time without stepping out of the compiler environment.
  • Scheme and C’s macro systems. Both Scheme and C (and C++) allow you to write macros that build commonly-repeated code. Scheme’s syntax for this is much easier to work with.

Until you’ve experienced the freedom of totally generic code in a language like Scheme it’s hard to explain why the “Generics” features of some languages are so lacking. Of course, static typed languages work under different constraints. Would it be possible to write a language with very strong generic programming features, but which still allows static typing and compiling to native, non-generic code? I think so.