I’ve been using Gemini since 1.0 was in beta. I’ve used AI Studio to create arrays of math problems, answers and hints in JSON format for our games, then put it aside. I’ve used Gemini to create scripts to organize thousands of image files in our company workspace. Still, AI is not something I used on a regular basis when coding. So, this week I decided to give it a shot
The task: split a block into two, creating one that is “fancy flash cards” and a second, more versatile block
Let me explain. Our games are made in blocks, using our proprietary 7 Gen Blocks platform. When a block seems too complicated for a novice developer to use, I split it into two blocks.
The original block could be used as flash cards- click on the card, it flips over with an image or text. A dialog box pops up and gives you more information, and optionally, an audio file plays. It could also be used for assessment, with one of the cards being “correct”, for example, click on the cardboard box with a picture of a primary source. It could also be used as instructional, from You are Here: On the Lewis & Clark Trail, click on an image anywhere in the page and another image appears. In the example below, any item you click on is replaced with the item you would get in trade, and a dialog box pops up with more explanation.
Step 1 (human): I copied the block into a new directory and renamed it “flash cards”.
Step 2 (human): I realized that since the initial block went to the next page when a specific correct card was selected, and in this case, there was no “correct” card, it never went to the next page. There was already a goToNextPage function but it wasn’t being called.
Step 3 (human): I copied all of the code into Gemini pro and gave the prompt, “Edit this code so that when the total number of cards clicked = the totalCards property of the options object, it goes to the page specified in the completionURL”.
Step 4 (AI) : Got it in one. Yes, I do know this was a very simple modification. It added this to the code:
let clicks = 0; // Counter for the number of clicks.
// Added correctly in the startGame function
function startGame() {
// Reset state for each new game
clicks = 0;
.....
// Added correctly on click
$(".cards").on("click", async function() {
if (!$(this).hasClass('cards')) return;
clicks++;
....
const totalCardsInOptions = options.totalCards || 0;
....
// Check for game completion based on the total number of clicks.
if (clicks >= totalCardsInOptions && options.completionURL) {
window.location.href = options.completionURL;
}
My point was to see if it could do something quite simple to code that is NOT at all simple. Sure, any half-way decent developer could have done this, but they would have needed to read the code first to find the startGame function and function when the cards are clicked. Gemini did this in seconds. I’m familiar with this code, so I probably could have done it in less than five minutes, but Gemini was still faster than me.
Step 5 (human): I decided I wanted the option to have more cards than would fit across the screen and to have cards replaced from the total cards until all were used. I gave this prompt, “Edit the code so that if totalCards > numberToDisplay , when the dialog box for a card is clicked, that slot is filled with a new card until the number of cards that has been displayed = totalCards “
Step 6 (AI and human): Although this seems a fairly simple modification, Gemini failed at it several times. On its first effort, when I clicked on any card, it went on to the next page. I added this prompt, “This doesn’t work. When I click the first card and then close the dialog box, it goes to the next page. It never gets to the const shouldReplace = totalCards > numToDisplay;“
On the second try, it showed it’s thinking (good) because I could then respond to its statement of the reason the code was not working, “That is not the problem. None of the cards have a distinguishedItem or goToPage property. This code still has the same problem.”
On the third failed attempt, it had me add some debugging statements and then copy the results from the console and paste the response as the next “prompt”. Then Gemini told me that the program now worked. Spoiler alert: It did not.
On the fourth attempt, it now went to the next page after two cards were clicked, instead of one. I pasted this in to the prompt “Still not working. Now it goes to the completionURL when two cards have been clicked. It should not go to the completionURL until the number of cards clicked = options.totalCards“
On the fifth attempt, it finally worked.
Step 7 (human): I decided teachers might want a delay before the card is displayed so students had more time to read it. I added this prompt, “Add a feature so that if an option in the config file exists, options.timeToRemove , after options.timeToRemove seconds that a card was clicked, it will be removed from the screen.“
Step 8 (AI and human): The first attempt did not work. I looked at the code and gave this prompt, “This did not work. I think the fadeout method is the problem. Perhaps it doesn’t exist. $clickedCardDiv.fadeOut(400, function() {$(this).remove();});“
Step 9 (AI and human): The second attempt, Gemini said to add a fading out class to the CSS. Which I did and the code still did not work. I figured just replacing the fading out with removing the element would be fine. I gave this prompt “Cards that have been clicked and NOT replaced with another card, just be removed after 30 seconds.”
Step 10 (AI and human): The third attempt did not work. I had assumed with the prompt that the fading out class, which was causing the issue, would be removed, but it was not, so I got more specific “The fading out class is there but this is still not working. Rewrite this without the fading out, just replacing the card, or removing a not replaced card after 30 seconds.“
Step 11 (AI and human): The fourth attempt did not work and I was running out of patience. I did see in the code that the fade out had been changed to remove. I gave this prompt, “The cards are not being removed.”
Step 12 (human): Gemini Pro said to paste in a bunch more console.log statements, but I decided instead of doing that to just read through the code myself. The problem was that in an earlier step, Gemini had written this statement
const timeInMs = 30 * 1000;
That’s not a bad idea. I might have done the same thing myself when testing code. However, it had two problems. First, very few children – or adults – are going to wait 30 seconds before clicking OK on the dialog box. In fact, this may have worked if I had been waiting 30 seconds instead of 5 or 10.
The bigger error was that, if you go back to my initial prompt for this, it was to use options.timeToRemove seconds which is set by the user. So, I just went into the code and changed it to this:
const timeInMs = options.timeToRemove || 0 ;
Step 13 (human): Looking at the config file, I realized that this block had originally been based on another block that was a memory game. As a result, the config file contained several parameters that were never used, like the label for the number of matches or whether or not the activity should be timed. I deleted those. That made me wonder what modules were being imported by the HTML file. Sure enough, there was a memory.js that didn’t need to be there.
Step 14 (human): The dialog box was covering some of the flash cards in the middle of the screen so I edited the CSS to move it up.
Conclusion: Gemini Pro was worth using
You might wonder why I would say that since the simple modification is the only change it got correct on the first try. It took five attempts to get the second, less simple change working and, even after five tries, it never got the third change right. Even the less simple changes were not major features. Most of the code was already written, working and thoroughly tested. Gemini did not need to touch the config file, HTML file or CSS file. The one CSS change it suggested didn’t work, and the other change I knew off the top of my head so didn’t use Gemini. Despite having the config file code, Gemini did not spot the unused object properties and flag or delete those.
Why is Gemini Pro worth it despite being frequently wrong?
Three words, “It saved time.”
Also, as someone who has been programming since 1974 (yes, punched cards, computers that took up a whole room), I know that every developer makes tons of mistakes. If it’s a really simple change, like adding a counter, incrementing it, checking its value and then doing something based on that value, then, yes, like Gemini, I can do that without error 99% of the time. The other 1% is a typo.
I could definitely have done this without Gemini Pro but then I would have needed to read the 157 lines of code in the js file, the 83 lines of code in the sample config file, remember how the array object was originally constructed and replace it with logic where not all of the cards in the array were displayed at once. Then, I’d have to add the function to replace the cards as they were removed. I’ve seen this code before and written some of the blocks code myself, but I hadn’t written this particular block, so it would have taken me some time to read through it. Then, just as I did with Gemini, I would have added each step and tested it.
Doing this without Gemini would have taken me an afternoon. With Gemini, it took me an hour.
To those developers who say, “I could have done it in an hour,” well, then, you’re not very smart. People like you break stuff. Never go in and change code without reading it and seeing how it works. Reading through it is how I saw that we were importing a module and setting properties that were never used. I knew not to change the dialog.css because it is linked in many other files. Also, I test EVERYTHING. When I removed the properties from the config file, I tested it still worked, etc.
Could Gemini replace a junior developer? Yes and no.
I say this as someone who has seen – and hired – a lot of junior developers over the past 40 years. Doing this with Gemini was faster for me than handing it off to a junior developer who would have taken at least 8 hours, and most likely 16-24 hours, because this is embedded in a larger code base. It imports several files which you would not immediately know are not relevant, unless you were familiar with the code. You may have noticed, it has some legacy code using jQuery, which might be unfamiliar. Values are read from a config file edited by the user, which may be new for a junior developer.
On the other hand, if a junior developer tested the code and it didn’t work, they wouldn’t tell me that it did. If they were good, they might notice that some of the properties in the config file were never used. MOST IMPORTANTLY, most of our junior developers get better with time and eventually, I could hand this off to them and they could do it with Gemini in an hour. Most of them improve to the point that they can create their own blocks, spot errors in the program and fix it themselves, come up with their own game ideas that are not just a regurgitation of what is on some game site.
Could anyone use Gemini to code?
I have no idea, but I have some thoughts, which maybe will be another newsletter.
- I don’t know if, whether I kept pasting the console log to Gemini whether it would have eventually gotten working code. I assume so.
- I don’t know whether, if I had posted less specific prompts, not using the object properties or code snippets, whether Gemini would have taken longer to find the correct solution or not get there at all.
- I think the best way to code is to break the desired result into small tasks, add and test each one individually. I don’t know what would have happened if I asked Gemini to make all of the modifications at once.
- I don’t know how someone completely unfamiliar with our code would have done this. I assume if they were an experienced developer, even if they knew zero Javascript, they could have gotten it done fairly quickly. If they knew nothing about programming – well, see number 3.