Finding the longest substring in a string
The algorithm has linear (\$O(n)\$) time complexity, which is good; you can't do better. It also has a linear space complexity, which is not so good; only a constant space is really required. Notice that you don't need to build substr (substr consumes memory!). It suffices to keep track of the start and end indices.
The test for index &lt; len(s) - 1 is un-pythonic. Don't ask permission, ask forgiveness.
The intention to


  minimize the number of loops


is dubious. Does it improve run time? Most likely, no (if you doubt, measure). Does it improve readability? Most likely, no. Consider the pseudocode

  while start_index &lt; string_length:
      length = scan_ordered_substring(string, start_index)
      do_business_logic
      start_index += length

I don't think that

    print(substr);


was intended.