docs: def calculate_fraction_of_sn_discovered(
          log,
          surveyCadenceSettings,
          snSurveyDiscoveryTimes,
          redshifts,
          peakAppMagList,
          snCampaignLengthList,
          extraSurveyConstraints,
          zmin,
          zmax):
      """
      *Given a list of the snSurveyDiscoveryTimes calculate the discovery/non-discovery ratio for a given redshift range*
  
      **Key Arguments:**
          - ``log`` -- logger
          - ``surveyCadenceSettings`` -- the cadence settings for the survey
          - ``snSurveyDiscoveryTimes`` -- the discovery times of the SN relative to the survey year
          - ``redshifts`` -- redshifts of the sne
          - ``peakAppMagList`` -- list of the SN peak magnitude in each filter
          - ``snCampaignLengthList`` -- a list of campaign lengths in each filter
          - ``extraSurveyConstraints`` -- some extra survey constraints
          - ``zmin`` -- minimum redshift in the range
          - ``zmax`` -- maximum redshift in the range
  
      **Return:**
          - None
      """
      ################ > IMPORTS ################
      ## STANDARD LIB ##
      ## THIRD PARTY ##
      ## LOCAL APPLICATION ##
  
      ################ >ACTION(S) ################
      filters = ['g', 'r', 'i', 'z']
      faintMagLimit = extraSurveyConstraints['Faint-Limit of Peak Magnitude']
      lunarMonth = 29.3
      surveyYear = 12. * lunarMonth
      observableFraction = surveyCadenceSettings["Observable Fraction of Year"]
  
      discovered = []
      tooFaint = []
      shortCampaign = []
      discoveredRedshift = []
      tooFaintRedshift = []
      notDiscoveredRedshift = []
      shortCampaignRedshift = []
      #log.info('len(redshifts) %s' % (len(redshifts),))
      dataDictionary = {}
      for item in range(len(redshifts)):
          if redshifts[item] > zmax or redshifts[item] <= zmin:
              continue
          if snSurveyDiscoveryTimes[item]['any'] is True:
              discoveryDayList = []
              faintDayList = []
              shortCampaignDayList = []
              for ffilter in filters:
                  if snSurveyDiscoveryTimes[item][ffilter]:
                      if peakAppMagList[item][ffilter] < faintMagLimit:
                          if (snCampaignLengthList[item]['max'] < extraSurveyConstraints['Observable for at least ? number of days']):
                              shortCampaignDayList.append(
                                  snSurveyDiscoveryTimes[item][ffilter])
                          else:
                              if (surveyYear * observableFraction - snSurveyDiscoveryTimes[item][ffilter]) > extraSurveyConstraints['Observable for at least ? number of days']:
                                  discoveryDayList.append(
                                      snSurveyDiscoveryTimes[item][ffilter])
                              # elif ((surveyYear*observableFraction -
                              # snSurveyDiscoveryTimes[item][ffilter]) <
                              # snSurveyDiscoveryTimes[item][ffilter] <
                              # surveyYear*observableFraction):
                              elif (snCampaignLengthList[item][ffilter] - (surveyYear - snSurveyDiscoveryTimes[item][ffilter])) > extraSurveyConstraints['Observable for at least ? number of days']:
                                  lcTail = snCampaignLengthList[item][
                                      ffilter] - (surveyYear - snSurveyDiscoveryTimes[item][ffilter])
                                  discoveryDayList.append(
                                      snSurveyDiscoveryTimes[item][ffilter])
                              else:
                                  shortCampaignDayList.append(
                                      snSurveyDiscoveryTimes[item][ffilter])
                                  # log.info('item: %s. ffilter %s. too short due to going behind sun, discovery day %s, camp length %s' % (item, ffilter, snSurveyDiscoveryTimes[item][ffilter], snCampaignLengthList[item][ffilter]))
                      else:
                          faintDayList.append(
                              snSurveyDiscoveryTimes[item][ffilter])
  
              if len(discoveryDayList) > 0:
                  discovered.append(min(discoveryDayList))
                  discoveredRedshift.append(redshifts[item])
              elif len(shortCampaignDayList) > 0:
                  shortCampaign.append(min(shortCampaignDayList))
                  shortCampaignRedshift.append(redshifts[item])
              else:
                  tooFaint.append(min(faintDayList))
                  tooFaintRedshift.append(redshifts[item])
          else:
              notDiscoveredRedshift.append(redshifts[item])
  
      if len(notDiscoveredRedshift) > 0:
          dataDictionary["Undiscovered"] = notDiscoveredRedshift
      if len(tooFaintRedshift) > 0:
          dataDictionary[
              "Detected - too faint to constrain as transient"] = tooFaintRedshift
      if len(discoveredRedshift) > 0:
          dataDictionary["Discovered"] = discoveredRedshift
      if len(shortCampaignRedshift) > 0:
          dataDictionary[
              "Detected - campaign to short to constrain as transient"] = shortCampaignRedshift
  
      totalWithinVolume = float(len(discoveredRedshift) + len(
          notDiscoveredRedshift) + len(tooFaintRedshift) + len(shortCampaignRedshift))
  
      if len(discoveredRedshift) == 0:
          discoveryFraction = 0.
      else:
          discoveryFraction = float(len(discoveredRedshift)) / totalWithinVolume
      if len(tooFaintRedshift) == 0:
          tooFaintFraction = 0.
      else:
          tooFaintFraction = float(len(tooFaintRedshift)) / totalWithinVolume
      if len(shortCampaignRedshift) == 0:
          shortCampaignFraction = 0.
      else:
          shortCampaignFraction = float(
              len(shortCampaignRedshift)) / totalWithinVolume
      # log.info('len(discoveredRedshift) %s' % (len(discoveredRedshift),))
      # log.info('len(notDiscoveredRedshift) %s' % (len(notDiscoveredRedshift),))
      # log.info('discoveryFraction %s' % (discoveryFraction,))
  
      return discoveryFraction, tooFaintFraction, shortCampaignFraction