How to Use ChatGPT to Generate Math Homework From Photos of My Daughter’s Assignments: Part 3

Using ChatGPT 4 to generate an HTML/JS based flashcard prototype

Sujan Kapadia
8 min readFeb 15, 2024

In part 2, we asked ChatGPT 4 to convert the math problems it generated into LaTeX, so we could produce a PDF to share with others. Today, we’re going to ask ChatGPT 4 to generate a very simple, proof-of-concept flashcard example, in HTML and Javascript. These specific problems don’t necessarily lend themselves well to flashcard based learning, but this attempt displays the power of ChatGPT.

This blog post will cover:

  • Asking gpt-4 to generate HTML and Javascript for a basic flashcard system, and testing it out in Chrome.
  • Asking it to modify the application to fix a layout issue.

Iteration 1: Generating a flashcard system

Let’s ask ChatGPT to do the following, and instruct it with a special persona:

User: “Below are a set a 6th grade math exam problems. Please generate an HTML page that reveals each question as a flashcard, one question at a time. There should be Previous and Next buttons to advance forwards or backwards through the flash cards. The page should display well on desktop, tablet, or mobile. The style and color of the text, card, and buttons should be easy to read, with good contrast.”

System: “You are a product development team for a education software company. You design and develop educational software for children.”

flashcard_prompt = """
Below are a set a 6th grade math exam problems. Please generate an HTML page that can reveals each question as a flashcard, one question at a time. There should be Previous and Next buttons to advance forwards or backwards through the flash cards. The page should display well on desktop, tablet, or mobile. The style and color of the text, card, and buttons should be easy to read, with good contrast.


Exam problems:

### Greatest Common Factor (GCF)

5. **GCF Practice**
a. GCF (24, 36) = ______
b. GCF (40, 60) = ______

### Least Common Multiple (LCM)

6. **LCM Challenge**
a. LCM (6, 9) = ______
b. LCM (7, 14) = ______

### Real-world Applications of LCM and GCF

7. **Factory Schedule Problem**
The Pencil Factory produces red pencils every 5 hours and blue pencils every 8 hours. They start production at 7:00 A.M. When will both red and blue pencils be produced at the same time next?

### Fraction Multiplication in Real-world Context

8. **Gardening Fractions**
Daniel is planning a rectangular flower bed. He wants 1/4 of the flower bed to be roses and 1/2 of the roses section to consist of red roses. What fraction of the whole flower bed will be red roses?

Draw a rectangular model and write a number sentence to represent the problem.

### Additional Common Factor and Multiple Problems

9. **Common Factors and Multiples**
a. Name all the common factors of 14 and 21.
b. What is the smallest common multiple of 11 and 12?

### Practical Fraction Problem

10. **Baking Fractions**
Maria has 3/4 of a cup of sugar. She uses 2/3 of it to make a batch of cookies. How much sugar does she have left?

Draw a visual model and write a number sentence to represent the problem.

### Rational Number Operations

11. **Fraction Subtraction**
a. Subtract the fraction: 5/8 - 1/4 = ______
b. Subtract the fraction: 7/10 - 2/5 = ______

### Time Interval Problem Using LCM

12. **Meeting Time**
Two friends want to meet for yoga. One friend goes every 6 days, and the other goes every 9 days. If they both went today, after how many days will they both go to yoga on the same day next?

### Area and Fraction Review

13. **Camping Plot**
A family is camping on a rectangular plot that is 1/3 acre. They use 3/5 of this plot to set up their tents. What fraction of an acre did the tents cover?

Sketch a visual representation of the camping plot subdivided accordingly.

### Additional Calculation Practice

14. **Quick Calculations**
a. Multiply the fraction: 3/8 * 2/5 = ______
b. Divide the fraction: 6/7 ÷ 3/4 = ______

### Problem-Solving with Unit Rates

15. **Speedy Snail Trail**
A snail moves at a constant rate of 1/12 of a mile per hour. How far will the snail travel in 4 hours?

Provide a number sentence to calculate the distance traveled.

Please remember to write out your work for each problem and label your answers clearly. Good luck!
"""

flashcard_messages = [
{
"role": "system",
"content": "You are a product development team for a education software company. You design and develop educational software for children."
},
{
"role": "user",
"content": f"{flashcard_prompt}"
}
]

response = client.chat.completions.create(
model="gpt-4",
messages=flashcard_messages,
max_tokens=4096)

print(response.choices[0].message.content)

With that, ChatGPT conjures up the following HTML, CSS, and Javascript:

<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
body {font-family: Arial, Helvetica, sans-serif;}
#flashcard_container {position: relative; width: 70%; margin: auto; padding: 20px; border: 1px solid #888; border-radius:10px; box-shadow: 5px 10px #888888; margin-top: 20px; margin-bottom:20px; }
#flashcard_container>div{display:none;}
#flashcard_container>div.visible{display:block;}
.flashcard {font-size: 18px; color: #000; line-height: 1.5;}
.prev, .next {background-color: #4CAF50; border: none; color: white; padding: 15px 32px; text-align: center; text-decoration: none; display: inline-block; font-size: 16px; margin: 4px 2px; cursor: pointer;}
.prev:hover, .next:hover {background-color: #45a049;}
</style>
</head>
<body>

<div id="flashcard_container">

<div class="flashcard visible">
<strong>GCF Practice</strong><br>
a. GCF (24, 36) = ______<br>
b. GCF (40, 60) = ______
</div>

<div class="flashcard">
<strong>LCM Challenge</strong><br>
a. LCM (6, 9) = ______<br>
b. LCM (7, 14) = ______
</div>

<!-- Additional flashcards go here. Replace `<strong>` with `###` and replace `<br>` with newlines -->

</div>

<button class="prev" onclick="prevFlashcard()">Previous</button>
<button class="next" onclick="nextFlashcard()">Next</button>

<script>
let flashcards = Array.from(document.querySelectorAll('.flashcard'));
let currentFlashcardIndex = 0;

function showFlashcard(index) {
flashcards.forEach((card, i) => {
card.classList[i === index ? 'add' : 'remove']('visible');
});
}

function prevFlashcard() {
currentFlashcardIndex = (currentFlashcardIndex <= 0) ? flashcards.length - 1 : currentFlashcardIndex - 1;
showFlashcard(currentFlashcardIndex);
}

function nextFlashcard() {
currentFlashcardIndex = (currentFlashcardIndex >= flashcards.length - 1) ? 0 : currentFlashcardIndex + 1;
showFlashcard(currentFlashcardIndex);
}

</script>

</body>
</html>

Hey ChatGPT, this only includes two of the problems! What gives? Oh wait, there’s a comment at the end of the flashcard_container div that indicates how to manually add more flashcards to the HTML.

Drum roll: Loading the page in Chrome

Below is the result. As we can see, the flash card has a drop shadow, a title, relatively easy to read content, and buttons that change color on hover. However, the buttons are not centered horizontally. Let’s fix that.

Preview of Iteration 1

Iteration 2: Modifying button layout

We’ll ask ChatGPT to fix this for us: “Thank you for creating a simple HTML based flash card system for the math problems you generated earlier. Can you update the following to center the buttons?” However, we need to include the entire HTML document it previously generated, since the ChatGPT API currently retains no history.

flashcard_prompt = r"""
Thank you for creating a simple HTML based flash card system for the math problems you generated earlier. Can you update the following to center the buttons?

<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
body {font-family: Arial, Helvetica, sans-serif;}
#flashcard_container {position: relative; width: 70%; margin: auto; padding: 20px; border: 1px solid #888; border-radius:10px; box-shadow: 5px 10px #888888; margin-top: 20px; margin-bottom:20px; }
#flashcard_container>div{display:none;}
#flashcard_container>div.visible{display:block;}
.flashcard {font-size: 18px; color: #000; line-height: 1.5;}
.prev, .next {background-color: #4CAF50; border: none; color: white; padding: 15px 32px; text-align: center; text-decoration: none; display: inline-block; font-size: 16px; margin: 4px 2px; cursor: pointer;}
.prev:hover, .next:hover {background-color: #45a049;}
</style>
</head>
<body>

<div id="flashcard_container">

<div class="flashcard visible">
<strong>GCF Practice</strong><br>
a. GCF (24, 36) = ______<br>
b. GCF (40, 60) = ______
</div>

<div class="flashcard">
<strong>LCM Challenge</strong><br>
a. LCM (6, 9) = ______<br>
b. LCM (7, 14) = ______
</div>

<!-- Additional flashcards go here. Replace `<strong>` with `###` and replace `<br>` with newlines -->

</div>

<button class="prev" onclick="prevFlashcard()">Previous</button>
<button class="next" onclick="nextFlashcard()">Next</button>

<script>
let flashcards = Array.from(document.querySelectorAll('.flashcard'));
let currentFlashcardIndex = 0;

function showFlashcard(index) {
flashcards.forEach((card, i) => {
card.classList[i === index ? 'add' : 'remove']('visible');
});
}

function prevFlashcard() {
currentFlashcardIndex = (currentFlashcardIndex <= 0) ? flashcards.length - 1 : currentFlashcardIndex - 1;
showFlashcard(currentFlashcardIndex);
}

function nextFlashcard() {
currentFlashcardIndex = (currentFlashcardIndex >= flashcards.length - 1) ? 0 : currentFlashcardIndex + 1;
showFlashcard(currentFlashcardIndex);
}

</script>

</body>
</html>
"""

flashcard_messages = [
{
"role": "system",
"content": "You are a product development team for a education software company. You design and develop educational software for children."
},
{
"role": "user",
"content": f"{flashcard_prompt}"
}
]

response = client.chat.completions.create(
model="gpt-4",
messages=flashcard_messages,
max_tokens=4096)

print(response.choices[0].message.content)

Here is the output:

Sure! Here are the necessary changes to center the buttons horizontally:

Your existing code has been slightly updated. Wrap the buttons with a new div, and apply style to center it.

```html
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
body {font-family: Arial, Helvetica, sans-serif;}
#flashcard_container {position: relative; width: 70%; margin: auto; padding: 20px; border: 1px solid #888; border-radius:10px; box-shadow: 5px 10px #888888; margin-top: 20px; margin-bottom:20px; }
#flashcard_container>div{display:none;}
#flashcard_container>div.visible{display:block;}
.flashcard {font-size: 18px; color: #000; line-height: 1.5;}
.prev, .next {background-color: #4CAF50; border: none; color: white; padding: 15px 32px; text-align: center; text-decoration: none; display: inline-block; font-size: 16px; margin: 4px 2px; cursor: pointer;}
.prev:hover, .next:hover {background-color: #45a049;}
.button_container {text-align: center;}
</style>
</head>
<body>

<div id="flashcard_container">

<div class="flashcard visible">
<strong>GCF Practice</strong><br>
a. GCF (24, 36) = ______<br>
b. GCF (40, 60) = ______
</div>

<div class="flashcard">
<strong>LCM Challenge</strong><br>
a. LCM (6, 9) = ______<br>
b. LCM (7, 14) = ______
</div>

<!-- Additional flashcards go here. Replace `<strong>` with `###` and replace `<br>` with newlines -->

</div>

<div class="button_container">
<button class="prev" onclick="prevFlashcard()">Previous</button>
<button class="next" onclick="nextFlashcard()">Next</button>
</div>

<script>
let flashcards = Array.from(document.querySelectorAll('.flashcard'));
let currentFlashcardIndex = 0;

function showFlashcard(index) {
flashcards.forEach((card, i) => {
card.classList[i === index ? 'add' : 'remove']('visible');
});
}

function prevFlashcard() {
currentFlashcardIndex = (currentFlashcardIndex <= 0) ? flashcards.length - 1 : currentFlashcardIndex - 1;
showFlashcard(currentFlashcardIndex);
}

function nextFlashcard() {
currentFlashcardIndex = (currentFlashcardIndex >= flashcards.length - 1) ? 0 : currentFlashcardIndex + 1;
showFlashcard(currentFlashcardIndex);
}

</script>

</body>
</html>
```
With the addition of the .button_container class and its text-align:center style, your buttons should be centered horizontally.

Preview of Centered Buttons

Loading this in Chrome, we can clearly see the buttons are centered horizontally between the left and right edges of the flashcard. In Developer Tools, let’s open the Device Toolbar and see what this looks like in an iPhone 12 Pro viewport (390px x 844px). It appears to be responsive, although I have not tested text wrapping within the flashcard.

Conclusions

  • With almost no effort, we were able to put together a very simple proof-of-concept to generate flash cards. We could take this further and try to build a cheap and dirty prototype to generate the backing data, SQL, and API to retrieve and populate new flashcards, add a scoring system, etc. (I’m very skeptical of the code generated by LLMs, and it can be wrong in a lot of cases. However, for boilerplate or repeatable data-driven logic, it’s worth experimenting with).
  • I have not reviewed the code it generated, since this was purely a proof-of-concept. Is it correct, well-factored, and adhering to best practices?
  • Generative AI may be a useful tool for converting information into different formats (LaTeX, PDFs, HTML based slides or flashcards, charts)
  • It’s insanely fun to play around with LLMs. It’s wild that I can do all this from a picture of my daughter’s 6th grade math homework!

--

--

Sujan Kapadia

Compiler of coffee and code, contemplator of dystopias.