Why Algebra?

Algebra is study of mathematical symbols (you might have seen: x, y, θ) and the rules for manipulating them. We most often use algebra to express relatioships between things (the symbols) and numbers.

For example: a bike hire shop could set the cost of renting a bike as a fixed cost plus an amount per day that the bike is rented. We could use algebra to work out costs for different customers.

But do we really need algebra? Can we just get along without it? Those symbols and all those rules are really confusing at first, is it worth the effort to learn them?

Let’s use Lego and a bit of Python programming to find out…

If you don’t have Python installed, head over to Repl.it to try it online. Also check out The Little Pythoner to learn the basics.

Building Pyramids

Imagine you are building a pyramid from lego cubes (the ones with 4 studs on top). How many blocks do you need to find for each level?

How would we work this out? Well it depends upon how high the pyramid is. Let’s say we were building a little pyramid, 5 levels high. It would look like this from the side:

5      *
4     * *
3    * * *
2   * * * *
1  * * * * *

Level 1, the first level has 5 blocks by 5 blocks, which is 25.

So in answer to the question: how many blocks for each level:

1 → 25
2 → 16
3 → 9
4 → 4
5 → 1

This is called a mapping: a sequence of numbers and their results.

We can turn this mapping into a Python function so that we can play with it and try out different versions. Just like the mapping above, we want our function to return the number of blocks we need for each level for a 5 level pyramid:

def pyramid_blocks(level):
  mapping = { 1: 25,
              2: 16,
              3: 9,
              4: 4,
              5: 1 }
  return mapping[level]

This function is a bit tedious to type in, but it is fairly easy to see that it does the same thing as the mapping above. Plus we’ve not had to use any algebra.

You can use it like this:

>>> pyramid_blocks(1)
1
>>> pyramid_blocks(3)
9

How about if we wanted to build a 10 level pyramid? How would we change the function to accommodate this? Well we know that the first level would require more bricks. Let’s draw it first:

10          *
9          * *
8         * * *
7        * * * *
6       * * * * *
5      * * * * * *
4     * * * * * * *
3    * * * * * * * *
2   * * * * * * * * *
1  * * * * * * * * * *

OK, so our new function looks like this:

def pyramid_blocks(level):
  mapping = { 1: 100,
              2: 81,
              3: 64,
              4: 49,
              5: 36,
              6: 25,
              7: 16,
              8: 9,
              9: 4,
              10: 1}
  return mapping[level]

However, now that function only works for 10 high pyramids, how would we get it to work for both?

We could pass in the height and use another if-statement like this:

def pyramid_blocks(level, height):
  if height == 5:
    mapping = { 1: 25,
                2: 16,
                3: 9,
                4: 4,
                5: 1 }
    return mapping[level]

  elif height == 10:
    mapping = { 1: 100,
                2: 81,
                3: 64,
                4: 49,
                5: 36,
                6: 25,
                7: 16,
                8: 9,
                9: 4,
                10: 1}
    return mapping[level]

OK, so I think we can see that this approach is not going to work if we keep changing the pyramid size – it’s a lot of typing and we have to change it each time we want to build a different size pyramid.

Surely we can do better?

We can, using algebra!

Introducing algebra

Algebra allows us to express answers in terms of relationships with other numbers. So we can express how many blocks in terms of the level and the height of the pyramid.

The challenge is this: What’s the relationship between the level, the height and the number of blocks?

Let’s start with the first function we wrote:

def pyramid_blocks(level):
  mapping = { 1: 25,
              2: 16,
              3: 9,
              4: 4,
              5: 1 }
  return mapping[level]

Those numbers 25, 16, 9, 4 and 1 are actually square numbers (makes sense since we’re building squares), so we can rewrite this function using this knowledge:

def pyramid_blocks(level):
  mapping = { 1: 5*5,
              2: 4*4,
              3: 3*3,
              4: 2*2,
              5: 1*1 }
  return mapping[level]

Now we can see a relationship between the level and square number – the level runs from 1 to 5 and the width of the square runs from 5 to 1, so we can further improve the function to this:

def pyramid_blocks(level):
  width = 6-level
  return width * width

Let’s test it:

>>> pyramid_blocks(3)
9
>>> pyramid_blocks(1)
25

Great stuff! Our new function produces the correct results.

OK so now let’s adapt this for different heights. Let’s start with the really long function we had before, but with the algebra we’ve worked out already:

def pyramid_blocks(level, height=5):
  if height == 5:
    width = 6-level
    return width * width

  elif height == 10:
    mapping = { 1: 10*10,
                2: 9*9,
                3: 8*8,
                4: 7*8,
                5: 6*6,
                6: 5*5,
                7: 4*4,
                8: 3*3,
                9: 2*2,
                10: 1*1}
    return mapping[level]

We can see a very similar (inverse) relationship as we saw before when height was 5: this time level runs from 1 to 10, and the width of the square runs from 10 to 1, so we can rewrite again:

def pyramid_blocks(level, height):
  if height == 5:
    width = 6-level
    return width * width
  elif height == 10:
    width = 11-level
    return width * width

Those return statements are the same so we can simplify a bit more:

def pyramid_blocks(level, height):
  if height == 5:
    width = 6-level
  elif height == 10:
    width = 11-level
  return width * width

This function still only works for 2 pyramids: 5 and 10 blocks high. However there’s one simple change we can make to make it work for any height. Can you see the relationship between height and how we calculate the width? The number is simply height + 1.

Here is the final function:

def pyramid_blocks(level, height):
  width = height + 1 - level
  return width * width

Now we have a function that works for any height pyramid we want to build, and it is only two lines long.

Let’s test it:

>>> pyramid_blocks(3,5)
9
>>> pyramid_blocks(1,5)
25
>>> pyramid_blocks(3,10)
64
>>> pyramid_blocks(1,10)
100
>>> pyramid_blocks(1,100)
10000
>>> pyramid_blocks(50,100)
2601

Finally let’s express that function using algebra:

b = ( h + 1 - l ) 2

where b is the number of blocks, h is height, l is level

Algebra allows us to express concisely the relationship between the number of blocks we need, the height and the level we’re building, which is much simpler to express than providing a list of all the possible values, as we did in our first attempts.

What next?

Here are some interesting questions to explore:

  • How would this algebra work in Minecraft?
  • What if you were building hollow pyramids?
  • What about a roof for a house (a triangular prism)?

How to learn to program

In my last post I shared some tutorials for Making Classic Games in Python, these have proven to very popular in our code club, helping kids learn Python with Pygame Zero.

A key part of successful learning is the learner’s motivation. If this is strong then they will be focussed and determined to make progress, even when they hit challenges or get frustrated (which is very common when learning to code).

However, what exactly is their motivation?

Often it is to re-create the classic game on their computer so that they can play it. Nothing wrong with that… it helps them work their way through the tutorials. But it does mean that often they are not trying to understand the code, just get it working.

When kids get stuck we often see a real lack knowledge of coding to solve the problem they face.

So what? We have a great team of mentors and we feel useful helping kids make progress and sharing our knowledge of coding to help them solve problems. That’s rewarding for the mentors.

However, our primary aim is to help kids learn how to learn. This is hard and takes time, but results in much more resiliant learners. A sign of success is that many of our older kids become mentors themselves, either informally helping their neighbours or by stepping into the mentor role.

So how do we help kids discover a motivation to understand the code? Really understand what it is doing and why it works?

We give them the choice to explore this path, and refer to the path as an interesting thing they might like to try.

That’s the theory anyway!

We have created a tutorial series called The Little Pythoner (inspired by classic book The Little Schemer) and we’ll be testing this out over the coming weeks. We’ll let you know how we get on…

A final point for now. It is important for the kids to have lots of good choices – e.g. making games, understanding coding, making something new – our role is to help them explore these paths when it is right for them.

Making Classic Games in Python

Python is a great programming language to learn however there’s no denying it’s a step up from block-based programming languages like Scratch.

When teaching Python it’s a big help if you can provide a hook to get new Python programmers interested. You will find that classic games like Candy Crush and Flappy Bird provide a great motivation for students.

../../../_images/flappy_bird.png

Flappy Bird in Pygame Zero

As soon as they see that they can create their own version of these classics they are fascinated and ready to get typing.

As well as the game concept you need a friendly programming environment and the Pygame Zero framework and the Mu editor are a great combination. Installing Mu also installs Pygame Zero so it’s easy to set up and get going.

../../../_images/candy_crush.png

Candy Crush in Pygame Zero

We (the mentors) at Brighton Coder Dojo have created three tutorials:

You’ll see a range of teaching styles in the tutorials from straightforward instruction (follow this and it will work), to some deliberate bugs that need to be fixed before progress can be made, through to more open ended exploration and algorithm design.

We plan to make more tutorials and would love to hear your feedback, so let us know what you think and if there’s anything you would like to suggest for future editions.

Eric Clack - eric@bn7.net.

Team Retrospective Principles

A retrospective makes time for the team to reflect on recent activities and identify actions to improve their performance.

There are many ways to run a retrospective, and many resources to help you to discover and practice new methods. So how do you pick which methods to use?

If you focus on the principles underlying a good retrospective you can be flexible and try a variety of methods that are compatible with your principles.

So let’s first look at the purpose of a retrospective and then the set of guiding principles I use.

I have also included a skeleton method at the end of this post so that you get an idea of the format of a typical retro.

However: be flexible, be creative and try out a wide variety of formats – you don’t want your retros to become a stale ritual that your team endure each time.

What’s the purpose?

A retrospective is all about making time for continuous improvement, that is: maximising value delivery and minimising waste. By meeting periodically and using the right process the team can make a big difference to its performance.

In an Agile software development team a retrospective is all about finding ways to deliver more valuable stories with less waste (e.g. fewer defects, avoiding the wrong stories, less delay).

For a customer service team a retrospective could focus on how to achieve more high quality customer interactions (such as account management) and less waste in the form of defects, team turnover, mis-configuration and lost customers.

In more detail the purpose of a retrospective is to:

  • commit the team to regular time for reflection and continuous improvement
  • help the team find the right problems to face
  • see the power they have to make progress
  • help the team discover, plan and execute improvement actions.

Retrospective principles:

Here are the principles I find produce the best results:

  • Aim for one good improvement action each retrospective, an action that is ready to make progress on right away, and with one willing owner
  • Confidential, make a safe place to discuss tricky topics; what is said in the room stays in the room unless the team collectively choose to take it out
  • Equivalence of team members, everyone in the retro has equal status in the room no mater what their status in the team
  • Consent over majority, find a way to bring the team together under a common purpose, rather than a split team with many competing ideas
  • Achieve a balance in the retro of quiet reflection, discussion, creativity and commitment to a way forward
  • Independent facilitator, you need someone to keep the team to the agreed process, to ensure progress is made towards your objective, to ensure equivalence of the team members, basically to ensure that everyone keeps to these principles.

I encourage you to think about what your principles would be. First do take time to understand why the principles above are widely supported and what effect they have on the team and the outcomes of the retrospective process.

Some ideas on running a retrospective

Taking everything above into account, here’s a skeleton retrospective structure that you might find useful:

Initial admin:

  1. Check-in – Everyone around the room checks in with a few words on how they are doing today. “I’m good”, “I’m tired”, “My dog isn’t well”, …
  2. Quick summary of how the week/month went – “We delivered X stories”, “It was a challenging week because…”
  3. Review the current improvement actions – from previous retros
  4. Agree desired outcome of this retro – often just “find one good improvement action”, but this could be “explore why we haven’t made much progress on our current actions”.
  5. Agree today’s retro theme or format

And now the main part, very much shaped by the retro theme or format:

  1. Quiet reflection, everyone writes things on sticky notes
  2. Facilitator builds a shared understanding by reading out the stickies and asking for clarification
  3. The team chooses what to make progress on, with the help of the facilitator.

And finally, once the improvement area has been chosen, the hardest part:

  1. Quiet reflection, the team thinks up ways to make progress on
    the chosen area
  2. Share proposals, the team shares proposals, with the facilitator building a shared understanding
  3. Build consent, guided by the facilitator the team comes together under a single proposal, often by merging several related proposals
  4. Action, the team decides and documents the action, the owner, and the first step.
  5. Commitment, the team checks itself for commitment to this action.

On that last point the team is checking that it is being realistic. I would advise that the team bears this in mind during this last stage, e.g. the facilitator could ask in proposal generation, “Is this something we are going to be able to commit to?”

What theme for your retrospective?

But what about the theme or format? Here’s a great guide with lots of ideas: Agile Retrospectives: Making Good Teams Great

Questions, comments, feedback? Email me: eric@bn7.net

Pixel perfect collision detection with PygameZero

PygameZero is a great framework to help young coders step up from block-based coding in Scratch. However it doesn’t have all the features of Scratch: one notable omission is pixel perfect collision detection.

As the name suggests, PygameZero is based on Pygame and this does have many collision detection methods, so can we use Pygame features to improve PygameZero?

The answer is Yes! It took a bit of digging, and here’s how to do it…

Add this import at the start of your code:

from pygame import mask

Then add this function:

def collide_pixels(actor1, actor2):

    # Get masks for pixel perfect collision detection:
    for a in [actor1, actor2]:
        if not hasattr(a, 'mask'):
            a.mask = mask.from_surface(images.load(a.image))

    # Check rectangles first, this is faster
        if not actor1.colliderect(actor2):
            return None

    # Offsets based on current positions of actors
    xoffset = int(actor2.left - actor1.left)
    yoffset = int(actor2.top - actor1.top)

    # Check for overlap => a collision
    return actor1.mask.overlap(actor2.mask, (xoffset, yoffset))

Now you can call this function with two actors and you’ll get pixel perfect collision detection based on the transparent pixels in each image (the alpha channel).

Here’s an example program that shows the function above in action.

You’ll need 3 PNG images (with transparency):

  • cave.png, which is a 500x500 pixel background with some brush strokes to mark the walls
  • me.png, which is our game character (I just used a dot for testing)
  • me-hit.png, a hit version of our character (I just used a different colour).

Here’s the complete program:

from pygame import mask

WIDTH = 500
HEIGHT = 500

cave = Actor('cave', (250,250))
me = Actor('me', (250,250))
me.speed_x = me.speed_y = 0

def collide_pixels(actor1, actor2):

    # Get masks for pixel perfect collision detection:
    for a in [actor1, actor2]:
        if not hasattr(a, 'mask'):
            a.mask = mask.from_surface(images.load(a.image))

    # Check rectangles first, this is faster
    if not actor1.colliderect(actor2):
        return None

    # Offsets based on current positions of actors
    xoffset = int(actor2.left - actor1.left)
    yoffset = int(actor2.top - actor1.top)

    # Check for overlap => a collision
    return actor1.mask.overlap(actor2.mask, (xoffset, yoffset))

def draw():
    cave.draw()
    me.draw()

def update():
    screen.clear()
    me.x += me.speed_x
    me.y += me.speed_y
    if collide_pixels(cave, me):
        print("collission!")
        me.image = 'me-hit'
    else:
        me.image = 'me'

def on_key_up(key):
    if key == keys.LEFT:
        me.speed_x += -1
    if key == keys.RIGHT:
        me.speed_x += 1
    if key == keys.UP:
        me.speed_y += -1
    if key == keys.DOWN:
        me.speed_y += 1

When you run this program you should see the me sprite change costume when it hits the walls. Now you can see how you can use collide_pixels in your own games to provide better gameplay.

Functional programming at code clubs

I’ve been mentoring at Brighton Coder Dojo and Code Clubs for a few years now and I’m always on the lookout for new things to try that might broaden the mind, offer alternative approaches and get students thinking differently.

So what about functional programming? How would that work at a code club with 6-16 year olds? Is it even possible in the programming environment we use most often: MIT Scratch?

Functional programming enables you to:

  • Write functions that take input and produce output with no side-effects, which makes them easy to reason about and test in isolation, and easy to share across projects
  • Use recursion to process lists of things, avoiding the work of loops and loop counters
  • Write higher-order functions that take other functions or blocks as input, making it possible to write custom logic or iteration blocks, such as for-each, map, filter or fold.

In addition, functional programming helps you to think differently about algorithms, often resulting in a more concise, elegant solution to a programming challenge. Indeed, many mainstream languages have adopted functional features to bring these benefits to the programmer, see examples in Python and JavaScript.

MIT Scratch is the most popular programming language we use at code clubs and I’ve explored it to see if I can demonstrate functional programming. Unfortunately it’s not possible to create blocks that return values (Reporter blocks – Stack Overflow post) so I need another tool.

Snap! looks like the answer. It’s an extended reimplementation of Scratch that allows you to build your own blocks with many more options than Scratch. In the creator’s words it is Scratch + the power of Scheme.

Modelling a flock of animals

To explore functional programming, we need an interesting app to create, how about Boids? Boids simulate the flocking behaviour of animals, such as birds or sheep. There are 3 simple to state rules:

  • separation: steer to avoid crowding local flockmates
  • alignment: steer towards the average heading of local flockmates
  • cohesion: steer to move toward the average position (centre of mass) of local flockmates

These are simple to state but harder to program! Read on to see some initial versions, with various functional elements. You can click a title to see the code running in Snap.

Sheep version zero

Let’s start with a very simple program: version 0 Here our sheep are moving randomly with no concern for each other. This has one new block (and nothing functional yet): if-on-edge-wrap — and nothing Scratch can’t do:

../../../_images/sheep-boids-v0.png

Sheep version 1

Now for version 1 Here our sheep are moving randomly, but they know when they are near another sheep and flash. I’ve created a new control block for-each so that we can run the set of instructions on every sheep.

../../../_images/sheep-boids-v1.png

The first two lines in the block create a local variable for each of the other sheep. We check the distance from us to this sheep and switch costume if it’s less than 60. The new for-each block makes it easy to do things to every element of the list, without having to do the usual loop work in Scratch.

Here’s the definition of the block, it takes a list and a code-block as parameters and uses recursion to work through the items of the list apply the block of instructions (above) to each. You can see the exit clause in the empty if-statement, if there’s no list left we’re all done.

../../../_images/sheep-boids-v1-code.png

Sheep version 2

Version 2 - Now our sheep like the mouse pointer and move towards it. There are several new functions to calculate the force applied to each sheep from the mouse.

../../../_images/sheep-boids-v2.png

Here’s the main block of code that runs for each sheep:

../../../_images/sheep-boids-v2-code.png

You can see them at the bottom of the left hand panel in the Operators section in Snap.

To do…

There’s lots left to explore, for example:

  • The sheep move too fast, maybe they should have a maximum speed?
  • While we’ve shown how the sheep react to the mouse pointer, they don’t react to each other yet; Version 1 has a starting point for this behaviour in that they know when they are close together.

A safe place to store photos at home

I’ve been taking photos for years and now have many thousands, in fact too many to store on my laptop. My family take photos too, and we all like to share them.

None of us are particularly happy with Facebook or other online photo sharing sites, and anyway most of these are geared towards individual photographers, not a family of photo sharers.

As I’m a programmer I like to know how things work and strongly favour a solution where I can see and test the photo and metadata storage, so that I know that everything is safe. (And OK, yes, as a programmer I’m much more motivated to create my own solution rather than use an existing one!)

So how do we store and share our photos? Our solution: a Home Photo Bank. It’s a safe place to store and share your family photos on your home network.

If you’ve got a spare computer around, a cheap Raspberry Pi would be idea, then follow this blog post to get your own photo bank up and running.

As well as photo storage and sharing, there are also tagging features so that you can categorise and discover related photos.

../../../_images/home-photo-bank-search.jpg

You can read a bit more about the photo bank on its GitHub page: https://github.com/ericclack/home-photo-bank

Note: this is tested on Raspbian, and Mac OS. It should work on any Debian distro, and will probably work on Windows with some tweaks.

What you need:

  • A Raspberry Pi, model 2 or 3, running Raspbian
  • A router to plug it into, or use wifi
  • Some familiarity with the linux command line.

The steps:

Here’s a summary of the steps we’ll carry out:

  • Make your Raspberry Pi visible on your home network
  • Install packages: oracle-java8-jdk and mongodb
  • Install the application
  • reate cron ‘reboot’ entry to run the photo bank
  • Add a photo-uploader user, SSH keys and local scripts to make it easy to import files
  • Test that it works.

Make your Raspberry Pi visible

Your family and friends (and anyone else on your home network) need to be able to access the photo bank. Set the Pi’s hostname by editing /etc/hostname and then share the link http://photobank.local:3000/ - replace “photobank” with whatever hostname you gave your pi.

Install packages

Use apt-get to install the required packages: Java JDK for the runtime, and MongoDB for the data store and git to get the app itself.

sudo apt-get install oracle-java8-jdk mongodb git

Install the Photo Bank

There are five parts to the install:

  • Install the build tool Leiningen
  • Get the app source code
  • Make media directories
  • Set database credentials
  • Run the app to download dependencies and start up the photo bank

To get Leiningen:

wget https://raw.githubusercontent.com/technomancy/leiningen/2.7.1/bin/lein
chmod +x lein
lein

To get the app source code run:

git clone git@github.com:ericclack/home-photo-bank.git

Make media directories:

The photo bank stores photos in media directories. Create these before you run the app:

cd home-photo-bank/media
mkdir _import _process _failed

Credentials:

The media and database credentials are stored in the file profiles.clj – create this file and add these lines:

{:profiles/dev
  {:env
    {:media-path "media"
     :database-url "mongodb://localhost/photo-bank" }}}

Almost there

Now run the app, this will download all dependencies on the first run:

cd home-photo-bank
lein run

Now you should be able to browse to http://photobank.local:3000/

Pop some files into the folder media/_process and then browse to the Import tab to tag and import.

Further set up information is available on the project GitHub page including scripts to automate start-up, import and backup.

An education manifesto

I’ve been involved in home school learning and education for over 5 years, enough time to start to make sense of my values and principles – what I stand for when guiding the learning of others.

So I’ve created a first draft education manifesto. I hope this will start a conversation about how we educators go about our work and how we support people on their learning journey.

BTW, this really is a first draft – it’s a bit jumbled and there are things missing – do help me improve it.

Why a manifesto?

By writing down our values and principles we can reflect on why we are doing what we are doing, explain to others what we are up to, and enable others to challenge our approach. This should lead to greater awareness and an improved approach, or at least an interesting conversation.

(Format and ideas inspired by the Agile Manfesto http://agilemanifesto.org/)

Education Manifesto

We are uncovering better ways to lead learning by doing it and helping others do it. Through this work we have come to value:

  • Learner led over leader led
  • Working on the learning environment over working on the learner
  • Intrinsic satisfaction over token rewards
  • Right pace over race to results
  • Deep understanding over memorisation
  • Working through struggle and mistakes over showing off perfection
  • Coaching and mentoring over micro-management
  • Questions from the learner over questions from the leader

Principles:

Create an ideal environment for learning. Think about productive environments and the activity they encourage, e.g. library, workshop, artists studio, music practice room.

Recognise energy now and choose task appropriately. If energy remains low, respect this and try something else.

Regular feedback to leader and learner to drive improvement. Respect learner’s readiness for feedback and seek permission periodically (not continuously).

Deliberate practice builds mastery.

Connected learning to learner’s needs + desires. “What does this mean for me?” is a great question.

Theory:

Some articles, books and notes about learning theory:

I’d love to hear what you think about this, email me at eric@bn7.net