docs: def vertical_graph(*args, sep='\n'):
      r"""Consume an iterable of integers and produce a vertical bar graph using
      braille characters.
  
      The graph is vertical in that its dependent axis is the vertical axis. Thus
      each value is represented as a row running left to right, and values are
      listed top to bottom.
  
      If the iterable contains more than four integers, it will be chunked into
      groups of four, separated with newlines by default.
  
          >>> vertical_graph([1, 2, 3, 4])
          '⣷⣄'
          >>> vertical_graph([1, 2, 3, 4, 5, 6])
          '⣷⣄\n⠛⠛⠓'
          >>> print(vertical_graph([1, 2, 3, 4, 5, 6]))
          ⣷⣄
          ⠛⠛⠓
  
      Alternately, the arguments can be passed directly:
  
          >>> vertical_graph(1, 2, 3, 4)
          '⣷⣄'
  
      The optional sep parameter controls how groups are separated. If sep is not
      passed (or if it is None), they are put on their own lines. For example, to
      keep everything on one line, space could be used:
  
          >>> vertical_graph(3, 1, 4, 1, 5, 9, 2, 6, sep=' ')
          '⡯⠥ ⣿⣛⣓⠒⠂'
  
      """
      lines = []
  
      # If the arguments were passed as a single iterable, pull it out.
      # Otherwise, just use them as-is.
      if len(args) == 1:
          bars = args[0]
      else:
          bars = args
  
      # Make sure we use the default when needed
      if sep is None:
          sep = '\n'
  
      # Break the bars into groups of four, one for each row in the braille
      # blocks.
      for bar_group in _chunk(bars, 4):
          line = []
  
          for braille_row, bar_value in enumerate(bar_group):
              # The number of full braille blocks needed to draw this bar. Each
              # block is two dots wide.
              full_blocks_needed = bar_value // 2
  
              # The number of braille blocks needed to draw this bar. The second
              # term accounts for a possible half row.
              blocks_needed = full_blocks_needed + (bar_value % 2)
  
              # The number of braille blocks we'll need to append to the current
              # line to accomodate this bar
              extra_blocks_needed = blocks_needed - len(line)
  
              # If we need extra blocks, add them.
              if extra_blocks_needed > 0:
                  line.extend([_BRAILLE_EMPTY_BLOCK] * extra_blocks_needed)
  
              # Fill in the majority of the bar with full braille rows (two dots).
              for block_index in range(full_blocks_needed):
                  line[block_index] += _BRAILLE_FULL_ROW[braille_row]
  
              # If the bar's value is odd, we'll need to add a single dot at the
              # end.
              if bar_value % 2:
                  line[full_blocks_needed] += _BRAILLE_HALF_ROW[braille_row]
  
          # Wrap up this line by converting all the code points to characters
          # and concatenating them.
          lines.append(''.join(chr(code) for code in line))
  
      # Join all the lines to make the final graph
      return sep.join(lines)