donnemartin/interactive-coding-challenges · error · ValueError
Invalid arg: Empty screen or width
Error message
Invalid arg: Empty screen or width
What it means
BitsScreen.draw_line raises ValueError('Invalid arg: Empty screen or width') when the screen buffer is empty/falsy or width is 0. Drawing a line requires at least one byte of screen and a positive width, so truthiness is checked before computing MAX_BIT_VALUE.
Source
Thrown at bit_manipulation/draw_line/draw_line_solution.ipynb:163
"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",
" left_mask = (1 << (8 - start_bit)) - 1\n",
" right_mask = ~((1 << (8 - end_bit - 1)) - 1)\n",View on GitHub (pinned to 358f2cc604)
Solutions
- Allocate a non-empty screen: screen = bytearray(height_bytes)
- Ensure width is a positive multiple related to screen size before calling
- Add an early guard that skips drawing when there is nothing to draw
Example fix
# before screen = bytearray(0) bits.draw_line(screen, 16, 0, 15) # after screen = bytearray(2) # 16 bits bits.draw_line(screen, 16, 0, 15)
Defensive patterns
Strategy: validation
Validate before calling
if not screen or not width:
raise ValueError('screen buffer and width must be non-empty/positive')
bits_screen.draw_line(screen, width, x1, x2) Type guard
def valid_screen(buf, w) -> bool:
return bool(buf) and isinstance(w, int) and w > 0 Try / catch
try:
bits_screen.draw_line(screen, width, x1, x2)
except ValueError as e:
if 'Empty screen' in str(e):
screen = bytearray(max(1, width // 8))
bits_screen.draw_line(screen, width, x1, x2)
else:
raise Prevention
- Allocate buffers eagerly, not conditionally
- Treat zero-width as a skip condition early in render loops
- Derive buffer size from width so they stay consistent
When it happens
Trigger: draw_line(bytearray(), 8, 0, 0) or draw_line(screen, 0, 0, 7) — an empty bytearray or zero width; also passing a screen variable that was never allocated.
Common situations: Allocating the screen buffer conditionally and skipping allocation on some path; computing width from a division/config value that evaluates to 0.
Related errors
- Invalid arg: x1 or x2 out of bounds
- Invalid index
- Invalid argument: None
- num cannot be 0 or negative
- Index cannot be negative
AI-assisted analysis of donnemartin/interactive-coding-challenges@358f2cc604 (2026-08-28).
Data as JSON: /api/errors/8dcc3751b38c9722.
Report an issue: GitHub.