Coding with ChatGPT

I tried ChatGPT's coding ability and am sharing here what I learned from the experience,

Further below, I share the entire work session arranged as a conversation between me and ChatGPT, including the code output at each step.

Observations:

  • Writes pretty clean code. Can write simple functional web apps.  
  • Bugs do occur. Sometimes it fails to complete the program. (I wonder if there is a limit on the size of app/ number of lines of code that can be generated).
  • While it was overall pretty impressive, it could sometimes confuse the context of a specific function or request.
  • Doesn't complain or make excuses. When I said something doesn't work, I was surprised that it would quickly make another attempt (and sometimes correct the issue).
  • The way you write the prompts makes a big difference on the results you get back.

Tips

  • Specify the language you want.
  • Specify the core functionality first. Then once it has written code that works, you can add additional features.
  • Think iteratively: Instead of saying I want 10 things, say I want this 1 thing. When it gets that right, then say I want this to be repeatable for up to 10 times.


Transcript and Code from the ChatGPT Work Session (Feb 2023)

Me:

Please provide the HTML5 code for a simple timer app, where tapping a Start button records a start time, tapping it again records a stop time and the duration between the start time and stop time. In addition, a text field allows the user to record a short note about what activity was completed between the start time and the stop time.

ChatGPT:

Here is the HTML5 code for a simple timer app:phpCopy code<!DOCTYPE html><html>  <head>    <title>Timer App</title>    <style>      .container { display: flex; flex-direction: column; align-items: center; } button { padding: 10px 20px; font-size: 18px; margin-top: 20px; } .output { margin-top: 20px; font-size: 18px; } </style>  </head>  <body>    <div class="container">      <button id="startStopBtn">Start</button>      <div class="output">Duration: <span id="duration"></span></div>      <div class="output">Note:</div>      <textarea id="note" rows="4" cols="50"></textarea>    </div> <script>      const startStopBtn = document.getElementById("startStopBtn"); const durationOutput = document.getElementById("duration"); const noteInput = document.getElementById("note"); let startTime, endTime; let timerRunning = false; startStopBtn.addEventListener("click", function() { if (!timerRunning) { startTime = new Date(); startStopBtn.innerHTML = "Stop"; timerRunning = true; } else { endTime = new Date(); const duration = (endTime - startTime) / 1000; durationOutput.innerHTML = duration + " seconds"; startStopBtn.innerHTML = "Start"; timerRunning = false; } }); </script>  </body></html>

In this code, tapping the Start button records the current time as the start time, and tapping it again records the current time as the end time. The duration between the start time and the end time is calculated in seconds and displayed. The text field allows the user to record a note about the activity completed between the start and end times.

Me:

good. What is the best method for persisting or storing the time durations and the activities recorded? For example should these be stored in a simple database or file? The user will need to keep records for up to 1 month in order to have an accurate history of how the user's time was spent during that month.

ChatGPT:

The best method for persisting or storing the time durations and activities recorded would depend on the specific requirements of your app and the resources you have available. Here are a few options you could consider:

  1. Simple database - storing the data in a database allows for easy retrieval, manipulation and organization of the data. You could use a database management system like MySQL or SQLite, which are well suited for small to medium sized projects.
  2. File storage - if the data is simple and does not need to be accessed by multiple users, you could store the data in a file on the user's device. For example, you could use a text file or a JSON file to store the data, and read from or write to the file as needed.
  3. Cloud storage - you could use a cloud-based storage solution like Amazon Web Services (AWS) or Google Cloud Platform (GCP) to store the data. This allows you to easily scale your app as needed and provides a centralized location for the data.

Regardless of the method you choose, it's important to ensure that the data is secure and can be easily backed up in case of any data loss. Additionally, you should consider the privacy implications of storing the data, and ensure that you have the user's consent to do so.

Me:

Can we modify the HTML5 code for the timer app so that when the Start button is clicked, it displays a live timer showing the elapsing time. Clicking the button again then shows the total elapsed time.

ChatGPT:

Yes, you can modify the HTML5 code for the timer app to display a live timer showing the elapsing time. Here's the updated code:phpCopy code<!DOCTYPE html><html>  <head>    <title>Timer App</title>    <style>      .container { display: flex; flex-direction: column; align-items: center; } button { padding: 10px 20px; font-size: 18px; margin-top: 20px; } .output { margin-top: 20px; font-size: 18px; } </style>  </head>  <body>    <div class="container">      <button id="startStopBtn">Start</button>      <div class="output">Duration: <span id="duration"></span></div>      <div class="output">Note:</div>      <textarea id="note" rows="4" cols="50"></textarea>    </div> <script>      const startStopBtn = document.getElementById("startStopBtn"); const durationOutput = document.getElementById("duration"); const noteInput = document.getElementById("note"); let startTime, endTime; let timerRunning = false; let intervalId; startStopBtn.addEventListener("click", function() { if (!timerRunning) { startTime = new Date(); startStopBtn.innerHTML = "Stop"; timerRunning = true; intervalId = setInterval(function() { const elapsedTime = new Date() - startTime; durationOutput.innerHTML = elapsedTime / 1000 + " seconds"; }, 1000); } else { clearInterval(intervalId); endTime = new Date(); const duration = (endTime - startTime) / 1000; durationOutput.innerHTML = duration + " seconds"; startStopBtn.innerHTML = "Start"; timerRunning = false; } }); </script>  </body></html>

In this updated code, the setInterval function is used to display a live timer showing the elapsing time. The setInterval function is called when the Start button is clicked, and it updates the duration output with the elapsed time in seconds every second. When the Stop button is clicked, the clearInterval function is called to stop the live timer, and the total elapsed time is displayed.

Me:

Good. Can you modify the code to show the duration in Hours minutes and seconds without decimals

ChatGPT:

Sure! You can modify the code to show the duration in hours, minutes, and seconds without decimals. Here's the updated code:phpCopy code<!DOCTYPE html><html>  <head>    <title>Timer App</title>    <style>      .container { display: flex; flex-direction: column; align-items: center; } button { padding: 10px 20px; font-size: 18px; margin-top: 20px; } .output { margin-top: 20px; font-size: 18px; } </style>  </head>  <body>    <div class="container">      <button id="startStopBtn">Start</button>      <div class="output">Duration: <span id="duration"></span></div>      <div class="output">Note:</div>      <textarea id="note" rows="4" cols="50"></textarea>    </div> <script>      const startStopBtn = document.getElementById("startStopBtn"); const durationOutput = document.getElementById("duration"); const noteInput = document.getElementById("note"); let startTime, endTime; let timerRunning = false; let intervalId; startStopBtn.addEventListener("click", function() { if (!timerRunning) { startTime = new Date(); startStopBtn.innerHTML = "Stop"; timerRunning = true; intervalId = setInterval(function() { const elapsedTime = new Date() - startTime; const hours = Math.floor(elapsedTime / (1000 * 60 * 60)); const minutes = Math.floor((elapsedTime % (1000 * 60 * 60)) / (1000 * 60)); const seconds = Math.floor((elapsedTime % (1000 * 60)) / 1000); durationOutput.innerHTML = `${hours} hours ${minutes} minutes ${seconds} seconds`; }, 1000); } else { clearInterval(intervalId); endTime = new Date(); const elapsedTime = endTime - startTime; const hours = Math.floor(elapsedTime / (1000 * 60 * 60)); const minutes = Math.floor((elapsedTime % (1000 * 60 * 60)) / (1000 * 60)); const seconds = Math.floor((elapsedTime % (1000 * 60)) / 1000); durationOutput.innerHTML = `${hours} hours ${minutes} minutes ${seconds} seconds`; startStopBtn.innerHTML = "Start"; timerRunning = false; } }); </script>  </body></html>

In this updated code, the elapsed time is calculated in milliseconds, and then divided into hours, minutes, and seconds using the Math.floor function. The duration output is updated to show the duration in hours, minutes, and seconds without decimals.

Me:

Very good. Now let's modify the app. Create a text field that allows a user to enter some text, then click a Save button. When the Save button is clicked the text is added as a list item to a list on the screen. Next to the list item is a small Start button. When the user clicks the start button, a timer starts. The button displays the word stop and the elapsing time is displayed between the button and the list item. When the user clicks the button again, the timer stops. The elapsed time is displayed next to the list item. If the user clicks the button yet again, the timer starts and the duration increases until the user clicks the button again. In this way, the user is able to make a list of items to do, then start and stop the timer as they do those items, and have a record of how much time they spent doing each item. 2 / 2

ChatGPT:

Here's the updated code for the timer app:phpCopy code<!DOCTYPE html><html>  <head>    <title>Timer App</title>    <style>      .container { display: flex; flex-direction: column; align-items: center; } button { padding: 10px 20px; font-size: 18px; margin-top: 20px; } ul { list-style: none; margin-top: 20px; } li { display: flex; align-items: center; margin-top: 20px; } </style>  </head>  <body>    <div class="container">      <div>        <input type="text" id="itemInput" />        <button id="addItemBtn">Add</button>      </div>      <ul id="itemList"></ul>    </div> <script>      const itemInput = document.getElementById("itemInput"); const addItemBtn = document.getElementById("addItemBtn"); const itemList = document.getElementById("itemList"); let intervalIds = []; addItemBtn.addEventListener("click", function() { const item = itemInput.value; itemInput.value = ""; const li = document.createElement("li"); li.innerHTML = `<span>${item}</span> <button class="startStopBtn">Start</button> <span class="duration">0 hours 0 minutes 0 seconds</span>`; itemList.appendChild(li); const startStopBtn = li.querySelector(".startStopBtn"); const durationOutput = li.querySelector(".duration"); let startTime, endTime; let timerRunning = false; startStopBtn.addEventListener("click", function() { if (!timerRunning) { startTime = new Date(); startStopBtn.innerHTML = "Stop"; timerRunning = true; intervalIds.push(setInterval(function() { const elapsedTime = new Date() - startTime; const hours = Math.floor(elapsedTime / (1000 * 60 * 60)); const minutes = Math.floor((elapsedTime % (1000 * 60 * 60)) / (1000 * 60)); const seconds = Math.floor((elapsedTime % (1000 * 60)) / 1000); durationOutput.innerHTML = `${hours} hours ${minutes} minutes ${seconds} seconds`; }, 1000)); } else { clearInterval(intervalIds.pop()); endTime = new Date(); const elapsedTime = endTime - startTime; const hours = Math.floor(elapsedTime / (1000 * 60 * 60)); const minutes = Math.floor((elapsedTime % (1000 * 60 * 60)) / (1000 * 60)); const seconds = Math.floor((elapsedTime % (1000 * 60)) / 1000); durationOutput.innerHTML = `${hours} hours ${minutes} minutes ${seconds} seconds`;

Me:

this doesn't seem to be complete

ChatGPT:

My apologies, here's a complete implementation of the updated feature requests:phpCopy code<!DOCTYPE html><html><head>  <meta charset="UTF-8">  <title>Timer App</title>  <style>    .list-item { display: flex; align-items: center; margin: 10px 0; } </style></head><body>  <h2>Timer App</h2> <label for="task-text">Task:</label>  <input type="text" id="task-text" /> <button id="save-task">Save</button> <ul id="task-list">  </ul> <script>    const taskTextInput = document.getElementById('task-text'); const saveTaskButton = document.getElementById('save-task'); const taskList = document.getElementById('task-list'); saveTaskButton.addEventListener('click', () => { const taskText = taskTextInput.value; taskTextInput.value = ''; if (!taskText) return; const listItem = document.createElement('li'); listItem.classList.add('list-item'); listItem.innerHTML = ` <span class="task-text">${taskText}</span> <button class="start-timer">Start</button> <span class="task-duration"></span> `; const startTimerButton = listItem.querySelector('.start-timer'); const taskDurationSpan = listItem.querySelector('.task-duration'); let startTime; let intervalId; let elapsedTime = 0; startTimerButton.addEventListener('click', () => { if (!startTime) { startTime = Date.now(); startTimerButton.innerText = 'Stop'; intervalId = setInterval(() => { elapsedTime = Date.now() - startTime; taskDurationSpan.innerText = formatDuration(elapsedTime); }, 1000); } else { clearInterval(intervalId); startTimerButton.innerText = 'Start'; taskDurationSpan.innerText = formatDuration(elapsedTime); startTime = null; } }); taskList.appendChild(listItem); }); function formatDuration(duration) { const hours = Math.floor(duration / (1000 * 60 * 60)); duration -= hours * (1000 * 60 * 60); const minutes = Math.floor(duration / (1000 * 60)); duration -= minutes * (1000 * 60); const seconds = Math.floor(duration / 1000); return `${hours}h ${minutes}m ${seconds}s`; } </script></body></html>

Me:

good. Now let's modify the list items so that the Start buttons, the text, and the time durations appear in columns; the first column has the start buttons, the second column has the text and the third column lists the time durations.

ChatGPT:

Here's an updated version of the HTML5 code that implements the requested changes:phpCopy code<!DOCTYPE html><html><head>  <meta charset="UTF-8">  <title>Timer App</title>  <style>    .container { display: flex; flex-direction: column; align-items: center; } table { border-collapse: collapse; width: 60%; } th, td { border: 1px solid black; padding: 8px; text-align: left; } th { background-color: lightgray; } </style></head><body>  <div class="container">    <h1>Timer App</h1>    <input type="text" id="textfield">    <button id="saveBtn">Save</button>    <table id="list">      <tr>        <th>Action</th>        <th>Text</th>        <th>Duration</th>      </tr>    </table>  </div>  <script>    const textfield = document.getElementById("textfield"); const saveBtn = document.getElementById("saveBtn"); const list = document.getElementById("list"); saveBtn.addEventListener("click", function () { const text = textfield.value; if (!text) return; const row = document.createElement("tr"); const actionCol = document.createElement("td"); const textCol = document.createElement("td"); const durationCol = document.createElement("td"); const startBtn = document.createElement("button"); startBtn.innerText = "Start"; startBtn.addEventListener("click", function () { let start, end; if (!start) { start = new Date(); startBtn.innerText = "Stop"; } else { end = new Date(); const elapsed = end - start; const hours = Math.floor(elapsed / (1000 * 60 * 60)); const minutes = Math.floor(elapsed / (1000 * 60)) % 60; const seconds = Math.floor(elapsed / 1000) % 60; durationCol.innerText = `${hours}:${minutes}:${seconds}`; start = null; end = null; startBtn.innerText = "Start"; } }); actionCol.appendChild(startBtn); textCol.innerText = text; row.appendChild(actionCol); row.appendChild(textCol); row.appendChild(durationCol); list.appendChild(row); textfield.value = ""; }); </script></body></html>

In this code, the table headers have been added and each list item is a row in the table, with the start button, text, and duration displayed in separate columns. The time durations are still displayed in hours, minutes, and seconds without decimals.

Me:

Very good. One small modification: Please position the Save button next to the text field.

ChatGPT:

Here's an updated version of the code with the Save button positioned next to the text field:phpCopy code<!DOCTYPE html><html>  <head>    <style>      table { width: 100%; border-collapse: collapse; } td, th { border: 1px solid black; padding: 8px; text-align: left; } th { background-color: #f2f2f2; } </style>  </head>  <body>    <input type="text" id="task" placeholder="Enter task"></input>    <button id="save-btn">Save</button>    <table id="task-table">      <thead>        <tr>          <th>Start</th>          <th>Task</th>          <th>Duration</th>        </tr>      </thead>      <tbody id="task-list">      </tbody>    </table>    <script>      const saveBtn = document.getElementById("save-btn"); const taskInput = document.getElementById("task"); const taskList = document.getElementById("task-list"); saveBtn.addEventListener("click", function() { const task = taskInput.value; if (!task) return; const row = document.createElement("tr"); const startCol = document.createElement("td"); const taskCol = document.createElement("td"); const durationCol = document.createElement("td"); taskCol.textContent = task; taskInput.value = ""; const startBtn = document.createElement("button"); startBtn.textContent = "Start"; startBtn.addEventListener("click", function() { let startTime; let intervalId; if (startBtn.textContent === "Start") { startBtn.textContent = "Stop"; startTime = new Date(); intervalId = setInterval(function() { const elapsedTime = new Date() - startTime; const seconds = Math.floor(elapsedTime / 1000) % 60; const minutes = Math.floor(elapsedTime / 60000) % 60; const hours = Math.floor(elapsedTime / 3600000); durationCol.textContent = `${hours}h ${minutes}m ${seconds}s`; }, 1000); } else { startBtn.textContent = "Start"; clearInterval(intervalId); } }); startCol.appendChild(startBtn); row.appendChild(startCol); row.appendChild(taskCol); row.appendChild(durationCol); taskList.appendChild(row); }); </script>  </body></html>

Me:

Ok please check the Start and Stop button code.  When the Start Button is pressed it begins the timer display. But when the button is pressed again it is not stopping the timer. Please fix this so that when the button is pressed again, the timer stops and the duration between the start time and the stop time is displayed in the duration column.

ChatGPT:

phpCopy code<html>  <head>    <script>      function startStopTimer(el) { let startTime; let timer; if (el.innerHTML === "Start") { startTime = Date.now(); el.innerHTML = "Stop"; timer = setInterval(() => { let elapsed = Date.now() - startTime; let hours = Math.floor(elapsed / 3600000); elapsed %= 3600000; let minutes = Math.floor(elapsed / 60000); elapsed %= 60000; let seconds = Math.floor(elapsed / 1000); el.nextSibling.innerHTML = `${hours}:${minutes}:${seconds}`; }, 1000); } else { clearInterval(timer); el.innerHTML = "Start"; } } </script>  </head>  <body>    <input type="text" id="activity" />    <button onclick="saveActivity()">Save</button>    <table>      <thead>        <tr>          <th>Start/Stop</th>          <th>Activity</th>          <th>Duration</th>        </tr>      </thead>      <tbody id="activityList">      </tbody>    </table>    <script>      function saveActivity() { let activity = document.getElementById("activity").value; let tbody = document.getElementById("activityList"); let row = document.createElement("tr"); let startCell = document.createElement("td"); let startButton = document.createElement("button"); startButton.innerHTML = "Start"; startButton.onclick = function() { startStopTimer(this); }; startCell.appendChild(startButton); let activityCell = document.createElement("td"); activityCell.innerHTML = activity; let durationCell = document.createElement("td"); row.appendChild(startCell); row.appendChild(activityCell); row.appendChild(durationCell); tbody.appendChild(row); document.getElementById("activity").value = ""; } </script>  </body></html>

(This didn't work so I started with a fresh instruction)

Me:

Please provide the HTML5 code for a simple timer app, which allows a user to record a list of tasks, then use a simple start / stop button to track how much time each task took. then use a timer with a start and stop button to record how much time elapsed At the top of the screen the app displays a text field with a save button next to it. When the user enters a task in the text field and clicks the Save button (or hits Enter) the task is added as a list item to a columnar list on the screen. The columnar list has 3 columns: The first column has the Start buttons, The second column has the text entered by the user, and the third column has the time durations showing the time elapsed between the time the user pressed the start and stop button. Next to each list item in the list is a small Start button. When the user clicks the start button, a timer starts. The button displays the word stop and the elapsing time in hours minutes and seconds format is displayed to the right of the list item. When the user clicks the button again, the timer stops. The total elapsed time is displayed to the right of the list item. If the user clicks the button yet again, the timer starts again and the duration increases until the user clicks the button again. In this way, the user is able to make a list of items to do, then start and stop the timer as they do those items, and have a record of how much time they spent doing each task.

ChatGPT:

Here is the HTML5 code for the timer app:phpCopy code<html>  <head>    <script>      function startTimer(e) { const button = e.target; const listItem = button.parentNode; const durationEl = listItem.querySelector(".duration"); const startTime = new Date(); let timerInterval; button.innerHTML = "Stop"; button.onclick = function() { clearInterval(timerInterval); const stopTime = new Date(); const duration = (stopTime - startTime) / 1000; const hours = Math.floor(duration / 3600); const minutes = Math.floor((duration % 3600) / 60); const seconds = Math.floor(duration % 60); durationEl.innerHTML = `${hours}:${minutes}:${seconds}`; button.innerHTML = "Start"; button.onclick = startTimer; }; timerInterval = setInterval(function() { const elapsedTime = (new Date() - startTime) / 1000; const hours = Math.floor(elapsedTime / 3600); const minutes = Math.floor((elapsedTime % 3600) / 60); const seconds = Math.floor(elapsedTime % 60); durationEl.innerHTML = `${hours}:${minutes}:${seconds}`; }, 1000); } function addTask() { const taskInput = document.querySelector("input[name='task']"); const taskList = document.querySelector("#task-list"); const taskText = taskInput.value; if (!taskText) return; const newTask = document.createElement("li"); newTask.innerHTML = ` <button class="start-timer">Start</button> <span>${taskText}</span> <span class="duration"></span> `; taskList.appendChild(newTask); taskInput.value = ""; const startTimerButton = newTask.querySelector(".start-timer"); startTimerButton.onclick = startTimer; } </script>  </head>  <body>    <input type="text" name="task">    <button onclick="addTask()">Save</button>    <ul id="task-list"></ul>  </body></html>