## Running Python inside ChatGPT

Running Python inside ChatGPT shows some amazing capabilities that ChatGPT has to understand Python code and evaluate it for you.

# Simulating the Python REPL inside ChatGPT

Lately, I have been reading some interesting articles about ChatGPT. In one, someone invented a new language and had ChatGPT speak it. In another, someone ran a virtual machine inside ChatGPT. The latter inspired me to ask this question:

Can you run an interactive Python session inside ChatGPT?

The short answer is “yes, you can”, and ChatGPT knows quite some Python! I played around with ChatGPT, gave it some different prompts and instructions, and then tested ChatGPT's limits and understanding of the Python language. I was blown away by ChatGPT's understanding of Python. It understood and gave the correct results for code that used:

ChatGPT was also able to write code that solved tasks I gave it.

In this article, I will go through excerpts of my conversations with ChatGPT to highlight some of the amazing things that ChatGPT did and some of the mistakes I was able to catch.

If you just want to go ahead and start playing with ChatGPT yourself, here are two simple prompts that you can try to use:

# Transcripts

This section will contain the transcripts from conversations between me and ChatGPT.

My prompts will be in this colour and I will write exactly what I wrote for ChatGPT.

My comments will show up as regular text, just like this.

Let's start.

## Conversation #1

I want you to simulate a Python interpreter. I will write Python code and your reply will be the REPL prompt, followed by my input, and then the result below. Write no explanations, unless a line ends with #?. If a line ends with #?, add an explanation of the result to your response.

Everything I type is supposed to be Python code that you can execute directly in the REPL. If I need to interact with you, I will start a line with #!. We will resume normal interactions when I exit the REPL.

Right away, ChatGPT was being a bit too verbose for my taste... But at least it showed signs of understanding what I wanted, taking into account the examples it gave and the things it said about #! and #?.

print("Hello, world!")

Alright, so ChatGPT seems to understand the basic function print and it knows the difference between the REPL prompt (>>>) and the results that do not have the prompt.

x = 3
y = 15

ChatGPT also knows that assignments are statements that do not produce results! Great! Now, things start to get interesting:

x + y
y ** x
list(range(y))

Here, ChatGPT shows it remembers the values that we assigned to the previous variables and is able to use them!

def fib(n):
if n <= 1: return 1
return fib(n - 1) + fib(n - 2)

Once more, ChatGPT shows it knows the Python REPL, because multiline blocks (like function definitions) start with the >>> prefix but subsequent lines get the prefix ....

What is even cooler is that we can use the function we just defined. What is even cooler is that we can use it inside a list comprehension. What is even cooler is that we can use #? to ask for an explanation of what is going on:

[fib(i) for i in range(y)]  #?

ChatGPT understood the list comprehension and the recursive function. It gave the correct result, it explained it, and it even gave us the for loop that is equivalent to the list comprehension shown. Is ChatGPT going to render my book on list comprehensions useless?!

At this point, I wondered what Python version we were running:

import sys
sys.version_info

So, it seems we are running Python 3.10. The explanation that followed was correct but I didn't ask for it...

The next few interactions will show my failed attempts at reminding ChatGPT of this and to try to force it to behave that way:

#! You were not supposed to give me an explanation for the previous piece of code. Remember that you only need to explain lines of code that I end with #?. You don't need to explicitly acknowledge this reminder.

1 / 0

#! Don't explain normal lines of code. You only need to explain lines of code that end with #?

prnt("Hello, world!")

This was my attempt at checking if ChatGPT would detect the NameError or if it would “interpret” my intent, which would be to print the string. ChatGPT got it right but it keeps giving unsolicited explanations:

my_dict = {"one": 1, "two": 2, "three": 3}

#! Stop explaining my code.

my_dict["one"] + my_dict["two"]

At this point, I gave up on this session because I couldn't get ChatGPT to stop giving explanations when I didn't ask for them.

I restarted the conversation and tried a new prompt.

## Conversation #2

I want you to simulate a Python interpreter. I will write Python code and your reply will be the REPL prompt, followed by my input, and then the result below. Your reply should be only the prompt, my input, and the result. Never reply with anything other than the requested.

If I terminate a line with #?, I want you to explain only that line of code to me. You can add your explanation in Python comments. If a line does not end with #?, you cannot explain it.

Everything I type is supposed to be Python code that you can execute directly in the REPL. If I need to interact with you, I will start a line with #!. We will resume normal interactions when I exit the REPL.

from itertools import pairwise
for a, b in pairwise(range(10)):
print(a + b, end = ", ")

Let us step it up a notch by importing a non-trivial tool from the standard library, a loop with two looping variables, and using a less common parameter of the function print.

ChatGPT managed to understand exactly what we were computing. Sadly, it didn't give the correct result.

#! You did not reply with the correct, full result. #! Also, I told you to only explain lines with #?. If a line does not have a #?, you cannot explain it.

for a, b in pairwise(range(3, 12)):
print(a + b, end=", ")

Here, ChatGPT apologises for the previous mistake... But does the same, explaining code when not asked to do it. However, its explanation uses perfect natural language to describe the result. The only issue is that the result is wrong:

• it should start at 7; and
• it should go up to 21.

At this point I wondered if part of the difficulty arose from the fact that I was asking for all the numbers to be printed on the same line, so I tried to get rid of the end=", " in each call to print:

for a, b in pairwise(range(10, 20)):
print(a + b)

Once more, ChatGPT gets that we are still doing a similar thing as before. It just gave the wrong results, because this time the results should start at 21 and go up to 37.

## Conversation #3

I want you to act as a Python REPL. My input will be the REPL input and you will display my input with the correct output > inside a single code block.

Do not write explanations.

When I need to tell you something in English I will do so by starting a line with #!

print("Hello, world!")

I tried making it simpler by removing the instructions regarding #?.

#! Import the module that contains information about the current Python version

Here, ChatGPT was able to guess what module I wanted to import and it even went ahead and printed the version information for me. Curiously enough, this time we seem to be running in Python 3.9... So, that got me wondering: can I import itertools.pairwise? I shouldn't be able to do that, since itertools.pairwise was only introduced in Python 3.10:

from itertools import pairwise

It seems ChatGPT isn't that clever! At least, let me try the loop with pairwise again:

for a, b in pairwise(range(10)):
print(a + b)

Finally! That is the correct result!

from itertools import tee
def triplewise(iterable):
a, b, c = tee(iter(iterable), 3)
next(c), next(c), next(b)
yield from zip(a, b, c)
for a, b, c in triplewise(range(10)):
print(a + b + c)

When I got this output back, I almost fell from the chair. Notice that itertools.tee isn't a trivial tool and ChatGPT knew how to use it to implement triplewise, a generalisation of pairwise. Then, it succeeded in using it to compute the sums of the first triples of numbers and this time the result is absolutely correct!

#! Write a function called fib that returns the nth fibonacci number

I gave it another instruction and it fulfilled it. It didn't implement the best (recursive) version of fib possible, but at least the implementation is correct.

Does ChatGPT know Python has a recursion limit?

fib(1050)

ChatGPT knows Python has a recursion limit! Cool! I didn't tell ChatGPT to explain code, and yet it did. At this point I started suspecting it has something to do with exceptions: whenever my code raises an error, ChatGPT explains what is going on. Interestingly enough, it suggested an alternative implementation of fib that works around the recursion limit by using a loop instead of recursion. It then proceeds to presenting what could very well be the result of fib(1050), except it isn't.

That huge number could be fib(1050), as in, it looks believable. But it is very far from the correct result, which starts with 12233... and has about half as many digits.

class MyInt:
def __init__(self, value):
self.value = int(value)

return self.value + other.value

print(MyInt(5) + MyInt(14.5))

ChatGPT understands dunder methods! It knows __init__ is used to initialise objects and it knows __add__ is used to add objects together!

#! Remember that you are not supposed to write code explanations. #! Please, do not write code explanations.

MyInt(5) + 14.5

In this interaction, ChatGPT correctly sees we should raise an error, but it gives the wrong error. The correct error would be an AttributeError:

>>> MyInt(5) + 14.5
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 5, in __add__
AttributeError: 'float' object has no attribute 'value'

Now, I tried telling ChatGPT to not explain code and it just decided to create a random piece of code:

#! Do not explain my code, even if it has errors.

At this point, my next request timed out so I had to start a new conversation.

## Conversation #4

I want you to act as a Python REPL. My input will be the REPL input and you will display the prompt, my input with the correct output inside a single code block.

Do not write explanations. Never improvise. Never write new code that I didn't write. If my code raises an error, do not write an explanation for it.

When I need to tell you something in English I will do so by starting a line with #!

1 / 0

Finally! ChatGPT didn't write an explanation, even after an exception was raised!

#! import the module that lets me generate random numbers

#! write a list comprehension that generates three random integers between 0 and 255, inclusive

class ObjWithProperty:
def __init__(self):
self._value = None

@property
def value(self):
if self._value is None:
print("Generating a new value.")
self._value = random.randint(0, 10)
return self._value

Notice ChatGPT understands in the Python REPL I cannot leave blank lines between methods in a class definition, otherwise the REPL things I am done with defining that class.

o = ObjWithProperty()
o.value
o.value

ChatGPT understands how properties work!

ObjWithProperty().value
ObjWithProperty().value
def decorator(f):
def wrapper(*args, **kwargs):
print(f"Calling {f.__name__} with {args = } and {kwargs = }.")
return f(*args, **kwargs)
return wrapper

Does ChatGPT understand decorators..?

@decorator
return a + b + c

add(10, c=6, b=3)

It does!

Does it know that decorated functions have their name overridden by the wrapper function?

add.__name__

It does!

Does it know that decorated functions have a weird representation?

add

It also does! This is exactly how add would look like in your own Python REPL!

import asyncio

async def my_sleep(label, t):
await asyncio.sleep(t)
print(label)

async def main():
await asyncio.gather(my_sleep("A", 5), my_sleep("B", 1), my_sleep("C", 3))

asyncio.run(main())

ChatGPT even understands asynchronous code! The three labels A, B, and C are printed in the correct order!

Looks like we are on a winning streak, so let us see if ChatGPT can handle large numbers properly.

#! Write an efficient implementation of the fibonacci function

fibonacci(1000)

I checked it and this result is correct! However, how can you tell if ChatGPT computed it according to its own implementation of fibonacci or it just understood that fibonacci computes Fibonacci numbers and, at the same time, somehow knew that that huge number is the 1050th Fibonacci number?

To try and work around that uncertainty, I reimplemented fibonacci in a slightly more obscure way:

def foo(n):
if n.__le__(2): return n
a, b = 0, 1
for _ in range(n.__sub__(1)):
return b
foo(1000)

ChatGPT wasn't fooled! This result is also correct!

## Conversation #5

This conversation shows a shorter and simpler prompt to which ChatGPT reacts decently:

I want you to act as a Python REPL. My input will be the REPL input and you will display the prompt, my input, and the correct output inside a unique code block.

x = 5
y = 18
[x, y, x + y, x - y]

Here is an inefficient piece of code to generate a bunch of prime numbers:

list(filter(lambda x: all(x % d for d in range(2, x)), range(2, 3 ** 10)))

ChatGPT understood we were generating prime numbers and generated a bunch of them! And it understood that from the cryptic one-liner shown above! That is very impressive. However, there are two problems:

1. it skipped the number 283, which should be in that list and is not; and
2. the list stopped way too early, as it should go up to 59029.

Then, I timed out again... Either way, I was running out of ideas for things to test ChatGPT on. I thought of only one more:

## Conversation 6

I want you to act as a Python REPL. My input will be the REPL input and you will display the prompt, my input with the correct output inside a single code block.

Do not write explanations. Never improvise. Never write new code that I didn't write. If my code raises an error, do not write an explanation for it.

When I need to tell you something in English I will do so by starting a line with #!

head, *tail = (my_list := list(map(str, range(10))))
tail
my_list

This shows that ChatGPT understands starred assignment and the walrus operator! Quite impressive!

That's it for now! Stay tuned and I'll see you around!