<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def _generate_fixed_param_names(self, param_names: List[str], strategy: str) -> List[str]: """ Generate a fixed parameter list given a list of all parameter names and a strategy. """

        # Number of encoder/decoder layers in model.
        if isinstance(self.config.config_encoder, EmptyEncoderConfig):
            num_encoder_layers = 1
        elif isinstance(self.config.config_encoder, RecurrentEncoderConfig):
            num_encoder_layers = self.config.config_encoder.rnn_config.num_layers
        else:
            num_encoder_layers = self.config.config_encoder.num_layers
        if isinstance(self.config.config_decoder, RecurrentDecoderConfig):
            num_decoder_layers = self.config.config_decoder.rnn_config.num_layers
        else:
            num_decoder_layers = self.config.config_decoder.num_layers

        def is_fixed(name: str) -> bool:
            if strategy == C.FIXED_PARAM_STRATEGY_ALL_EXCEPT_DECODER:
                # Any decoder layer.
                return not name.startswith(C.DECODER_PREFIX)
            if strategy == C.FIXED_PARAM_STRATEGY_ALL_EXCEPT_OUTER_LAYERS:
                # First and last encoder and decoder layers for RNN,
                # Transformer, and CNN models.
                return not (name.startswith("{}{}l{}".format(C.BIDIRECTIONALRNN_PREFIX, C.FORWARD_PREFIX, 0)) or
                            name.startswith("{}{}l{}".format(C.BIDIRECTIONALRNN_PREFIX, C.REVERSE_PREFIX, 0)) or
                            name.startswith("{}l{}".format(C.STACKEDRNN_PREFIX, num_encoder_layers - 2)) or
                            name.startswith("{}l{}".format(C.RNN_DECODER_PREFIX, 0)) or
                            name.startswith("{}l{}".format(C.RNN_DECODER_PREFIX, num_decoder_layers - 1)) or
                            name.startswith("{}{}".format(C.TRANSFORMER_ENCODER_PREFIX, 0)) or
                            name.startswith("{}{}".format(C.TRANSFORMER_ENCODER_PREFIX, num_encoder_layers - 1)) or
                            name.startswith("{}{}".format(C.TRANSFORMER_DECODER_PREFIX, 0)) or
                            name.startswith("{}{}".format(C.TRANSFORMER_DECODER_PREFIX, num_decoder_layers - 1)) or
                            name.startswith("{}{}".format(C.CNN_ENCODER_PREFIX, 0)) or
                            name.startswith("{}{}".format(C.CNN_ENCODER_PREFIX, num_encoder_layers - 1)) or
                            name.startswith("{}{}".format(C.CNN_DECODER_PREFIX, 0)) or
                            name.startswith("{}{}".format(C.CNN_DECODER_PREFIX, num_decoder_layers - 1)))
            if strategy == C.FIXED_PARAM_STRATEGY_ALL_EXCEPT_EMBEDDINGS:
                # Any type of learned embedding.
                return not (name.startswith(C.SOURCE_EMBEDDING_PREFIX) or
                            name.startswith(C.SOURCE_POSITIONAL_EMBEDDING_PREFIX) or
                            name.startswith(C.TARGET_EMBEDDING_PREFIX) or
                            name.startswith(C.TARGET_POSITIONAL_EMBEDDING_PREFIX) or
                            name.startswith(C.SHARED_EMBEDDING_PREFIX))
            if strategy == C.FIXED_PARAM_STRATEGY_ALL_EXCEPT_OUTPUT_PROJ:
                # Target output projection.
                return not name.startswith(C.DEFAULT_OUTPUT_LAYER_PREFIX)
            raise ValueError("Unknown fixed parameter strategy: %s" % strategy)

        return [name for name in param_names if is_fixed(name)]