donnemartin/interactive-coding-challenges · error · TypeError
Cannot have a None input
Error message
Cannot have a None input
What it means
Raised by Hanoi.move_disks when any of the src, dest, or buff tower arguments is None. It is an explicit input-validation guard at the top of the public API before the recursive _move_disks helper runs, because the algorithm assumes all three pegs are real stack-like objects. It exists to fail fast with a clear message instead of an opaque AttributeError deep in the recursion.
Source
Thrown at recursion_dynamic/hanoi/hanoi_solution.ipynb:100
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"%run ../../stacks_queues/stack/stack.py"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"class Hanoi(object):\n",
"\n",
" def move_disks(self, num_disks, src, dest, buff):\n",
" if src is None or dest is None or buff is None:\n",
" raise TypeError('Cannot have a None input')\n",
" self._move_disks(num_disks, src, dest, buff)\n",
"\n",
" def _move_disks(self, num_disks, src, dest, buff):\n",
" if num_disks == 0:\n",
" return\n",
" self.move_disks(num_disks - 1, src, buff, dest)\n",
" dest.push(src.pop())\n",
" self.move_disks(num_disks - 1, buff, dest, src)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Unit Test\n",
"\n"
]
},View on GitHub (pinned to 358f2cc604)
Solutions
- Ensure all three tower arguments are initialized (e.g. dest = Stack(), buff = Stack()) before calling move_disks
- If pegs may be absent, default them to empty Stack instances instead of None
- Add a caller-side guard: if any peg is None, skip or report the call before invoking move_disks
Example fix
// before hanoi.move_disks(3, src, None, buff) // after buff = Stack() hanoi.move_disks(3, src, dest, buff)
Defensive patterns
Strategy: validation
Validate before calling
if src is None or dest is None or buff is None:
raise ValueError('all towers must be provided')
hanoi.move_disks(n, src, dest, buff) Type guard
def valid_towers(*towers):
return all(t is not None for t in towers) Try / catch
try:
hanoi.move_disks(n, src, dest, buff)
except TypeError as e:
if 'Cannot have a None input' in str(e):
# initialize missing towers and retry
... Prevention
- Always construct all three Stack objects up front
- Never default tower parameters to None
When it happens
Trigger: Calling hanoi.move_disks(num_disks, None, dest, buff), or passing any peg as None, e.g. initializing tower objects where one failed to construct. The very first check in move_disks triggers before any recursion.
Common situations: Building the three stacks (source/destination/buffer) from user input or a config where one is missing; refactoring constructors so a peg defaults to None; unmarshalling data where a tower list is absent.
Related errors
- a or b cannot be None
- a or b cannot be None
- a or b cannot be None
- a or b cannot be None
- array cannot be None
AI-assisted analysis of donnemartin/interactive-coding-challenges@358f2cc604 (2026-08-28).
Data as JSON: /api/errors/5e1c05444d1de550.
Report an issue: GitHub.