Python Forum
quick function to get indentation level - Printable Version

+- Python Forum (https://python-forum.io)
+-- Forum: General (https://python-forum.io/forum-1.html)
+--- Forum: News and Discussions (https://python-forum.io/forum-31.html)
+--- Thread: quick function to get indentation level (/thread-22021.html)



quick function to get indentation level - Skaperen - Oct-25-2019

i'm reading in a series of lines. it might be better to think of this as iterating over an iterator of lines. the lines may be indented just like reading python source. what i would like for a function or class to do is, given that line (not stripped), return the indentation sequence for it. that is not how many spaces it is indented but rather, is the spaces if the text is indented by exactly one space, regardless of the actual syntax in use (disregard syntax). if the next line un-indents to a level previously seen, its index level will be the same as that level. if the next line un-indents to a number of spaces different than seen before, it can return some error value or raise an exception.

example:
start #0
here #0
  alpha #1
  beta #1
   gamma #2
      delta #3
      epsilon #3
   zeta #2
   eta #2
   theta #2
  iota #1
     kappa #2
      lambda #3
  mu #1
nu #0
    xi #1
        omicron #2
      pi #invalid undentation
anyone know of such a function or class?


RE: quick function to get indentation level - Gribouillis - Oct-25-2019

My attempt
DATA = """\
start #0
here #0
  alpha #1
  beta #1
   gamma #2
      delta #3
      epsilon #3
   zeta #2
   eta #2
   theta #2
  iota #1
     kappa #2
      lambda #3
  mu #1
nu #0
    xi #1
        omicron #2
      pi #invalid undentation
"""

def space_scanned(lines):
    width = 0
    for line in lines:
        x = line.lstrip()
        if x:
            width = len(line) - len(x)
        yield (width, line)

def indent_scanned(lines, lineno=1):
    tabs = [0]
    for no, (width, line) in enumerate(space_scanned(lines), lineno):
        if width > tabs[-1]:
            tabs.append(width)
        else:
            while width < tabs[-1]:
                del tabs[-1]
            if width > tabs[-1]:
                raise IndentationError(('At line ', no, line))
        yield (len(tabs) - 1, line)
        
if __name__ == '__main__':
    import io
    for level, line in indent_scanned(io.StringIO(DATA)):
        print( level, repr(line) )
Output:
λ python3 paillasse/skapindent.py 0 'start #0\n' 0 'here #0\n' 1 ' alpha #1\n' 1 ' beta #1\n' 2 ' gamma #2\n' 3 ' delta #3\n' 3 ' epsilon #3\n' 2 ' zeta #2\n' 2 ' eta #2\n' 2 ' theta #2\n' 1 ' iota #1\n' 2 ' kappa #2\n' 3 ' lambda #3\n' 1 ' mu #1\n' 0 'nu #0\n' 1 ' xi #1\n' 2 ' omicron #2\n' Traceback (most recent call last): File "paillasse/skapindent.py", line 45, in <module> for level, line in indent_scanned(io.StringIO(DATA)): File "paillasse/skapindent.py", line 40, in indent_scanned raise IndentationError(('At line ', no, line)) IndentationError: ('At line ', 18, ' pi #invalid undentation\n')