donnemartin/interactive-coding-challenges · error · TypeError

Invalid argument: None

Error message

Invalid argument: None

What it means

BitsScreen.draw_line raises TypeError('Invalid argument: None') when any of screen, width, x1, x2 is None. The routine performs arithmetic and indexing on all four parameters immediately, so it rejects None inputs before touching them.

Source

Thrown at bit_manipulation/draw_line/draw_line_solution.ipynb:161

  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Code"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "class BitsScreen(object):\n",
    "\n",
    "    def draw_line(self, screen, width, x1, x2):\n",
    "        if None in (screen, width, x1, x2):\n",
    "            raise TypeError('Invalid argument: None')\n",
    "        if not screen or not width:\n",
    "            raise ValueError('Invalid arg: Empty screen or width')\n",
    "        MAX_BIT_VALUE = len(screen) * 8\n",
    "        if x1 < 0 or x2 < 0 or x1 >= MAX_BIT_VALUE or x2 >= MAX_BIT_VALUE:\n",
    "            raise ValueError('Invalid arg: x1 or x2 out of bounds')\n",
    "        start_bit = x1 % 8\n",
    "        end_bit = x2 % 8\n",
    "        first_full_byte = x1 // 8\n",
    "        if start_bit != 0:\n",
    "            first_full_byte += 1\n",
    "        last_full_byte = x2 // 8\n",
    "        if end_bit != (8 - 1):\n",
    "            last_full_byte -= 1\n",
    "        for byte in range(first_full_byte, last_full_byte + 1):\n",
    "            screen[byte] = int('11111111', base=2)\n",
    "        start_byte = x1 // 8\n",
    "        end_byte = x2 // 8\n",
    "        if start_byte == end_byte:\n",

View on GitHub (pinned to 358f2cc604)

Solutions

  1. Pass all four arguments with concrete values: bytearray, width, x1, x2
  2. Validate the payload/config that produces these values before calling
  3. Use parameter defaults at the call site (e.g. x1 = x1 or 0) only when semantically safe

Example fix

# before
bits.draw_line(screen, width, None, 10)

# after
if x1 is None:
    x1 = 0
bits.draw_line(screen, width, x1, 10)
Defensive patterns

Strategy: type-guard

Validate before calling

if any(v is None for v in (screen, width, x1, x2)):
    raise ValueError('screen, width, x1, x2 are all required')
bits_screen.draw_line(screen, width, x1, x2)

Type guard

def has_all(*vals) -> bool:
    return all(v is not None for v in vals)

Try / catch

try:
    bits_screen.draw_line(screen, width, x1, x2)
except TypeError as e:
    if 'Invalid argument' in str(e):
        raise ValueError('missing draw_line argument') from e
    raise

Prevention

When it happens

Trigger: draw_line(None, 8, 0, 7), calling with a partially populated argument list, omitting a positional argument via a dict splat that misses keys, or passing optional params that defaulted to None.

Common situations: Screen buffers or dimensions loaded from config/payloads where fields are absent; refactoring a call site that dropped an argument.

Related errors


AI-assisted analysis of donnemartin/interactive-coding-challenges@358f2cc604 (2026-08-28). Data as JSON: /api/errors/0becb743b124c9b3. Report an issue: GitHub.