Python Forum
quick function to get indentation level
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
quick function to get indentation level
#1
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?
Tradition is peer pressure from dead people

What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Reply
#2
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')
Reply


Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020