# We asked if vibecoding had fried people's brains

> Source: <https://codeset.ai/blog/has-vibecoding-fried-your-brain>
> Published: 2026-09-09 11:22:35+00:00

# We asked if vibecoding had fried people’s brains

Nuno Saavedra7 min read

We wanted a meme. The bit was that AI had written enough of everyone’s code that the fundamentals were gone. Has vibecoding fried your brain?

So we made a quiz. We gave it funny characters so it looked like a personality test, and a roast at the end so each person walked away with something of their own to share. We put it at [codeset.ai/fried](https://codeset.ai/fried) and waited for the joke to land.

It took off. A LinkedIn post did the work: 120k+ views, and **5,783 people finished the quiz.**

What started as a joke had a result in it, but not the result the title promised.

## Most people were not fried

The mean score is **4.97** out of 10. The median is **5**. Eighty-six people got a perfect score.

If the meme were true, this chart would pile up on the left. It doesn’t. It peaks at 4 and 5, which is somewhat of a relief... at least for now.

| Verdict | Score | People | Share | 
|---|---|---|---|
| Fried | 0–2 | 718 | 12% | 
| Mush | 3–4 | 1,789 | 31% | 
| Soft | 5–6 | 1,871 | 32% | 
| Toasted | 7–8 | 1,097 | 19% | 
| Intact | 9–10 | 308 | 5% | 

Fried and Intact are the characters you share as a bit, however most people got Mush or Soft.

Each quiz mixed ordinary language questions with a few items framed as something a model wrote. People missed both: 54% of the ordinary items, 42% of the model ones.

## Same quiz, different shapes

Python was the default choice on the quiz, so most people took it: 3,767 finishes, against a few hundred each for JavaScript, Java, and C, and 160 for Rust.

However, the interesting part is not the counts but where the scores sat.

JavaScript, Java, and C look like the same quiz: a bump around 5, means within a tenth of a point of each other. Python, the crowd that never changed the picker, sits a little to the left and Rust sits clearly to the right.

That does not mean Python programmers are worse, or that Rust programmers are better, even though the Rust community will probably still say they are. Python is who showed up. Rust is who chose Rust. The comparison that survives is the middle three: different languages, same shape.

What follows is mostly Python, because that is the sample large enough to look at individual questions. JavaScript shows up when the same idea appears there too.

## The same few ideas, missed over and over

The title said fried brains. The questions said something more specific.

### They still picture a fresh list

``` python
def add(item, bag=[]):
    bag.append(item)
    return bag
```

Two items in the quiz used this trap. One asked what `add(1)` then `add(2)` return. The other showed the same function with two prints, said the model claimed it prints `[1]` then `[2]`, and asked what it actually prints.

The answer to both is `[1]` then `[1, 2]`. The `[]` in `bag=[]` is not rebuilt on each call. Python creates that list once, when the function is defined, and every call appends to the same object.

About six in ten missed the first question. About half missed the second. On the first, **583 of 676 wrong answers were `[1] then [2]`**: people assumed each call started with a fresh, empty list. They knew what `append` did; what they did not picture was the default argument as one actual list, created once, attached to the function, and quietly reused on every call.

I (Nuno) would have been in that pile. I hit this exact bug in a university project: a list kept growing between calls I was sure were independent, and it took me far too long to realize the default argument was the culprit.

A third item tested the same mental model from a different angle:

```
d = {}
a = d.setdefault("items", [])
b = d.setdefault("items", [])
b.append("x")
print(a, b)
```

`setdefault` returns the value already stored under the key, so `a` and `b` point to the same list and the output is `['x'] ['x']`. About 56% missed it. The most common wrong answer was `[] ['x']`: the same instinct as before, treating each expression as if it produced a fresh list rather than another reference to an existing one.

### They don't know what sort does

```
nums = [3, 1, 2]
print(nums.sort())
```

About 59% missed it. **495 people answered `[1, 2, 3]`**. The trap is that `sort()` does two separate things: it **changes `nums` in place**, and it **returns `None`**. So after the call, `nums` is `[1, 2, 3]`, but `print(nums.sort())` prints `None`.

JavaScript has a related trap:

```
console.log([10, 2, 1].sort());
```

About 68% missed it. Most answered `[1, 2, 10]`. Here `sort()` does return the array, but JavaScript sorts elements **as strings by default**, not numerically. It compares `"1"`, `"10"`, and `"2"`, so the result is:

```
[1, 10, 2]
```

Both questions expose the same habit: seeing a familiar method name and jumping straight to the result we expect, without checking exactly what the method returns or how it performs the operation.

### Assignment makes a name local

The hardest identifiable Python item is not a meme.

``` python
def f():
    x = 1
    def g():
        print(x)
        x = 2
    g()
f()
```

*What happens when `f()` runs?*

About **83%** missed it. **292 of 395 misses said “Prints 1.”** That answer assumes `g()` reads the `x` from `f()` and only later creates its own.

Because `g()` assigns to `x` anywhere in its body, Python treats `x` as a **local variable throughout all of `g()`**. So `print(x)` tries to read that local variable before it has been assigned.

The result is an **`UnboundLocalError`**. The later `x = 2` changes what the earlier `print(x)` means.

### A generator is not a list

``` python
def split_positive(values):
    it = (x for x in values if x > 0)
    has_any = any(it)
    return has_any, list(it)
```

*Which input makes this misbehave, if the returned list should contain every positive?*

About **68%** missed it. The most popular wrong answer was `[0, 0]`. The input that actually breaks the function is **`[0, 4]`**: `any()` advances the iterator until it finds the truthy `4`, so by the time `list(it)` runs, the iterator is already exhausted.

That was the pattern across the iterator questions. With `all()` on a generator, about half assumed every value would still be checked even after a false one appeared. With `zip(it, it)` on an odd-length iterator, many expected the leftover element to remain untouched. In each case, the missing mental model was the same: **iterators have state**. If you consume them, they move; if you walk them to the end, they are gone.

### `d.get` is not `d[key]`

``` python
class Buckets(dict):
    def __missing__(self, key):
        value = []
        self[key] = value
        return value

d = Buckets()

d.get("items", []).append("x")
print(d)  # {}

d["items"].append("x")
print(d)  # {'items': ['x']}
```

A dict subclass can define `__missing__` to create a value on demand, but that hook is only used by `d[key]`. `d.get(key, [])` skips it entirely — about **64%** thought it would still call the hook. If you want the bucket to be created before you mutate it, you need `d[key]`, not `get`.

The same protocol detail explains another trap: if `__missing__` does `return self[key]`, it just triggers itself again and again, ending in a **` RecursionError`**, not a `KeyError`.

The gap here is not really about defaults. Most people already understand that `settings.get("retries", 1 / 0)` can still raise even when `"retries"` exists, because the default expression is evaluated before `get` is called.

The real gap is the **lookup protocol**. `get` looks like the safer form of dictionary access, but precisely because it is a different lookup path, it bypasses `__missing__`.

## So did it fry anyone?

Not in the way the joke wanted. The average person who clicked the meme got five out of ten. They catch a lying comment and an empty `except`, but they still picture a fresh default list, a sorted array coming back from `sort`, and a generator you can walk twice.

That is less “brains fried” and more “these objects do not do what the English suggests”.

The quiz is still up. [codeset.ai/fried](https://codeset.ai/fried)
