def get_family_id_to_lang_scr_to_sample_key(family_id_to_lang_scrs,
                                           families,
                                           lang_scr_to_sample_infos):

    family_id_to_lang_scr_to_sample_key = {}
    sample_key_to_info = {}

    tested_keys = set()
    failed_keys = set()

    for family_id in sorted(family_id_to_lang_scrs):
      lang_scr_to_sample_key = {}
      for lang_scr in sorted(family_id_to_lang_scrs[family_id]):
        sample_infos = lang_scr_to_sample_infos[lang_scr]
        assert len(sample_infos) > 0

        sample_key_for_lang = None
        for info in sample_infos:
          sample, _, sample_key = info

          full_key = sample_key + '-' + family_id
          if full_key in tested_keys:
            if full_key in failed_keys:
              print 'family %s already rejected sample %s (lang %s)' % (
                  family_id, sample_key, lang_scr)
              continue
          else:
            failed_cps = set()
            tested_keys.add(full_key)
            charset = families[family_id].charset
            for cp in sample:
              if ord(cp) in [
                  0xa, 0x28, 0x29, 0x2c, 0x2d, 0x2e, 0x3b, 0x5b, 0x5d, 0x2010,
                  0xfe0e, 0xfe0f]:
                continue
              if ord(cp) not in charset:
                failed_cps.add(ord(cp))

            if failed_cps:
              print 'family %s rejects sample %s for lang %s:\n  %s' % (
                  family_id, sample_key, lang_scr,
                  '\n  '.join('%04x (%s)' % (
                      cp, unichr(cp)) for cp in sorted(failed_cps)))
              failed_keys.add(full_key)
              continue

          print 'family %s accepts sample %s for lang %s' % (
              family_id, sample_key, lang_scr)

          sample_key_for_lang = sample_key
          if sample_key not in sample_key_to_info:
            sample_key_to_info[sample_key] = info
          break

        if not sample_key_for_lang:
          print '%s has no sample to display in %s' % (lang_scr, family_id)
        else:
          lang_scr_to_sample_key[lang_scr] = sample_key_for_lang

      if not lang_scr_to_sample_key:
        print '!%s can display no samples for any lang of %s' % (
            family_id, ', '.join(sorted(family_id_to_lang_scrs[family_id])))
      else:
        print '%s has samples for %s langs' % (
            family_id, len(lang_scr_to_sample_key))
        family_id_to_lang_scr_to_sample_key[family_id] = lang_scr_to_sample_key

    return (family_id_to_lang_scr_to_sample_key, sample_key_to_info)
Convert the given Exception object into a string, but handling
dataset/ETHPy150Open googlei18n/nototools/nototools/generate_website_2_data.py/get_family_id_to_lang_scr_to_sample_key--crossover with--dataset/ETHPy150Open lsaffre/lino/lino/core/utils.py/error2str