code: def _generate_line_modifications(lines, change_count):
      def random_line(include_end=False):
          return random.randint(0, len(lines) - (not include_end))
  
      lines = list(lines)
      for _ in range(change_count):
          rand = random.randint(1, 4)
          if rand == 1:
              if len(lines) == 1:
                  # We cannot delete every line, that doesn't make sense to
                  # fuzz and it would be annoying to rewrite everything here.
                  continue
              ld = LineDeletion(random_line())
          elif rand == 2:
              # Copy / Insertion
              # Make it possible to insert into the first and the last line
              ld = LineCopy(
                  random_line(), random_line(include_end=True)
              )
          elif rand in (3, 4):
              # Modify a line in some weird random ways.
              line_nr = random_line()
              line = lines[line_nr]
              column = random.randint(0, len(line))
              random_string = ""
              for _ in range(random.randint(1, 3)):
                  if random.random() > 0.8:
                      # The lower characters cause way more issues.
                      unicode_range = (
                          0x1F if random.randint(0, 1) else 0x3000
                      )
                      random_string += chr(
                          random.randint(0, unicode_range)
                      )
                  else:
                      # These insertions let us understand how random
                      # keyword/operator insertions work. Theoretically this
                      # could also be done with unicode insertions, but the
                      # fuzzer is just way more effective here.
                      random_string += random.choice(
                          _random_python_fragments
                      )
              if random.random() > 0.5:
                  # In this case we insert at a very random place that
                  # probably breaks syntax.
                  line = line[:column] + random_string + line[column:]
              else:
                  # Here we have better chances to not break syntax, because
                  # we really replace the line with something that has
                  # indentation.
                  line = (
                      " " * random.randint(0, 12) + random_string + "\n"
                  )
              ld = LineReplacement(line_nr, line)
          ld.apply(lines)
          yield ld
  
imports: from __future__ import print_function
  import logging
  import sys
  import os
  import random
  import pickle
  import parso
  from parso.utils import split_lines
  from test.test_diff_parser import _check_error_leaves_nodes
label_desc: Use image node_id 2 for calling the FileModification obj's underlying member method code with example usage: obj._generate_line_modifications(lines, change_count) and returns: random