Chatgpt Made This

About the project

Experimenting with outsourcing a project to ChatGPT to make a nice festive animated Christmas Tree on a Unicorn HAT and do the write up too!

Project info

Difficulty: Easy

Platforms: Raspberry PiPimoroni

Estimated time: 1 hour

License: GNU General Public License, version 3 or later (GPL3+)

Items used in this project

Hardware components

Pimoroni Unicorn HAT HD Pimoroni Unicorn HAT HD x 1
Raspberry Pi Zero Raspberry Pi Zero x 1

Software apps and online services

gpt chat gpt chat

Story

Outsourcing to a Robot

Everyone's talking about ChatGPT at the moment and I am currently at the end phase of a long project that's a bit of a pain to get over the line, it's been a while since I posted something; so I thought why not outsource a little festive project to a robot?

I used ChatGPT (which you can sign up for for free) and asked it to give me some code that would generate an animated Christmas tree on the Unicorn HD HAT as well as write the blog post for me.

Here's the first attempt that generated a relatively tree looking animation and blog post to go with it; using the request "Write a 314reactor blog post about a project that draws a christmas tree on a raspberry pi unicorn hd with python code":

Are you looking to add some holiday cheer to your Raspberry Pi project? Look no further! In this post, we will show you how to create an animated Christmas tree using Python and the Unicorn HAT HD Raspberry Pi display.
First, let's take a look at the code:
import unicornhathd
from time import sleep
from random import randint

# Initialize the UnicornHathd display
unicornhathd.rotation(0)
unicornhathd.brightness(0.75)

# Set the initial colors for the tree
tree = [
(0, 100, 0), # green for the tree base
(0, 255, 0), # bright green for the tree trunk
(255, 0, 0), # red for the tree lights
(255, 255, 0), # yellow for the star on top
]

# Animate the tree
while True:
# Update the tree colors
tree[2] = (randint(0, 255), randint(0, 255), randint(0, 255)) # change the tree lights to a random color
tree[3] = (randint(0, 255), randint(0, 255), randint(0, 255)) # change the star to a random color

# Draw the tree on the UnicornHathd
unicornhathd.clear()
unicornhathd.set_pixel(1, 6, tree[0][0], tree[0][1], tree[0][2])
unicornhathd.set_pixel(2, 6, tree[0][0], tree[0][1], tree[0][2])
unicornhathd.set_pixel(3, 6, tree[0][0], tree[0][1], tree[0][2])
unicornhathd.set_pixel(2, 5, tree[1][0], tree[1][1], tree[1][2])
unicornhathd.set_pixel(2, 4, tree[1][0], tree[1][1], tree[1][2])
unicornhathd.set_pixel(2, 3, tree[1][0], tree[1][1], tree[1][2])
unicornhathd.set_pixel(1, 2, tree[2][0], tree[2][1], tree[2][2])
unicornhathd.set_pixel(2, 2, tree[2][0], tree[2][1], tree[2][2])
unicornhathd.set_pixel(3, 2, tree[2][0], tree[2][1], tree[2][2])
unicornhathd.set_pixel(2, 1, tree[3][0], tree[3][1], tree[3][2])
unicornhathd.show()

# Pause for a moment before updating the colors again
sleep(0.25)
This code will animate a Christmas tree on a Unicorn HAT HD Raspberry Pi display. The tree will consist of a green base, a green trunk, red tree lights, and a yellow star on top. The colors of the tree lights and star will be randomly changed every quarter second, creating an animated effect.
To use this code, you will need to have the unicornhathd library installed on your Raspberry Pi, as well as the random and time libraries. You will also need to have a Unicorn HAT HD connected to your Raspberry Pi.
The unicornhathd.rotation(0) line in the code sets the rotation of the display to 0 degrees. If you want to rotate the display in a different way, you can change this value to the desired rotation in degrees (e.g. unicornhathd.rotation(90) to rotate the display 90 degrees). You can also adjust the brightness of the display using the unicornhathd.brightness() function (the value should be between 0.0 and 1.0, with 1.0 being the brightest).
You can easily modify the code to fit your specific needs and hardware setup. For example, you could change the colors of the tree or the speed of the animation by modifying the values in the tree list or the sleep() function, respectively.
One way to improve this code to make it more like a Christmas tree is to add more lights to the tree. Currently, the tree only has three lights, which is not very realistic. You could add more lights to the tree by modifying the code that draws the tree on the Unicorn HAT HD display. For example, you could add additional unicornhathd.set_pixel() calls to draw additional lights on the tree.
Another way to improve the code is to make the tree lights blink, which is a common characteristic of Christmas tree lights. To do this, you could add an additional loop inside the main while loop that controls the animation of the tree. This loop could iterate over the tree lights and turn them on and off repeatedly, creating a blinking effect.
Additionally, you could change the colors of the tree lights to more realistic colors, such as red, green, and blue. This would make the tree look more like a traditional Christmas tree. You could do this by modifying the values in the tree list to use the desired colors. For example, you could change the (255, 0, 0) tuple in the tree list to (255, 0, 0), (0, 255, 0), and (0, 0, 255) to use red, green, and blue colors for the tree lights.
Overall, by adding more lights, making the lights blink, and using more realistic colors, you can improve this code to make it more like a Christmas tree.
Try out this code and add some holiday cheer to your next Raspberry Pi project!

Iterative Improvements

So that's pretty cool. It did the job I asked it too and the code only needed a bit of tweaking - it can also take a few attempts to get some decent code to start of with. But the write up it gave is pretty awesome - I could have just pasted it in and pretended it was me!

But I wasn't initially happy with the tree; it was generating this:

Which is a bit of a small funny lookin' tree - so I pasted the code back into GPTChat and asked it to make the tree bigger and it said the following:

To make the Christmas tree bigger in the code, you could use a loop to set multiple pixels at once. This will make it easier to create the different parts of the tree and make the tree look more realistic.
Here is an example of how you could modify the code to create a bigger Christmas tree:
import unicornhathd
from time import sleep
from random import randint

# Initialize the UnicornHathd display
unicornhathd.rotation(0)
unicornhathd.brightness(0.75)

# Set the initial colors for the tree
tree = [
(0, 100, 0), # green for the tree base
(0, 255, 0), # bright green for the tree trunk
(255, 0, 0), # red for the tree lights
(255, 255, 0), # yellow for the star on top
]

# Animate the tree
while True:
# Update the tree colors
tree[2] = (randint(0, 255), randint(0, 255), randint(0, 255)) # change the tree lights to a random color
tree[3] = (randint(0, 255), randint(0, 255), randint(0, 255)) # change the star to a random color

# Draw the tree on the UnicornHathd
unicornhathd.clear()

# Draw the tree base
for i in range(5):
for j in range(5):
unicornhathd.set_pixel(i, 6, tree[0][0], tree[0][1], tree[0][2])

# Draw the tree trunk
for i in range(3):
unicornhathd.set_pixel(i+1, 5, tree[1][0], tree[1][1], tree[1][2])
unicornhathd.set_pixel(i+1, 4, tree[1][0], tree[1][1], tree[1][2])
unicornhathd.set_pixel(i+1, 3, tree[1][0], tree[1][1], tree[1][2])

# Draw the tree lights
for i in range(3):
unicornhathd.set_pixel(i+1, 2, tree[2][0], tree[2][1], tree[2][2])
unicornhathd.set_pixel(i+1, 1, tree[2][0], tree[2][1], tree[2][2])

# Draw the star on top
unicornhathd.set_pixel(2, 0, tree[3][0], tree[3][1], tree[3][2])

unicornhathd.show()

# Pause for a moment before updating the colors again
sleep(0.25)
In this modified code, the tree is created using loops that set multiple pixels at once. This makes it easier to create the different parts of the tree, and the tree looks more realistic. You can further customize the code to make the tree even bigger or add more details to the tree.

The Final Iteration?

That worked nicely and made this slightly better looking tree:

It's really impressive how it can understand and improve the code with natural language requests, like "improve this code and make the Christmas tree bigger" and including the code.

So realising it could improve its own code I asked it to add more branches to the tree. This one took a few attempts as it seems when the reply is quite long it tends to keep stopping half way through and giving up:

Not ideal

Not ideal

Not ideal

After hitting "Try again" a bunch of times I managed to get this:

To give the tree more branches, we can add more rows of lights on top of the existing ones. For example, we can add a row of lights on the bottom part of the star. We can do this by adding the following code after the existing code that draws the tree lights:
# Draw the bottom part of the star
unicornhathd.set_pixel(1, 0, tree[2][0], tree[2][1], tree[2][2])
unicornhathd.set_pixel(3, 0, tree[2][0], tree[2][1], tree[2][2])
This will add two more lights to the bottom of the star, giving the tree a more full and detailed appearance.
We can also add more branches to the tree by drawing additional rows of lights below the existing ones. For example, we can add a row of lights on the second and third rows of the tree trunk. We can do this by adding the following code after the existing code that draws the tree lights:
# Draw additional branches on the tree
for i in range(3):
unicornhathd.set_pixel(i + 1, 2, tree[2][0], tree[2][1], tree[2][2])
unicornhathd.set_pixel(i + 1, 3, tree[2][0], tree[2][1], tree[2][2])
This will add two more rows of lights to the tree, giving it a fuller and more detailed appearance.
Additionally, we can also make the tree lights flash by adding a simple conditional statement that alternates between drawing the tree lights and not drawing them on each iteration of the main loop. This can be done by replacing the existing code that draws the tree lights with the following code:
# Alternate between drawing and not drawing the tree lights
if tree[2][0] == 0 and tree[2][1] == 0 and tree[2][2] == 0:
# Draw the tree lights
for i in range(3):
unicornhathd.set_pixel(i + 1, 2, tree[2][0], tree[2][1], tree[2][2])
unicornhathd.set_pixel(i + 1, 1, tree[2][0], tree[2][1], tree[2][2])
else:
# Don't draw the tree lights
for i in range(3):
unicornhathd.set_pixel(i + 1, 2, 0, 0, 0)
unicornhathd.set_pixel(i + 1, 1, 0, 0, 0)
This code will alternate between drawing the tree lights and not drawing them on each iteration of the main loop, giving the appearance of the lights flashing on and off.

Which resulted in:

Not the best improvement, so I gave it a few more attempts, maybe this was the limit?

Eventually it gave me some additional branch code:

unicornhathd.set_pixel(0, 3, tree[1][0], tree[1][1], tree[1][2])
unicornhathd.set_pixel(4, 3, tree[1][0], tree[1][1], tree[1][2])
unicornhathd.set_pixel(1, 2, tree[1][0], tree[1][1], tree[1][2])
unicornhathd.set_pixel(3, 2, tree[1][0], tree[1][1], tree[1][2])
unicornhathd.set_pixel(1, 1, tree[1][0], tree[1][1], tree[1][2])
unicornhathd.set_pixel(3, 1, tree[1][0], tree[1][1], tree[1][2])

So it's giving small improvements - but maybe there's a bit more to go, it's still not quite a tree. So another re-paste of the latest code and asking it to improve the code it gave some neat suggestions:

Here is one way to improve the code to make the Christmas tree look better:
Use more meaningful variable names to make the code more readable. For example, instead of using tree as the variable name for the colors of the tree, you could use something like tree_colors.
Use more meaningful variable names to make the code more readable. For example, instead of using tree as the variable name for the colors of the tree, you could use something like tree_colors.
Use a more structured approach to draw the tree, such as using nested for loops to draw each part of the tree (e.g. the base, the trunk, the branches, the lights, and the star) instead of using multiple independent sets of for loops.
Use a more structured approach to draw the tree, such as using nested for loops to draw each part of the tree (e.g. the base, the trunk, the branches, the lights, and the star) instead of using multiple independent sets of for loops.
Use a more realistic color scheme for the tree. For example, instead of using a single color for the entire tree base and trunk, you could use different shades of green to give the tree a more natural look. You could also use different colors for the tree lights, such as red, green, and white, instead of randomly changing their colors.
Use a more realistic color scheme for the tree. For example, instead of using a single color for the entire tree base and trunk, you could use different shades of green to give the tree a more natural look. You could also use different colors for the tree lights, such as red, green, and white, instead of randomly changing their colors.

Along with some code improvements:

# Set the initial colors for the tree
tree_colors = [
(0, 100, 0), # dark green for the tree base
(0, 200, 0), # green for the tree trunk
(255, 0, 0), # red for the tree lights
(255, 255, 0), # yellow for the star on top
]

And another line for the lights with a small tweak from me:

tree_colors[2] = (randint(200, 255), 0, 0)  # change the tree lights to red

And we get:

Different colours along the tree base and trunk/branches

And in motion, can just about see the red lights pulsing:

After one final request of "how do I modify the following code to give the christmas tree longer branches and a pointed top?" and re-running the question a few times I ended up with:

To give the Christmas tree longer branches, you could increase the range of the for loop that draws the branches on the tree. For example, you could change the line for i in range(3): to for i in range(4): to add one more branch to the tree.
To give the tree a pointed top, you could add additional pixels to the top of the tree. For example, you could add the following lines after the lines that draw the tree trunk:
# Draw a pointed top for the tree
unicornhathd.set_pixel(1, 2, tree_colors[1][0], tree_colors[1][1], tree_colors[1][2])
unicornhathd.set_pixel(3, 2, tree_colors[1][0], tree_colors[1][1], tree_colors[1][2])
This would add two additional pixels to the top of the tree to create a pointed top. You could experiment with different positions and colors for these pixels to achieve the desired appearance for the tree's top.

and

To give the Christmas tree longer branches, you can modify the code by adding more pixels to the branches that are drawn on the UnicornHathd display. For example, you can add the following lines of code to draw additional branches on the tree:
# Draw additional branches on the tree
for i in range(3):
unicornhathd.set_pixel(i + 1, 2, tree_colors[2][0], tree_colors[2][1], tree_colors[2][2])
unicornhathd.set_pixel(i + 1, 3, tree_colors[2][0], tree_colors[2][1], tree_colors[2][2])

unicornhathd.set_pixel(0, 3, tree_colors[1][0], tree_colors[1][1], tree_colors[1][2])
unicornhathd.set_pixel(4, 3, tree_colors[1][0], tree_colors[1][1], tree_colors[1][2])
unicornhathd.set_pixel(1, 2, tree_colors[1][0], tree_colors[1][1], tree_colors[1][2])
unicornhathd.set_pixel(3, 2, tree_colors[1][0], tree_colors[1][1], tree_colors[1][2])
Alternatively, you can also modify the for loop that draws the branches to have a larger range, like this:
# Draw additional branches on the tree
for i in range(5): # changed the range to 5 instead of 3
unicornhathd.set_pixel(i, 2, tree_colors[2][0], tree_colors[2][1], tree_colors[2][2])
unicornhathd.set_pixel(i, 3, tree_colors[2][0], tree_colors[2][1], tree_colors[2][2])

unicornhathd.set_pixel(0, 3, tree_colors[1][0], tree_colors[1][1], tree_colors[1][2])
unicornhathd.set_pixel(4, 3, tree_colors[1][0], tree_colors[1][1], tree_colors[1][2])
unicornhathd.set_pixel(1, 2, tree_colors[1][0], tree_colors[1][1], tree_colors[1][2])
unicornhathd.set_pixel(3, 2, tree_colors[1][0], tree_colors[1][1], tree_colors[1][2])
Either of these modifications will make the branches of the Christmas tree longer on the UnicornHathd display.

Which gave me:

It was also still able to give other suggestions, but they weren't always effective:

To modify the code to give the Christmas tree longer branches and a pointed top and to center the tree on the Unicorn HD display, you can try the following:
Make the branches longer by modifying the for loops that draw the branches. For example, you can increase the range of the for loop from 3 to 6 to make the branches twice as long:
for i in range(6):
unicornhathd.set_pixel(i + 1, 2, tree_colors[2][0], tree_colors[2][1], tree_colors[2][2])
unicornhathd.set_pixel(i + 1, 3, tree_colors[2][0], tree_colors[2][1], tree_colors[2][2])
To give the tree a pointed top, you can draw additional branches at the top of the tree. You can do this by adding more pixels to the for loop that draws the bottom part of the star:
Copy code
for i in range(3):
unicornhathd.set_pixel(1, i, tree_colors[2][0], tree_colors[2][1], tree_colors[2][2])
unicornhathd.set_pixel(3, i, tree_colors[2][0], tree_colors[2][1], tree_colors[2][2])
To center the tree on the Unicorn HD display, you can adjust the coordinates of the pixels that are drawn. For example, instead of drawing the tree at coordinates (i, j), you can draw the tree at coordinates (i + 1, j + 1) to shift the tree one pixel to the right and one pixel down.
# Draw the tree base
for i in range(5):
for j in range(5):
unicornhathd.set_pixel(i + 1, j + 1, tree_colors[0][0], tree_colors[0][1], tree_colors[0][2])

# Draw the tree trunk
for i in range(3):
unicornhathd.set_pixel(i + 1, j + 1, tree_colors[1][0], tree_colors[1][1], tree_colors[1][2])
unicornhathd.set_pixel(i + 1, j + 1, tree_colors[1][0], tree_colors[1][1], tree_colors[1][2])
unicornhathd.set_pixel(i + 1, j + 1, tree_colors[1][0], tree_colors[1][1], tree_colors[1][2])

So it's still giving good suggestions - but lets try something entirely fresh without any code going into the message - "python code that draws an animated christmas tree on a raspberry pi unicorn hd in the centre".

After a few runs it was returning some good code that had improvements such as attempting again to have a pointed top and drawing the tree in the middle of the Unicorn HAT. However, it wouldn't finish the code no matter how many attempts I tried, always stopping here:

Which is a shame as I think if it carried on it would have drawn up code for a larger centre stage tree with maybe a pointed top and some extra branches after a few more iterations; but I think that's where I'll stop for now.

The final tree looks like:

What a journey.

Conclusion

This may have code in it similar to something someone else made or even some similar blog text to something that already exists, so keep that in mind and let me know if you want it taken down if the bot has blatantly copied something that a human made.

It also took a good few attempts in the first instance to get some code from it that would actually draw something resembling a tree, and required a couple of minor tweaks such as fixing an import or two.

It's just a shame it tends to stop half way through generating some responses - I'm not sure if anyone else has experienced this or if there is a workaround. It would also run into problems where the entire thread would need to be reset before it would generate new replies.

It's not exactly a perfect Christmas Tree and some of the code didn't work, I can see why they banned GPTChat code from Stackoverflow, but it's very impressive how it could improve its own code when asked and the Tree looked more tree-ish in the end! I was originally just going to stick with the first iteration of generated code and blog post but when I discovered it would improve/offer suggestions on its own code it became a larger experiment.

It will also describe code and find bugs and offer suggestions; so I may run some of my existing projects through it and see what it says! It's also very cool that it also adds comments into the code.

Hopefully in future as the tech improves my entire project pipeline can be automated, next time I may get it to write a video script for me. Given how fast ML tech is progressing I imagine it won't be long before it's producing really good code and text first time.

I think as things move forward from now we will be abstracting up and away from code and architecture and getting specially trained models like GPTChat to generate things for us - using natural language requests, like:

"make me a eks cluster that loads up an image from ecr to run a web application behind an elb please and generate security groups that will allow port 443 to port 8080 internally only, also generate me a dockerfile that will build a node.js frontend, then generate some autoscaling tests for it"

And the AI will build it all for you - maybe even within its own 'imagination' like the VM someone built within GPTChat. I imagine then once the AI has built this it would maybe take a few manual tweaks from a human - engineering will move from coding and scripting to high-level planning and delegating to a machine.

Maybe even moving from actual infrastructure to just everything running within the machines mind... who knows; could end up like that scene in Star Trek in the holodeck: "computer make me a table".

That's just my opinion though, let me know what you think!

Either way it's an exciting and hopefully automated robot assisted future...

Hello

Hello

Code

Christmas Tree Animation

Christmas Tree animation python code for the Unicorn HAT HD (generated by GPTChat)

Credits

Photo of 314Reactor

314Reactor

Technology loving nerd with a passion for trying to bring SciFi to life.

   

Leave your feedback...