find_lines(path, needle) returning a list of (line_number, line) tuples (1-based numbering, line stripped of its trailing newline) for every line containing needle case-insensitively.find_lines('app.log', 'error') # line 2 is 'DB Error: timeout'[(2, 'DB Error: timeout')]
Case-insensitive match on line 2.
enumerate(f, start=1) numbers the lines.
Compare lowercased haystack and needle.