def _getSmartIndenter(indenterName, qpart, indenter):
    """Get indenter by name.
    Available indenters are none, normal, cstyle, haskell, lilypond, lisp, python, ruby, xml
    Indenter name is not case sensitive
    Raise KeyError if not found
    indentText is indentation, which shall be used. i.e. '\t' for tabs, '    ' for 4 space symbols
    """
    indenterName = indenterName.lower()

    if indenterName in ('haskell', 'lilypond'):  # not supported yet
        logger.warning('Smart indentation for %s not supported yet. But you could be a hero who implemented it' % indenterName)
        from qutepart.indenter.base import IndentAlgNormal as indenterClass
    elif 'none' == indenterName:
        from qutepart.indenter.base import IndentAlgBase as indenterClass
    elif 'normal' == indenterName:
        from qutepart.indenter.base import IndentAlgNormal as indenterClass
    elif 'cstyle' == indenterName:
        from qutepart.indenter.cstyle import IndentAlgCStyle as indenterClass
    elif 'python' == indenterName:
        from qutepart.indenter.python import IndentAlgPython as indenterClass
    elif 'ruby' == indenterName:
        from qutepart.indenter.ruby import IndentAlgRuby as indenterClass
    elif 'xml' == indenterName:
        from qutepart.indenter.xmlindent import IndentAlgXml as indenterClass
    elif 'haskell' == indenterName:
        from qutepart.indenter.haskell import IndenterHaskell as indenterClass
    elif 'lilypond' == indenterName:
        from qutepart.indenter.lilypond import IndenterLilypond as indenterClass
    elif 'lisp' == indenterName:
        from qutepart.indenter.lisp import IndentAlgLisp as indenterClass
    elif 'scheme' == indenterName:
        from qutepart.indenter.scheme import IndentAlgScheme as indenterClass
    else:
        raise KeyError("Indenter %s not found" % indenterName)

    return indenterClass(qpart, indenter)
def read_example_file(
        netcdf_file_name, read_all_target_vars, target_name=None,
        metadata_only=False, targets_only=False, include_soundings=True,
        radar_field_names_to_keep=None, radar_heights_to_keep_m_agl=None,
        sounding_field_names_to_keep=None, sounding_heights_to_keep_m_agl=None,
        first_time_to_keep_unix_sec=None, last_time_to_keep_unix_sec=None,
        num_rows_to_keep=None, num_columns_to_keep=None,
        downsampling_dict=None):
    """Reads examples from NetCDF file.

    If `metadata_only == True`, later input args are ignored.
    If `targets_only == True`, later input args are ignored.

    :param netcdf_file_name: Path to input file.
    :param read_all_target_vars: Boolean flag.  If True, will read all target
        variables.  If False, will read only `target_name`.  Either way, if
        downsampling is done, it will be based only on `target_name`.
    :param target_name: Will read this target variable.  If
        `read_all_target_vars == True` and `downsampling_dict is None`, you can
        leave this alone.
    :param metadata_only: Boolean flag.  If False, this method will read
        everything.  If True, will read everything except predictor and target
        variables.
    :param targets_only: Boolean flag.  If False, this method will read
        everything.  If True, will read everything except predictors.
    :param include_soundings: Boolean flag.  If True and the file contains
        soundings, this method will return soundings.  Otherwise, no soundings.
    :param radar_field_names_to_keep: See doc for `_subset_radar_data`.
    :param radar_heights_to_keep_m_agl: Same.
    :param sounding_field_names_to_keep: See doc for `_subset_sounding_data`.
    :param sounding_heights_to_keep_m_agl: Same.
    :param first_time_to_keep_unix_sec: First time to keep.  If
        `first_time_to_keep_unix_sec is None`, all storm objects will be kept.
    :param last_time_to_keep_unix_sec: Last time to keep.  If
        `last_time_to_keep_unix_sec is None`, all storm objects will be kept.
    :param num_rows_to_keep: See doc for `_subset_radar_data`.
    :param num_columns_to_keep: Same.
    :param downsampling_dict: See doc for `_filter_examples_by_class`.
    :return: example_dict: If `read_all_target_vars == True`, dictionary will
        have all keys listed in doc for `write_example_file`.  If
        `read_all_target_vars == False`, key "target_names" will be replaced by
        "target_name" and "target_matrix" will be replaced by "target_values".

    example_dict['target_name']: Name of target variable.
    example_dict['target_values']: length-E list of target values (integer
        class labels), where E = number of examples.
    """

    # TODO(thunderhoser): Allow this method to read only soundings without radar
    # data.

    if (
            target_name ==
            'tornado_lead-time=0000-3600sec_distance=00000-10000m'
    ):
        target_name = (
            'tornado_lead-time=0000-3600sec_distance=00000-30000m_min-fujita=0'
        )

    error_checking.assert_is_boolean(read_all_target_vars)
    error_checking.assert_is_boolean(include_soundings)
    error_checking.assert_is_boolean(metadata_only)
    error_checking.assert_is_boolean(targets_only)

    example_dict, netcdf_dataset = _read_metadata_from_example_file(
        netcdf_file_name=netcdf_file_name, include_soundings=include_soundings)

    need_main_target_values = (
        not read_all_target_vars
        or downsampling_dict is not None
    )

    if need_main_target_values:
        target_index = example_dict[TARGET_NAMES_KEY].index(target_name)
    else:
        target_index = -1

    if not read_all_target_vars:
        example_dict[TARGET_NAME_KEY] = target_name
        example_dict.pop(TARGET_NAMES_KEY)

    if metadata_only:
        netcdf_dataset.close()
        return example_dict

    if need_main_target_values:
        main_target_values = numpy.array(
            netcdf_dataset.variables[TARGET_MATRIX_KEY][:, target_index],
            dtype=int
        )
    else:
        main_target_values = None

    if read_all_target_vars:
        example_dict[TARGET_MATRIX_KEY] = numpy.array(
            netcdf_dataset.variables[TARGET_MATRIX_KEY][:], dtype=int
        )
    else:
        example_dict[TARGET_VALUES_KEY] = main_target_values

    # Subset by time.
    if first_time_to_keep_unix_sec is None:
        first_time_to_keep_unix_sec = 0
    if last_time_to_keep_unix_sec is None:
        last_time_to_keep_unix_sec = int(1e12)

    error_checking.assert_is_integer(first_time_to_keep_unix_sec)
    error_checking.assert_is_integer(last_time_to_keep_unix_sec)
    error_checking.assert_is_geq(
        last_time_to_keep_unix_sec, first_time_to_keep_unix_sec)

    example_indices_to_keep = numpy.where(numpy.logical_and(
        example_dict[STORM_TIMES_KEY] >= first_time_to_keep_unix_sec,
        example_dict[STORM_TIMES_KEY] <= last_time_to_keep_unix_sec
    ))[0]

    if downsampling_dict is not None:
        subindices_to_keep = _filter_examples_by_class(
            target_values=main_target_values[example_indices_to_keep],
            downsampling_dict=downsampling_dict
        )
    elif not read_all_target_vars:
        subindices_to_keep = numpy.where(
            main_target_values[example_indices_to_keep] !=
            target_val_utils.INVALID_STORM_INTEGER
        )[0]
    else:
        subindices_to_keep = numpy.linspace(
            0, len(example_indices_to_keep) - 1,
            num=len(example_indices_to_keep), dtype=int
        )

    example_indices_to_keep = example_indices_to_keep[subindices_to_keep]
    if len(example_indices_to_keep) == 0:
        return None

    example_dict[FULL_IDS_KEY] = [
        example_dict[FULL_IDS_KEY][k] for k in example_indices_to_keep
    ]
    example_dict[STORM_TIMES_KEY] = (
        example_dict[STORM_TIMES_KEY][example_indices_to_keep]
    )

    if read_all_target_vars:
        example_dict[TARGET_MATRIX_KEY] = (
            example_dict[TARGET_MATRIX_KEY][example_indices_to_keep, :]
        )
    else:
        example_dict[TARGET_VALUES_KEY] = (
            example_dict[TARGET_VALUES_KEY][example_indices_to_keep]
        )

    if targets_only:
        netcdf_dataset.close()
        return example_dict

    example_dict = _subset_radar_data(
        example_dict=example_dict, netcdf_dataset_object=netcdf_dataset,
        example_indices_to_keep=example_indices_to_keep,
        field_names_to_keep=radar_field_names_to_keep,
        heights_to_keep_m_agl=radar_heights_to_keep_m_agl,
        num_rows_to_keep=num_rows_to_keep,
        num_columns_to_keep=num_columns_to_keep)

    if not include_soundings:
        netcdf_dataset.close()
        return example_dict

    example_dict = _subset_sounding_data(
        example_dict=example_dict, netcdf_dataset_object=netcdf_dataset,
        example_indices_to_keep=example_indices_to_keep,
        field_names_to_keep=sounding_field_names_to_keep,
        heights_to_keep_m_agl=sounding_heights_to_keep_m_agl)

    netcdf_dataset.close()
    return example_dict