Max out your programming skills with Raspberry Pi Magazine

The latest issue of Raspberry Pi Magazine is now out. You can find it here. It’s got a couple of articles by me in it, which is rather nice. The first one is all about maximising your coding skills by learning new things about Python and taking a look at other languages - JavaScript and Rust. The second one describes how to build a Raspberry Pi PICO powered cable release with built in self-destruction detector. The magazine is a great read, and the new layout is really nice. Well worth a read. You can buy it online or you can find it in newsagents.

Proper use of ChatGPT for learning to program

You might be wondering about the best way to use ChatGPT (other large language models are available) to learn how to write programs.  Here’s what I think.

Do not ask ChatGPT to write code for you

This is a great idea if you know how to do a job but are just too lazy to do it yourself. If is a bad idea if you want to learn from what ChatGPT will produce.

In my experience requests to make code usually result in something around 95% right. You can fix the first few faults by telling ChatGPT what it has got wrong. But there comes a point where this no longer works. ChatGPT will claim it has fixed things, but the program still won’t work. A skilled coder can have fun finding the remaining issues and fixing them. A learning coder will just get frustrated.

Do ask ChatGPT to explain things to you

You are on much more solid ground if you ask ChatGPT to explain something you don’t understand. Ask it what “NaN” means in JavaScript, and you will get a good explanation, some examples and suggestions of things that you might want to know about next. This can make for great learning journeys. And at any time, you can ask it to summarize what you have learnt so far or ask you some questions you can use to check on your progress.

When ChatGPT is asked to explain something, it just has to find the information it has obtained from lots of sources - including my writings ☹ - and then summarize it. ChatGPT doesn’t have to make anything original. You can be a lot more confident that what it says is correct, since it hasn’t really had to originate anything.

Do tell ChatGPT what you know

You can use ChatGPT to test your understanding of something. This is very useful for two reasons. Firstly it gets you used to explaining what you know. Secondly it provides useful confirmation or critique of what you understand and how you expressed it. Start with “As I understand it….” and then go on to set out what you think you know. If you have a question about this, add it on the end. This gives the AI plenty of raw materials to come up with a useful response.

Do show ChatGPT your code

It turns out that ChatGPT is very good at figuring out what code does. If you want some comments on your approach or better ways to do things, paste the lot into ChatGPT and see what it says. You can then ask ChatGPT to expand on its comments and make more suggestions. If you want to learn a new graphical framework or library (or even language), paste your code into ChatGPT and ask it to generate a new program with the required changes. You can even get ChatGPT to write documentation for you. Or at least produce a first draft you can fiddle with.

Back from holidays

I’ve been away for the last couple of weeks having the full theme park experience. Above is a picture of an installation at the resort where we stayed for the first week. The various hotels were all themed, this one was all about the 1990’s and was adorned with a huge laptop from the era.

They also had a rather large Mickey Mouse telephone. It was a great holiday. Expect slightly fewer Python posts and more Disney/Universal ones going forward.

Hull Tech Session on May 6th at Hull University

The heading is doing most of the heavy lifting on this post. But I’d just like to add that the session starts at 6:30 pm and ends at 8:30 and is in the Brynmor Jones Library at Hull University. There are two talks, one from Ben Foster about integrating large AI models with smart home systems and another from Alistair Kennedy about Cybersecurity.

You can sign up here. The last session I went to was excellent.

Python Shorts 12: Fun with string formatting

We can use Python formatted string literals to easily drop values into strings of text. But we can also have even more fun with them when we add extra information to control the formatting process. This is particularly useful when we are creating messages to be displayed on devices with particular dimensions.

For example. perhaps I want to display the time on an LCD panel. I want the hour and the minute to have leading zeroes (so that they look like a digital clock). I could write some cunning code to add the zeroes if the values are less than 10, or I could use a formatted string:

hour=5
minute=6

These are our time values. If we want to make a digital clock out of them we just need to do this:

time = f"{hour:02}:{minute:02}"

Note that each expression to be output is now followed by a colon and a couple of digits. The first digit means "Pad the number with zeroes". The second digit means "display the value in two spaces". So the time string is set to:

05:06

If we don't want to pad the number with zeros, but use spaces instead, we just omit the leading zero.

f"{0:10}"

This string literal ends up being 9 spaces followed by a single zero.

We can add a decimal point to our formatting values to control the number of decimal places displayed when using floating point values:

x=f"{3.141592653:10.3f}"

This would create a 10 character long string with a three decimal place value of the high-precision value of Pi:

'     3.142'

Note that the f after the 3 in the fornmat (the number of decimal places) tells Python that you are outputting a floating point number and it must have three decimal places. If you leave out the f Python assumes you are outputting a general value and will just display three digits (3.14).

Things get even better when we start using control characters to select the text alignment:

f"{'Menu':^10}"

This would centre the word Menu in a 10 character string. Jolly useful if you want to line things up for a particular sized LCD panel. You can use < and > to left or right justify the string inside the field. And it gets even funner (if that is a word). You can even use variables to control this formatting behaviour:

display_width=16
banner=f"{'Menu':^{display_width}}"

The above statements make a banner which is 16 characters long and contains the word Menu centred in it. If you want to change the size of the display you are using, just modify display_width

It is worth getting good with format strings, they can save an awful lot of work.

Python Shorts 11: Formatted string literals

Formatted string literals are amazingly useful. You can make your Python output look really good, whether you are printing on the terminal or assembling a message to be displayed on an embedded display.

There are several ways to create formatted literals. I like the “f-string” approach which works in later versions of the language, including MicroPython and CircuitPython.

Let’s start with some values we might want to output:

name="Rob"
age=21

We can create a formatted string to display this values as follows:

message = f"Name:{name} Age:{age}"

The f in front of the string tells Python to scan the string and look for braces (curly brackets) that identify expression values to be included in the string. The values of name and age are inserted into the string in the specified positions. If you actually want to put braces into your text you have to enter two of them:

age_braces = f"{{{age}}}"

This would create a string containing the value of age enclosed in braces.

Python Shorts 10: Going Global

A variable is a box you can name to put something in. In Python you can just make one:

 age=21

Python decides it needs to make a variable (age is not a word Python knows), looks at 21, decides that it needs an integer shaped box, makes one,  puts 21 in it and then paints the word age on the box so it can find age later. So far, so normal. Let’s make a function:

 def brokenFunc():
    print(age)

There’s a clue here that bad things are about to happen. If you run this you get: 

UnboundLocalError: cannot access local variable 'age' where it is not associated with a value

This is because the body of a function (the indented bit after def) is a separate variable scope. The scope of a variable is those areas of your code where statements can work with it. Any variables created in a function body are local to the function and disappear when the function completes. Variables are either global (declared outside all functions) or local (declared inside the body of a function). If you want to be able to access global variables inside a function body you need to tell Python

 def mendedFunc():
global age
    print(age)

Code in the body of mendedFunc function can now access age (and also change it). Forcing programmers to explicitly state when they are using global resources in their code helps prevent errors which would be caused if the same variable name is used in more then one context. If one part of the program is manipulating the age of a person, and another part of the program is manipulating the age of the house they want to buy, we don’t want these getting mixed up when the program runs.

Python Shorts: 09 Dictionary madness

You can have all kinds of fun with dictionaries.

First off, you can add things to a dictionary any time you like:

z={"name":"Anne","age":21}

This makes a dictionary called z

z["address"]="18 Pussycat Mews"

This adds an address item to the dictionary. But for super fun you can use any kind of value as a key for an item:

z[1.5]="This is crazy"

This uses the value 1.5 as a key. What with computer floating point maths not being as accurate as you might like, using floating point values as keys to dictionary entries is not advisable, but using integers can be very sensible. And if you are doing things like counting the number of letters in text, or putting ranges of values into buckets you can use dictionaries to very good effect.

Minecraft the Movie

We went to see Minecraft the movie. The seats in the cinema were very comfortable. The images on the screen were bright and sharp. The popcorn was tasty. That’s it.

Saying Minecraft is a bad movie kind of misses the point. I don’t consider it a movie. It’s just a collection of stuff that happens, often involving explosions and improbable physics. I didn’t expect Shakespeare, but I did expect something. The dialogue is sub-bad. The exchange "Have you finished?” - “No I think he’s from Sweden” is one of the highlights.

Jack Black must have taken one look at the script and decided that the only way to get through it was to go into “super-turbo” mode. If they ever make a film like this with both him and Jim Carey in leading roles we could probably power the planet with it.

Minecraft has been very successful. Which is depressing. I think it is just that at this time of year folks are looking for somewhere dark and comfortable to sit for a while.

Python Shorts: 08 Dictionary Fun

Dictionaries are fun. As we saw last time we can use them to create lumps of data with named contents:

z={"name":"Anne","age":21}

This makes a dictionary called z with two things inside it, name and age. We can get these out by name (as it were):

n = z["name"]

One thing to watch out for is that you need to get the search item (or key as it is called) exactly right:

n = z["Name"]

This would end badly, with an exception which will stop your program:

KeyError: name

If you are worried about your program crashing when you try to get something out of a dictionary, you can use the in operator to check:

if "name" in z:
print("we have a name")

As a side note, I’m using square brackets to enclose the key we want to find. You can use the get function instead:

n = z.get("name")

This would set n to the name in z.

More on dictionaries later, as we explore dictionary madness.

Python Shorts: 07 Dictionaries

You may have spotted a problem with lists and tuples. When we talked about functions we worried about the situation where we use the wrong order of parameters to a call. We can get the same problem with lists and tuples:

The statement above would set the age of person y to “James”, which would not be a good thing if the age value was stored in location 1. It would be lovely if we had a data structure that let us explicitly name the data elements in it. It turns out that we do, and it is called a dictionary:

z={"name":"Anne",
"age":21}

When you make a dictionary you give it a set of key – value pairs. This means that everything that is stored has a name – the key which is used to access it. The dictionary referred to by z has two keys, name and age. You can use these to get hold of the values:

n = z["name"]

The above statement gets the value of the name item in z. In this case the value of n would be “Anne”. Dictionaries are fun. We’ll have more about them in the next short.

Python Shorts 06: List Fun

Python lists are nice. We can make them very easily:

x = [1,2,3]

The order of the list is preserved. If we work our way through the elements they will always come out in the same order. We can use the len function to find out how many things are in a list:

l = len(x)

If we want to add something to a list we can use the append behaviour provided by lists:

x.append(5)

This will pop 5 on the end of the list. There’s no “prepend” function for putting something at the start of a list. Instead there’s an insert function that can be used to insert something at a particular position:

x.insert(0,0)

This statement would put the value 0 at the start of list x. You can use the remove behaviour to get rid of an element at a particular position in the list and pop, which removes an item and returns it.

Python Shorts 05: Lists

Making a list looks very like making a tuple:

y = ["Jim",25]

The statement above makes a list called y. Note the use of square brackets, which is different from how we make a tuple (which uses round brackets). Lists are a lot more flexible than tuples. For one thing we can change the content of their elements:

y[0]="James"

This statement changes the item at the start of y to “James”.

Python Shorts 04: Tuple of One

We’ve seen that we can create a tuple by using brackets to “squish” things together:

x = (“Rob”,21)

Tuples are very useful if you want to return multiple values from a function:

return (“Rob”,21)

This lets me return name and age values. However, sometimes you might want to return just one item in a tuple. You might think you do this:

x = (1)

However, this doesn’t work. Python thinks that the brackets are part of an expression, gets rid of them and puts the value 1 in x. If you want to make it clear to Python that you are making a tuple, put a “spare” comma on the end:

x = (1,)

This would “tupleise” the value.

Python Shorts 03: Tuples

Tuples should be called “lumps”. You can squish things together to make a lump. Tuples let you squish data together.

x = ("Jim",25)

The statement above creates a tuple called x which contains name and age information. Tuples can contain lots of data. The best way to unpick them is to use a cunning assignment:

(name,age)=x

This creates variables called name and age which hold “Jim” and 25 respectively.  Another way to get values out of a tuple is to index it:

name=x[0]

age=x[1]

The item at the start of the tuple has index value 0. Tuples are read only:

x[0]="James"

The statement above tries to change the in the x tuple. This will not work. Tuples are great for passing lumps of data around a program but no good for things you might want to modify. If you want to be able to change things in a lump of data you need use a list.

I find tuples very useful, but I do worry that the thing making the tuple and the thing using the tuple have to agree on the order of the elements. As we saw with name and age in function parameters this might lead to confusion. If you want both ends of a conversation to be absolutely clear about which data means what, you can use dictionaries to do that, but they are coming later.

Python Shorts 02: Default parameter values in functions and methods

We’ve seen how to make parameters clearer in calls, now let’s add some magic to the function itself. Sometimes we might only have the name of the person, can we make an add_person which will handle only one input? Yes, we can.

def add_person(name, age=3):
   print("Adding a person")

The code above creates an add_person function which has name and age parameters. The age parameter is set to 3 if it is missed out. Programmers call the value 3 the “default” value.

add_person(name="Simon")

This would add a person with the name Simon with age 3. You may be wondering why I picked 3 as the default. If we were writing a system to control access to fairground rides, we want to make it as safe as possible. Simon would only be able to go on rides which are suitable for 3-year-olds. If they want to go on the bigger rides, they must give their age.

add_person(name="Rob")

Note that if you want to use default values like these you must put the parameters with the default values at the end of the parameter list when the function is defined.

Get to sleep using your kitchens

If you are having bother getting to sleep, spend some time walking down memory lane thinking about kitchens. Works for me. Thinking about stuff that hasn’t happened yet gets the brain whizzing with plans and things to do. But thinking about stuff in the past is quite different (at least for me). So at the moment I’m working my way through the various kitchens we’ve had over the years. The memories are all good ones - like when we used to have a high chair and baby food all over the floor.

if you’re having trouble getting to sleep think about something that you liked doing in he past and see if it works for you..