Table of Contents

Introduction

I’ve previously written about writing applications with ChatGPT. Now I am writing about using ChatGPT as a coding tutor.

Background

I have always struggled to find application software coding projects to improve with. I’ve not been driven primarily in that space, but as a result I have struggled to improve my coding chops. I do get to do some ‘proper coding’ in the day job but it is occasional and limited. Where I have tried to up my game with book and video courses I have found that the learning is never suitably paced. Typically it’s too slow at the beginning and then suddenly too fast - classic ‘How to draw an Owl’ Territory:

How to draw an owl meme

Beyond that, I’ve found that the moment I go ‘off-piste’ and try to e.g. add a feature to a worked example, I tend to open a can of worms - there’s often simply no easy or obvious way to extend what I have without completely re-doing it, which, whilst understandable for a tutorial example, of course negates the point. Add to that the classic ‘X and Y problem’:

The XY problem is asking about your attempted solution rather than your actual problem. This leads to enormous amounts of wasted time and energy, both on the part of people asking for help, and on the part of those providing help.

I would point out that you can fall victim to the XY problem despite your own best efforts in trying to figure out how to do something. Especially in a new area of knowledge, you don’t know what you don’t know. I find that I often haven’t had enough context to accurately frame the question for e.g. a Google search.

How else could I tackle this?

What has worked for me with personal projects and in the day job has been:

  • Having a clear idea of the problem to solve and its boundaries
  • Having a sound context for what a ‘good’ solution would look like
  • Being able to find relevant expertise or advice for the odd ‘gap’

How to replicate this for my own learning?

I wanted to improve my Python coding. I have done some trivial stuff with Python in the past but nothing serious. I have done some coding with Golang but that’s a very different language. I’ve discussed previous attempts at structured study above. Let’s find some simple projects online and try and tackle these in the way I would tackle a work project with the aim of building some Python fundamentals.

First attempt

I thought it might be an idea to look at some of the old ‘Advent of Code’ challenges. I don’t think it’s unfair to say that these are beyond tutorial examples- they’re clearly pitched at people who are able to decompose the problems presented and map that to tooling and methods in whatever language. Initially this was too far out for me - I would return later.

Second attempt

I decided to look for lists of tutorial Python projects. I found one that seemed to have a few good projects although it is clearly pretty uneven- the first five are all command line single-page projects:

  1. Mad Libs Generator
  2. Number Guessing
  3. Text-based Adventure Game
  4. Dice Rolling Simulator
  5. Hangman

and then number 6 is a GUI app with an SQLite backend! 🤯

OK, so I have a clear idea of what sort of projects I want to tackle (and avoid!) plus a few suggestions. The Upgrad site is trying to link to their own online course so they don’t provide ready examples but these are sufficiently generic projects/problems that many other people do, and also it’s fairly easy to look up, e.g. ‘string variable substitution’. I was able to get through these about one-a-day after work and add my own convenience features:

Mad-Libs

I found an example walkthrough online. It’s okay but I wanted to make some changes:

  • I wanted the grammar to be correct
  • I wanted to loop requesting user input rather than having a whole lode of boilerplate around each request
  • I wanted defaults offered to the user so that I wasn’t going through typing 13 different interactions to test my code each time

Working with ChatGPT I was able to explore all of these. I was careful to avoid having ChatGPT write the entire program. When I had a running program I asked for changes to be made to the story and ChatGPT additionally changed the output from string concatenation to printf format which makes a lot of sense.

Number Guessing

Here I didn’t look up a worked example. I was able to research subtopics like ‘how to create a random number in Python’ myself. When I had something that was almost there but broken I asked ChatGPT to diagnose e.g. broken functions. Again I did not have ChatGPT write the whole program for me but I did ask for review when I had something running and made some iterations with tha. Unsurprisingly progress was speedy!

I then decided to re-implement this project in Golang to see the difference in the two languages. I’d recently done something similar (entirely with ChatGPT, no manual coding) implementing a Caesar Cipher in Python, Golang and BASH. I immediately fell down on the syntax, which I should have know but was in a Python haze… ChatGPT was able to assess the context of what I was doing and give detailed critiques on my errors, even some quite subtle ones.

Other Upgrad examples

I can’t recall all the details at this point but I do recall that for ‘Hangman’ I wanted to get an online list of English words- I typically use CSpell based spellchecking in my text editor - so I did

from english_words import get_english_words_set

Back to ‘Advent of Code’

Given that I did not want to jump to GUI/SQL examples at this point I decided to go back to look at ‘Advent of Code’ (2022). These are clearly considerably beyond tutorial level. Here progress has been far more nuanced and less structured. Yes, I can decompose the problem and propose a starting point but I find that I have had to often look at other people’s solutions to get some of the nuances of the problem. For instance, for day 5 I was completely stumped parsing the input, even where I ’thought’ I had got it, I hadn’t, and as I have found before with ChatGPT, it struggled with the looseness of Python. In the end I had to defer to someone else’s (Galaxy Inferno’s) described example and sample code Yes it works, it’s very clever but I wasn’t really keen on the whole classes approach for such a simple problem or ready to tackle Jupyter notebooks. I stuck with her for day 6 after flapping about on my own - a very succinct solution but when I got to day 7 I had to give up. Her solution is 110 lines of class based code when another example is only 38.

By this point I felt that I had got the hang of using

with open('input.txt', 'r')as f:

For collecting my input (trivial, I know). and some awareness of what numpy and pandas are useful for.

Now things might become interesting

Now I was not just decomposing problems but evaluating alternative approaches. By day 8 challenge I was able to recognise that I needed a solution for evaluating numbers in a matrix, welcome back numpy but I needed help on the syntax for addressing elements in a matrix. I made heavy use of ChatGPT here but part 2 was getting heavily bogged down and my proposed answers were off. In retrospect, the test example should have been enough, but I decided to look for an example of what good looked like. I had given up on galaxyinferno’s solutions as well beyond what I was trying to focus on and I came across a solution ‘in pure TensorFlow’. This code is astonishing in several respects. It didn’t seem to be especially long or complicated and appeared to have a simple structure. The performance though… I thought the code was broken and cancelled and re-called it several times, but yes it really does take 24 seconds to run on an M2 MacBook Pro 🤯:

$time python3 tf-aoc.py 
part 1:  1835
part 2:  263670

real    0m23.089s
user    0m23.715s
sys     0m1.741s

by comparison the (two-part) solution I had arrived at with ChatGPT using NumPy (times are for finished version of code giving correct answers):

$time python3 grid-check-pt-1.py 
Hidden Trees Count: 7966
Visible Trees Count: 1835

real    0m0.154s
user    0m0.987s
sys     0m0.095s
$ time python3 grid-check-pt-2.py 
The maximum scenic score for any tree is 263670

real    0m0.120s
user    0m0.740s
sys     0m0.029s

Of course I still ’needed’ the TensorFlow example in order to assess ‘good’ but I was still getting the wrong answers. At this point I went round and round with ChatGPT but I could not quite see the problem, and plainly neither could ChatGPT. I went away and came back several times, but it wasn’t until I started concentrating on the test example in the brief, which is simple enough to calculate manually, that I could get something that I could work with to identify the issue, doing things like printing out the score factors for each entry. ChatGPT was advising routines like this:

    # Count in the left direction
    for k in range(j - 1, -1, -1):
        if matrix[i, k] < height:
            count_left += 1
        else:
            break  # Stop counting if a taller or equal tree is found

for each direction. When it actually needed to be

    # Count in the left direction
    for k in range(j - 1, -1, -1):
        count_left += 1
        if matrix[i, k] >= height:
            break  # Stop counting if a taller or equal tree is found

For the purpose of the problem in question the difference is in counting exclusively of the taller tree (first version) versus inclusively (second version).

This is the first solution attempt that I feel able to publish. The licensing generally isn’t clear for solutions provided by or based on those provided by other people but this is one that I decomposed and came up with the basic design for myself.

(P.S.) - Interim Conclusions

ChatGPT is a patient and well-read teacher, always ready to give context-sensitive review and suggestions. All of the usual caveats apply, as for any other use of ChatGPT, but here I would suggest two more- the requirement for good self discipline, both regarding what advice to request, and also to try and and decompose the problem yourself. It is very easy to just say ‘give me a solution’, harder to evaluate it, but harder still to say ‘don’t do $(thing), I want to work that out for myself’. Accepting that however, it’s great. Compared to how I have struggled with written, online and video-based courses in the past, it’s wonderful to be able to address what I myself consider to be meaningful and/or enjoyable challenges. I can riff on the same or a related topic any number of times as I might want to consolidate it and there are no ‘slow bits’ that I already know. I can freshen things up with my own ideas without having to fear that a small digression on my part will drag me into endless weeds. I can also see that as I engage rather than slavishly follow that the learning is consolidating, not merely resting to soon fade away as so often has happened in the past. Perhaps sometime I will try asking ChatGPT to set some exercises on particular topics