<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def GetBatchJobDownloadUrlWhenReady(client, batch_job_id, max_poll_attempts=MAX_POLL_ATTEMPTS):
 """Retrieves the downloadUrl when the BatchJob is complete. Args: client: an instantiated AdWordsClient used to poll the BatchJob. batch_job_id: a long identifying the BatchJob to be polled. max_poll_attempts: an int defining the number of times the BatchJob will be checked to determine whether it has completed. Returns: A str containing the downloadUrl of the completed BatchJob. Raises: Exception: If the BatchJob hasn't finished after the maximum poll attempts have been made. """

  batch_job = GetBatchJob(client, batch_job_id)
  if batch_job['status'] == 'CANCELED':
    raise Exception('Batch Job with ID "%s" was canceled before completing.'
                    % batch_job_id)

  poll_attempt = 0

  while (poll_attempt in range(max_poll_attempts) and
         batch_job['status'] in PENDING_STATUSES):
    sleep_interval = (30 * (2 ** poll_attempt) +
                      (random.randint(0, 10000) / 1000))
    print 'Batch Job not ready, sleeping for %s seconds.' % sleep_interval
    time.sleep(sleep_interval)
    batch_job = GetBatchJob(client, batch_job_id)
    poll_attempt += 1

    if 'downloadUrl' in batch_job:
      url = batch_job['downloadUrl']['url']
      print ('Batch Job with Id "%s", Status "%s", and DownloadUrl "%s" ready.'
             % (batch_job['id'], batch_job['status'], url))
      return url

  print ('BatchJob with ID "%s" is being canceled because it was in a pending '
         'state after polling %d times.' % (batch_job_id, max_poll_attempts))
  CancelBatchJob(client, batch_job)