Skip to content

Commit 79aeea4

Browse files
Merge branch 'master' into generate-images-openai
2 parents 02a31ce + 1c2d0b2 commit 79aeea4

281 files changed

Lines changed: 13666 additions & 1027 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎ai-benchmark/README.md‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# How AI Models Draw a Python Reading a Book
2+
3+
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.
4+
5+
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.
6+
7+
| Folder | Write-up |
8+
|---|---|
9+
| [`gpt-6-astra/`](gpt-6-astra/) | [GPT-6 Astra Draws a Python Reading a Book](https://realpython.com/ai-benchmark-gpt-6-astra/) |
10+
| [`claude-fable-5.1/`](claude-fable-5.1/) | [Claude Fable 5.1 Draws a Python Reading a Book](https://realpython.com/ai-benchmark-claude-fable-5-1/) |
11+
12+
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.
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Claude Fable 5.1 Draws a Python Reading a Book
2+
3+
This folder holds the sample code for the Real Python write-up [Claude Fable 5.1 Draws a Python Reading a Book](https://realpython.com/ai-benchmark-claude-fable-5-1/), part of [How AI Models Draw a Python Reading a Book](https://realpython.com/ai-benchmark/).
4+
5+
- Model: `anthropic/claude-fable-5.1`, at its default reasoning settings, run on 2026-09-04
6+
- Prompt: *Write a Python turtle program that draws a python reading a book.*
7+
8+
## What's Here
9+
10+
| File | What |
11+
|---|---|
12+
| `claude-fable-5-1-python-reading-a-book.py` | The turtle script, exactly as the model returned it, with a header naming the model, date, and prompt |
13+
| `claude-fable-5-1-python-reading-a-book.png` | The finished drawing, rendered headlessly at 800×600 |
14+
| `claude-fable-5-1-python-reading-a-book.gif` | The turtle drawing it, frame by frame |
15+
16+
## Run It
17+
18+
You need Python with `tkinter`, which ships with the standard installers from python.org:
19+
20+
```sh
21+
$ python claude-fable-5-1-python-reading-a-book.py
22+
```
23+
24+
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/).
25+
26+
## A Note on the Code
27+
28+
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.
319 KB
Loading
101 KB
Loading
Lines changed: 221 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,221 @@
1+
"""A python reading a book, drawn by Claude Fable 5.1.
2+
3+
Model: anthropic/claude-fable-5.1
4+
Date: 2026-09-04
5+
Prompt: Write a Python turtle program that draws a python reading a book.
6+
7+
Generated for snake-bench, Real Python's vibe check for new AI models:
8+
https://github.com/devcademy/snake-bench
9+
10+
The code is exactly what the model returned. Nothing was fixed up.
11+
Run it with: python claude-fable-5-1-python-reading-a-book.py
12+
"""
13+
14+
import math
15+
import turtle
16+
17+
# ---------------------------------------------------------------- setup
18+
screen = turtle.Screen()
19+
screen.setup(800, 600)
20+
screen.bgcolor("#f7f1e1")
21+
screen.title("A Python Reading a Book")
22+
screen.tracer(0) # draw instantly, then update once
23+
24+
t = turtle.Turtle()
25+
t.hideturtle()
26+
t.speed(0)
27+
28+
SNAKE_DARK = "#2e7d32"
29+
SNAKE_LIGHT = "#9ccc65"
30+
SNAKE_OUTLINE = "#1b4d1e"
31+
COIL_X = -290 # center of the coiled body
32+
33+
34+
# -------------------------------------------------------------- helpers
35+
def jump(x, y, heading=None):
36+
"""Move without drawing, optionally set heading."""
37+
t.penup()
38+
t.goto(x, y)
39+
if heading is not None:
40+
t.setheading(heading)
41+
t.pendown()
42+
43+
44+
def polygon(points, fill, outline=None):
45+
t.color(outline or fill, fill)
46+
t.pensize(2)
47+
t.penup()
48+
t.goto(points[0])
49+
t.pendown()
50+
t.begin_fill()
51+
for p in points[1:]:
52+
t.goto(p)
53+
t.goto(points[0])
54+
t.end_fill()
55+
56+
57+
def arc(radius, extent, w_start, w_end, steps=30):
58+
"""Draw an arc whose pen width tapers smoothly from w_start to w_end."""
59+
for i in range(steps):
60+
t.pensize(w_start + (w_end - w_start) * i / (steps - 1))
61+
t.circle(radius, extent / steps)
62+
63+
64+
# ---------------------------------------------------------------- scene
65+
def draw_table():
66+
polygon([(-400, -215), (400, -215), (400, -300), (-400, -300)],
67+
"#c9a46c", "#a67c48")
68+
t.color("#a67c48")
69+
t.pensize(3)
70+
jump(-400, -215)
71+
t.goto(400, -215)
72+
73+
74+
def draw_book():
75+
# hard cover
76+
polygon([(-175, -215), (0, -235), (175, -215),
77+
(175, -95), (0, -115), (-175, -95)],
78+
"#7a3b1e", "#4d240f")
79+
# left and right pages (slightly tilted toward the spine)
80+
polygon([(-160, -200), (-4, -222), (-4, -118), (-160, -98)],
81+
"#fffaf0", "#d8cfbf")
82+
polygon([(4, -222), (160, -200), (160, -98), (4, -118)],
83+
"#fffaf0", "#d8cfbf")
84+
# spine
85+
t.color("#4d240f")
86+
t.pensize(3)
87+
jump(0, -235)
88+
t.goto(0, -115)
89+
90+
# lines of "text" on each page
91+
t.color("#666666")
92+
t.pensize(2)
93+
lengths = [105, 90, 110, 70, 100, 85]
94+
for i, length in enumerate(lengths):
95+
d = 18 + 13 * i # distance below the top edge
96+
# left page: top edge runs from (-160,-98) to (-4,-118)
97+
x0 = -145
98+
x1 = x0 + length
99+
jump(x0, -118 - d + (-4 - x0) * 20 / 156)
100+
t.goto(x1, -118 - d + (-4 - x1) * 20 / 156)
101+
# right page: top edge runs from (4,-118) to (160,-98)
102+
x0 = 20
103+
x1 = x0 + length
104+
jump(x0, -118 - d + (x0 - 4) * 20 / 156)
105+
t.goto(x1, -118 - d + (x1 - 4) * 20 / 156)
106+
107+
108+
def draw_body(scale, color):
109+
"""Coiled body that spirals outward, then rises into a neck over the book."""
110+
t.color(color)
111+
jump(COIL_X, -140, 0)
112+
widths = [6, 12, 18, 24, 30, 34]
113+
radii = [20, 35, 50, 65, 80]
114+
for i, r in enumerate(radii):
115+
arc(r, 180, widths[i] * scale, widths[i + 1] * scale)
116+
# neck: up and then arching over toward the book
117+
arc(-70, 180, 34 * scale, 34 * scale)
118+
arc(-160, 75, 34 * scale, 34 * scale)
119+
120+
121+
def draw_head():
122+
hx, hy = t.position()
123+
ang = math.radians(t.heading())
124+
fx, fy = math.cos(ang), math.sin(ang) # forward direction
125+
px, py = -fy, fx # perpendicular (left)
126+
127+
cx, cy = hx + 18 * fx, hy + 18 * fy # head center
128+
t.penup()
129+
t.goto(cx, cy)
130+
t.dot(66, SNAKE_OUTLINE)
131+
t.dot(60, SNAKE_DARK)
132+
# snout
133+
t.goto(cx + 22 * fx, cy + 22 * fy)
134+
t.dot(44, SNAKE_OUTLINE)
135+
t.dot(40, SNAKE_DARK)
136+
# lighter "chin"
137+
t.goto(cx + 26 * fx, cy + 26 * fy)
138+
t.dot(24, SNAKE_LIGHT)
139+
140+
# eyes (looking down at the book) with reading glasses
141+
eyes = []
142+
for side in (-1, 1):
143+
ex = cx + 10 * fx + side * 13 * px
144+
ey = cy + 10 * fy + side * 13 * py
145+
eyes.append((ex, ey))
146+
t.goto(ex, ey)
147+
t.dot(16, "white")
148+
t.goto(ex + 3 * fx, ey + 3 * fy)
149+
t.dot(7, "black")
150+
# glasses rim
151+
t.color("black")
152+
t.pensize(2)
153+
jump(ex, ey - 11, 0)
154+
t.circle(11)
155+
(e1x, e1y), (e2x, e2y) = eyes
156+
# bridge of the glasses
157+
jump(e1x + 11 * px, e1y + 11 * py)
158+
t.goto(e2x - 11 * px, e2y - 11 * py)
159+
# temple arms going back along the head
160+
jump(e2x + 11 * px, e2y + 11 * py)
161+
t.goto(e2x + 11 * px - 26 * fx, e2y + 11 * py - 26 * fy)
162+
jump(e1x - 11 * px, e1y - 11 * py)
163+
t.goto(e1x - 11 * px - 26 * fx, e1y - 11 * py - 26 * fy)
164+
165+
# forked tongue
166+
t.color("#e53935")
167+
t.pensize(3)
168+
tx, ty = cx + 42 * fx, cy + 42 * fy
169+
jump(tx, ty, math.degrees(ang))
170+
t.forward(18)
171+
fork = t.position()
172+
t.left(30)
173+
t.forward(9)
174+
jump(*fork, math.degrees(ang))
175+
t.right(30)
176+
t.forward(9)
177+
178+
return cx, cy
179+
180+
181+
def draw_thought_bubble(head_x, head_y):
182+
t.penup()
183+
t.color("#555555", "white")
184+
# trail of small bubbles from the head
185+
for (bx, by, r) in [(head_x + 26, head_y + 36, 8),
186+
(head_x + 46, head_y + 66, 12)]:
187+
t.goto(bx, by)
188+
t.dot(r * 2 + 4, "#555555")
189+
t.dot(r * 2, "white")
190+
# main bubble
191+
bx, by, r = -40, 100, 68
192+
t.goto(bx, by)
193+
t.dot(r * 2 + 4, "#555555")
194+
t.dot(r * 2, "white")
195+
t.color("#1a237e")
196+
t.goto(bx, by + 2)
197+
t.write("import", align="center", font=("Courier", 13, "bold"))
198+
t.goto(bx, by - 20)
199+
t.write("antigravity", align="center", font=("Courier", 13, "bold"))
200+
201+
202+
def draw_caption():
203+
t.penup()
204+
t.goto(0, 235)
205+
t.color("#4d240f")
206+
t.write("A Python reading a book", align="center",
207+
font=("Georgia", 20, "italic"))
208+
209+
210+
# ----------------------------------------------------------------- draw
211+
draw_table()
212+
draw_book()
213+
draw_body(1.0, SNAKE_OUTLINE) # dark outline pass (slightly wider)
214+
draw_body(0.85, SNAKE_DARK) # main body color
215+
draw_body(0.35, SNAKE_LIGHT) # dorsal stripe
216+
cx, cy = draw_head()
217+
draw_thought_bubble(cx, cy)
218+
draw_caption()
219+
220+
screen.update()
221+
turtle.done()

‎ai-benchmark/gpt-6-astra/README.md‎

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# GPT-6 Astra Draws a Python Reading a Book
2+
3+
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/).
4+
5+
- Model: `openai/gpt-6-astra`, at its default reasoning settings, run on 2026-09-04
6+
- Prompt: *Write a Python turtle program that draws a python reading a book.*
7+
8+
## What's Here
9+
10+
| File | What |
11+
|---|---|
12+
| `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 |
13+
| `gpt-6-astra-python-reading-a-book.png` | The finished drawing, rendered headlessly at 800×600 |
14+
| `gpt-6-astra-python-reading-a-book.gif` | The turtle drawing it, frame by frame |
15+
16+
## Run It
17+
18+
You need Python with `tkinter`, which ships with the standard installers from python.org:
19+
20+
```sh
21+
$ python gpt-6-astra-python-reading-a-book.py
22+
```
23+
24+
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/).
25+
26+
## A Note on the Code
27+
28+
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.
170 KB
Loading
82.3 KB
Loading

0 commit comments

Comments
 (0)