Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions ai-benchmark/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# How AI Models Draw a Python Reading a Book

Sample code for Real Python's [vibe check for new AI models](https://realpython.com/ai-benchmark/). Every new model gets the same fixed prompt, *Write a Python turtle program that draws a python reading a book*, and the result is published as is, drawing and all.

Each subfolder is one model's run, named after the model id without its vendor prefix. It contains the turtle script exactly as the model returned it, the rendered drawing, the animation of the turtle drawing it, and a README with the details of that run.

| Folder | Write-up |
|---|---|
| [`gpt-6-astra/`](gpt-6-astra/) | [GPT-6 Astra Draws a Python Reading a Book](https://realpython.com/ai-benchmark-gpt-6-astra/) |

The scripts are the models' output verbatim and are excluded from this repository's Ruff checks on purpose. Nothing was fixed up; that's the point.
28 changes: 28 additions & 0 deletions ai-benchmark/gpt-6-astra/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# GPT-6 Astra Draws a Python Reading a Book

This folder holds the sample code for the Real Python write-up [GPT-6 Astra Draws a Python Reading a Book](https://realpython.com/ai-benchmark-gpt-6-astra/), part of [How AI Models Draw a Python Reading a Book](https://realpython.com/ai-benchmark/).

- Model: `openai/gpt-6-astra`, at its default reasoning settings, run on 2026-09-04
- Prompt: *Write a Python turtle program that draws a python reading a book.*

## What's Here

| File | What |
|---|---|
| `gpt-6-astra-python-reading-a-book.py` | The turtle script, exactly as the model returned it, with a header naming the model, date, and prompt |
| `gpt-6-astra-python-reading-a-book.png` | The finished drawing, rendered headlessly at 800×600 |
| `gpt-6-astra-python-reading-a-book.gif` | The turtle drawing it, frame by frame |

## Run It

You need Python with `tkinter`, which ships with the standard installers from python.org:

```sh
$ python gpt-6-astra-python-reading-a-book.py
```

A window opens and the turtle draws the picture. Change a color, a coordinate, or the caption and run it again to see what the model's code is actually doing. To learn the module from scratch, start with [The Beginner's Guide to Python's turtle Module](https://realpython.com/beginners-guide-python-turtle/).

## A Note on the Code

Nothing in the script was fixed up. It's the model's output verbatim, so it isn't formatted to this repository's Ruff rules on purpose. That's part of what the write-up reads off it.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
209 changes: 209 additions & 0 deletions ai-benchmark/gpt-6-astra/gpt-6-astra-python-reading-a-book.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
"""A python reading a book, drawn by GPT-6 Astra.

Model: openai/gpt-6-astra
Date: 2026-09-04
Prompt: Write a Python turtle program that draws a python reading a book.

Generated for snake-bench, Real Python's vibe check for new AI models:
https://github.com/devcademy/snake-bench

The code is exactly what the model returned. Nothing was fixed up.
Run it with: python gpt-6-astra-python-reading-a-book.py
"""

import math
import turtle

screen = turtle.Screen()
screen.setup(800, 650)
screen.title("A Python Reading Python")
screen.bgcolor("#fff6df")
screen.tracer(0)

pen = turtle.Turtle()
pen.hideturtle()
pen.speed(0)

GREEN = "#68ad45"
DARK_GREEN = "#315e32"
LIGHT_GREEN = "#91c85c"
INK = "#354253"


def polygon(points, fill, outline=INK, width=2):
pen.penup()
pen.goto(points[0])
pen.color(outline, fill)
pen.pensize(width)
pen.pendown()
pen.begin_fill()
for point in points[1:]:
pen.goto(point)
pen.goto(points[0])
pen.end_fill()
pen.penup()


def ellipse(x, y, rx, ry, fill, outline=INK, width=2):
points = [
(
x + rx * math.cos(math.radians(angle)),
y + ry * math.sin(math.radians(angle)),
)
for angle in range(0, 360, 5)
]
polygon(points, fill, outline, width)


def line(points, color=INK, width=2):
pen.penup()
pen.goto(points[0])
pen.pencolor(color)
pen.pensize(width)
pen.pendown()
for point in points[1:]:
pen.goto(point)
pen.penup()


def bezier(p0, p1, p2, p3, steps=60):
points = []
for i in range(steps + 1):
t = i / steps
u = 1 - t
points.append((
u**3 * p0[0] + 3*u*u*t * p1[0]
+ 3*u*t*t * p2[0] + t**3 * p3[0],
u**3 * p0[1] + 3*u*u*t * p1[1]
+ 3*u*t*t * p2[1] + t**3 * p3[1],
))
return points


def text(x, y, words, size=18, color=INK):
pen.penup()
pen.goto(x, y)
pen.pencolor(color)
pen.write(words, align="center", font=("Arial", size, "bold"))


# Ground shadow
ellipse(10, -190, 235, 25, "#e4d7b5", "#e4d7b5")

# Tail curling out from behind the coils
tail = bezier(
(-80, -160), (-260, -210), (-265, -65), (-200, -105)
)
line(tail, DARK_GREEN, 28)
line(tail, GREEN, 22)

# Broad, overlapping coils
ellipse(15, -156, 182, 46, GREEN, DARK_GREEN, 4)
ellipse(15, -132, 154, 39, LIGHT_GREEN, DARK_GREEN, 4)
ellipse(15, -112, 125, 31, GREEN, DARK_GREEN, 4)

# Raised neck, behind the book
neck = (
bezier((105, -117), (215, -85), (174, 39), (112, 56))
+ bezier((112, 56), (83, 66), (70, 74), (51, 90))[1:]
)
line(neck, DARK_GREEN, 66)
line(neck, GREEN, 58)

# A few python markings
for x, y, rx, ry in [
(150, -69, 12, 17),
(158, -29, 12, 16),
(143, 10, 14, 11),
(107, 39, 13, 9),
(-94, -163, 17, 8),
(-42, -178, 17, 7),
(29, -179, 17, 7),
(100, -167, 17, 8),
]:
ellipse(x, y, rx, ry, "#4c873b", "#4c873b")

# Head
ellipse(15, 96, 82, 55, LIGHT_GREEN, DARK_GREEN, 4)
ellipse(15, 73, 56, 24, "#b7db7a", "#b7db7a")

# Eyes
for x in (-16, 43):
ellipse(x, 108, 22, 23, "white", DARK_GREEN, 2)
# Pupils look down toward the book.
ellipse(x + 2, 100, 7, 10, INK, INK)
ellipse(x, 104, 2, 3, "white", "white")

# Round reading glasses
for x in (-16, 43):
rim = [
(
x + 27 * math.cos(math.radians(a)),
108 + 27 * math.sin(math.radians(a)),
)
for a in range(0, 361, 5)
]
line(rim, "#664735", 4)

line([(11, 110), (16, 112)], "#664735", 4)
line([(-43, 114), (-60, 125)], "#664735", 4)
line([(70, 114), (88, 124)], "#664735", 4)

# Nostrils and a contented smile
ellipse(-5, 77, 2, 3, DARK_GREEN, DARK_GREEN)
ellipse(27, 77, 2, 3, DARK_GREEN, DARK_GREEN)
line(
bezier((-12, 66), (3, 54), (25, 54), (41, 67)),
DARK_GREEN,
3,
)

# Open book: blue covers
polygon(
[(-168, 12), (-8, -14), (0, -27),
(8, -14), (168, 12), (168, -123),
(0, -156), (-168, -123)],
"#396f9d",
"#244664",
4,
)

# Left and right pages
polygon(
[(-156, 24), (-24, 6), (0, -14),
(0, -143), (-24, -127), (-156, -110)],
"#fffdf3",
"#b6aa8a",
)
polygon(
[(0, -14), (24, 6), (156, 24),
(156, -110), (24, -127), (0, -143)],
"#fff8e3",
"#b6aa8a",
)

# Spine
line([(0, -15), (0, -142)], "#a99a7c", 3)

# Page headings
text(-80, -20, "PYTHON", 17)
text(80, -20, "CHAPTER 1", 12)

# Printed lines follow the angle of each page.
for y in (-39, -55, -71, -87):
line([(-135, y + 8), (-25, y - 7)], "#a7aaa5", 2)
line([(25, y - 7), (135, y + 8)], "#a7aaa5", 2)

# Ribbon bookmark
polygon(
[(15, -130), (29, -127), (29, -173),
(22, -164), (15, -177)],
"#df6558",
"#b94940",
)

text(0, 231, "A little light reading...", 24, DARK_GREEN)
text(0, -246, "Even pythons study Python!", 17, DARK_GREEN)

screen.update()
screen.exitonclick()
3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ exclude = [
".github",
"migrations",
"how-to-indent-in-python/sample_code.py",
"agents-md/run1_main.py"
"agents-md/run1_main.py",
"ai-benchmark"
]

[tool.ruff.lint]
Expand Down
Loading