






'''simple docstring'''

import unittest

from transformers import AutoTokenizer, FalconConfig, is_torch_available
from transformers.testing_utils import require_torch, slow, torch_device

from ...generation.test_utils import GenerationTesterMixin
from ...test_configuration_common import ConfigTester
from ...test_modeling_common import ModelTesterMixin, ids_tensor, random_attention_mask
from ...test_pipeline_mixin import PipelineTesterMixin


if is_torch_available():
      import torch

      from transformers import (
          FalconForCausalLM,
          FalconForQuestionAnswering,
          FalconForSequenceClassification,
          FalconForTokenClassification,
          FalconModel,
      )




class     A    :






 """simple docstring"""





 def __init__(							self			,     __lowerCAmelCase			,     __lowerCAmelCase=3			,     __lowerCAmelCase=7			,     __lowerCAmelCase=True			,     __lowerCAmelCase=True			,     __lowerCAmelCase=False			,     __lowerCAmelCase=True			,     __lowerCAmelCase=99			,     __lowerCAmelCase=32			,     __lowerCAmelCase=5			,     __lowerCAmelCase=4			,     __lowerCAmelCase=37			,     __lowerCAmelCase="gelu"			,     __lowerCAmelCase=0.1			,     __lowerCAmelCase=0.1			,     __lowerCAmelCase=5_12			,     __lowerCAmelCase=16			,     __lowerCAmelCase=2			,     __lowerCAmelCase=0.02			,     __lowerCAmelCase=3			,     __lowerCAmelCase=4			,     __lowerCAmelCase=None			,     ):
       UpperCamelCase_				:   Optional[Any]					    =							parent
       UpperCamelCase_				:   List[str]					    =							batch_size
       UpperCamelCase_				:   Optional[Any]					    =							seq_length
       UpperCamelCase_				:   Optional[int]					    =							is_training
       UpperCamelCase_				:   str					    =							use_input_mask
       UpperCamelCase_				:   int					    =							use_token_type_ids
       UpperCamelCase_				:   int					    =							use_labels
       UpperCamelCase_				:   Any					    =							vocab_size
       UpperCamelCase_				:   Union[str, Any]					    =							hidden_size
       UpperCamelCase_				:   str					    =							num_hidden_layers
       UpperCamelCase_				:   Tuple					    =							num_attention_heads
       UpperCamelCase_				:   List[Any]					    =							intermediate_size
       UpperCamelCase_				:   Any					    =							hidden_act
       UpperCamelCase_				:   Union[str, Any]					    =							hidden_dropout_prob
       UpperCamelCase_				:   Optional[Any]					    =							attention_probs_dropout_prob
       UpperCamelCase_				:   List[str]					    =							max_position_embeddings
       UpperCamelCase_				:   Dict					    =							type_vocab_size
       UpperCamelCase_				:   Dict					    =							type_sequence_label_size
       UpperCamelCase_				:   Optional[Any]					    =							initializer_range
       UpperCamelCase_				:   List[str]					    =							num_labels
       UpperCamelCase_				:   str					    =							num_choices
       UpperCamelCase_				:   Tuple					    =							scope
 def   _UpperCAmelCase       (							self ):
       UpperCamelCase_				:   Tuple					    =							ids_tensor([self.batch_size, self.seq_length]			,     self.vocab_size )

       UpperCamelCase_				:   Dict					    =							None
       if self.use_input_mask:
             UpperCamelCase_				:   Optional[int]					    =							random_attention_mask([self.batch_size, self.seq_length] )

       UpperCamelCase_				:   int					    =							None

       UpperCamelCase_				:   Tuple					    =							None
       UpperCamelCase_				:   Union[str, Any]					    =							None
       UpperCamelCase_				:   Optional[int]					    =							None
       if self.use_labels:
             UpperCamelCase_				:   int					    =							ids_tensor([self.batch_size]			,     self.type_sequence_label_size )
             UpperCamelCase_				:   int					    =							ids_tensor([self.batch_size, self.seq_length]			,     self.num_labels )
             UpperCamelCase_				:   List[Any]					    =							ids_tensor([self.batch_size]			,     self.num_choices )

       UpperCamelCase_				:   Any					    =							self.get_config()

       return config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels
 def   _UpperCAmelCase       (							self ):
       return FalconConfig(
           vocab_size=self.vocab_size			,     hidden_size=self.hidden_size			,     num_hidden_layers=self.num_hidden_layers			,     num_attention_heads=self.num_attention_heads			,     intermediate_size=self.intermediate_size			,     hidden_act=self.hidden_act			,     hidden_dropout_prob=self.hidden_dropout_prob			,     attention_probs_dropout_prob=self.attention_probs_dropout_prob			,     max_position_embeddings=self.max_position_embeddings			,     type_vocab_size=self.type_vocab_size			,     is_decoder=__lowerCAmelCase			,     initializer_range=self.initializer_range			,     pad_token_id=1			,     new_decoder_architecture=__lowerCAmelCase			,     )
 def   _UpperCAmelCase       (							self			,     __lowerCAmelCase			,     __lowerCAmelCase			,     __lowerCAmelCase			,     __lowerCAmelCase			,     __lowerCAmelCase			,     __lowerCAmelCase			,     __lowerCAmelCase ):
       UpperCamelCase_				:   List[Any]					    =							FalconModel(config=__lowerCAmelCase )
       model.to(__lowerCAmelCase )
       model.eval()
       UpperCamelCase_				:   List[str]					    =							model(__lowerCAmelCase			,     attention_mask=__lowerCAmelCase )
       UpperCamelCase_				:   Any					    =							model(__lowerCAmelCase )
       self.parent.assertEqual(result.last_hidden_state.shape			,     (self.batch_size, self.seq_length, self.hidden_size) )
 def   _UpperCAmelCase       (							self			,     __lowerCAmelCase			,     __lowerCAmelCase			,     __lowerCAmelCase			,     __lowerCAmelCase			,     __lowerCAmelCase			,     __lowerCAmelCase			,     __lowerCAmelCase			,     __lowerCAmelCase			,     __lowerCAmelCase			,     ):
       UpperCamelCase_				:   Dict					    =							True
       UpperCamelCase_				:   Optional[Any]					    =							FalconModel(__lowerCAmelCase )
       model.to(__lowerCAmelCase )
       model.eval()
       UpperCamelCase_				:   Tuple					    =							model(
           __lowerCAmelCase			,     attention_mask=__lowerCAmelCase			,     encoder_hidden_states=__lowerCAmelCase			,     encoder_attention_mask=__lowerCAmelCase			,     )
       UpperCamelCase_				:   Optional[int]					    =							model(
           __lowerCAmelCase			,     attention_mask=__lowerCAmelCase			,     encoder_hidden_states=__lowerCAmelCase			,     )
       UpperCamelCase_				:   Union[str, Any]					    =							model(__lowerCAmelCase			,     attention_mask=__lowerCAmelCase )
       self.parent.assertEqual(result.last_hidden_state.shape			,     (self.batch_size, self.seq_length, self.hidden_size) )
 def   _UpperCAmelCase       (							self			,     __lowerCAmelCase			,     __lowerCAmelCase			,     __lowerCAmelCase			,     __lowerCAmelCase			,     __lowerCAmelCase			,     __lowerCAmelCase			,     __lowerCAmelCase			,     __lowerCAmelCase			,     __lowerCAmelCase			,     ):
       UpperCamelCase_				:   Optional[int]					    =							FalconForCausalLM(config=__lowerCAmelCase )
       model.to(__lowerCAmelCase )
       model.eval()
       UpperCamelCase_				:   str					    =							model(__lowerCAmelCase			,     attention_mask=__lowerCAmelCase			,     labels=__lowerCAmelCase )
       self.parent.assertEqual(result.logits.shape			,     (self.batch_size, self.seq_length, self.vocab_size) )
 def   _UpperCAmelCase       (							self			,     __lowerCAmelCase			,     __lowerCAmelCase			,     __lowerCAmelCase			,     __lowerCAmelCase			,     __lowerCAmelCase			,     __lowerCAmelCase			,     __lowerCAmelCase			,     __lowerCAmelCase			,     __lowerCAmelCase			,     ):
       UpperCamelCase_				:   str					    =							True
       UpperCamelCase_				:   Optional[Any]					    =							True
       UpperCamelCase_				:   Any					    =							FalconForCausalLM(config=__lowerCAmelCase )
       model.to(__lowerCAmelCase )
       model.eval()

       # first forward pass
       UpperCamelCase_				:   List[str]					    =							model(
           __lowerCAmelCase			,     attention_mask=__lowerCAmelCase			,     encoder_hidden_states=__lowerCAmelCase			,     encoder_attention_mask=__lowerCAmelCase			,     use_cache=__lowerCAmelCase			,     )
       UpperCamelCase_				:   Union[str, Any]					    =							outputs.past_key_values

       # create hypothetical multiple next token and extent to next_input_ids
       UpperCamelCase_				:   List[str]					    =							ids_tensor((self.batch_size, 3)			,     config.vocab_size )
       UpperCamelCase_				:   Optional[int]					    =							ids_tensor((self.batch_size, 3)			,     vocab_size=2 )

       # append to next input_ids and
       UpperCamelCase_				:   List[Any]					    =							torch.cat([input_ids, next_tokens]			,     dim=-1 )
       UpperCamelCase_				:   Optional[int]					    =							torch.cat([input_mask, next_mask]			,     dim=-1 )

       UpperCamelCase_				:   Optional[Any]					    =							model(
           __lowerCAmelCase			,     attention_mask=__lowerCAmelCase			,     encoder_hidden_states=__lowerCAmelCase			,     encoder_attention_mask=__lowerCAmelCase			,     output_hidden_states=__lowerCAmelCase			,     )["""hidden_states"""][0]
       UpperCamelCase_				:   int					    =							model(
           __lowerCAmelCase			,     attention_mask=__lowerCAmelCase			,     encoder_hidden_states=__lowerCAmelCase			,     encoder_attention_mask=__lowerCAmelCase			,     past_key_values=__lowerCAmelCase			,     output_hidden_states=__lowerCAmelCase			,     )["""hidden_states"""][0]

       # select random slice
       UpperCamelCase_				:   List[Any]					    =							ids_tensor((1,)			,     output_from_past.shape[-1] ).item()
       UpperCamelCase_				:   Optional[int]					    =							output_from_no_past[:, -3:, random_slice_idx].detach()
       UpperCamelCase_				:   List[str]					    =							output_from_past[:, :, random_slice_idx].detach()

       self.parent.assertTrue(output_from_past_slice.shape[1] == next_tokens.shape[1] )

       # test that outputs are equal for slice
       self.parent.assertTrue(torch.allclose(__lowerCAmelCase			,     __lowerCAmelCase			,     atol=1E-3 ) )





 def   _UpperCAmelCase       (							self ):
       UpperCamelCase_				:   Dict					    =							self.prepare_config_and_inputs()
       (
           (
           UpperCamelCase_
       )    ,			(
           UpperCamelCase_
       )    ,			(
           UpperCamelCase_
       )    ,			(
           UpperCamelCase_
       )    ,			(
           UpperCamelCase_
       )    ,			(
           UpperCamelCase_
       )    ,			(
           UpperCamelCase_
       )    ,			
       )				:   Optional[Any]					    =							config_and_inputs
       UpperCamelCase_				:   List[Any]					    =							{"""input_ids""": input_ids, """attention_mask""": input_mask}
       return config, inputs_dict






@require_torch
class     A    (      SCREAMING_SNAKE_CASE__,   SCREAMING_SNAKE_CASE__,   SCREAMING_SNAKE_CASE__,   unittest.TestCase						):






 """simple docstring"""





 __a			:						int      =						(
     (
         FalconModel,
         FalconForCausalLM,
         FalconForSequenceClassification,
         FalconForTokenClassification,
         FalconForQuestionAnswering,
     )
     if is_torch_available()
     else ()
 )
 __a			:						Dict      =						(FalconForCausalLM,) if is_torch_available() else ()
 __a			:						Optional[Any]      =						(
     {
         '''feature-extraction''': FalconModel,
         '''text-classification''': FalconForSequenceClassification,
         '''text-generation''': FalconForCausalLM,
         '''question-answering''': FalconForQuestionAnswering,
         '''token-classification''': FalconForTokenClassification,
         '''zero-shot''': FalconForSequenceClassification,
     }
     if is_torch_available()
     else {}
 )
 __a			:						List[Any]      =						False
 __a			:						str      =						False
 def   _UpperCAmelCase       (							self ):
       UpperCamelCase_				:   Optional[Any]					    =							FalconModelTester(self )
       UpperCamelCase_				:   List[Any]					    =							ConfigTester(self			,     config_class=__lowerCAmelCase			,     hidden_size=37 )
 def   _UpperCAmelCase       (							self ):
       self.config_tester.run_common_tests()
 def   _UpperCAmelCase       (							self ):
       UpperCamelCase_				:   List[Any]					    =							self.model_tester.prepare_config_and_inputs()
       self.model_tester.create_and_check_model(*__lowerCAmelCase )
 def   _UpperCAmelCase       (							self ):
       UpperCamelCase_    ,			*UpperCamelCase_				:   str					    =							self.model_tester.prepare_config_and_inputs()
       for alibi in [True, False]:
             UpperCamelCase_				:   Dict					    =							alibi
             self.model_tester.create_and_check_model(__lowerCAmelCase			,     *__lowerCAmelCase )
 def   _UpperCAmelCase       (							self ):
       UpperCamelCase_    ,			UpperCamelCase_				:   str					    =							self.model_tester.prepare_config_and_inputs_for_common()
       UpperCamelCase_				:   int					    =							3
       UpperCamelCase_				:   List[Any]					    =							input_dict["""input_ids"""]
       UpperCamelCase_				:   List[Any]					    =							input_ids.ne(1 ).to(__lowerCAmelCase )
       UpperCamelCase_				:   Union[str, Any]					    =							ids_tensor([self.model_tester.batch_size]			,     self.model_tester.type_sequence_label_size )
       UpperCamelCase_				:   List[Any]					    =							FalconForSequenceClassification(__lowerCAmelCase )
       model.to(__lowerCAmelCase )
       model.eval()
       UpperCamelCase_				:   Union[str, Any]					    =							model(__lowerCAmelCase			,     attention_mask=__lowerCAmelCase			,     labels=__lowerCAmelCase )
       self.assertEqual(result.logits.shape			,     (self.model_tester.batch_size, self.model_tester.num_labels) )
 def   _UpperCAmelCase       (							self ):
       UpperCamelCase_    ,			UpperCamelCase_				:   Tuple					    =							self.model_tester.prepare_config_and_inputs_for_common()
       UpperCamelCase_				:   Tuple					    =							3
       UpperCamelCase_				:   Optional[int]					    =							"""single_label_classification"""
       UpperCamelCase_				:   Dict					    =							input_dict["""input_ids"""]
       UpperCamelCase_				:   Optional[int]					    =							input_ids.ne(1 ).to(__lowerCAmelCase )
       UpperCamelCase_				:   int					    =							ids_tensor([self.model_tester.batch_size]			,     self.model_tester.type_sequence_label_size )
       UpperCamelCase_				:   Optional[Any]					    =							FalconForSequenceClassification(__lowerCAmelCase )
       model.to(__lowerCAmelCase )
       model.eval()
       UpperCamelCase_				:   Dict					    =							model(__lowerCAmelCase			,     attention_mask=__lowerCAmelCase			,     labels=__lowerCAmelCase )
       self.assertEqual(result.logits.shape			,     (self.model_tester.batch_size, self.model_tester.num_labels) )
 def   _UpperCAmelCase       (							self ):
       UpperCamelCase_    ,			UpperCamelCase_				:   Optional[int]					    =							self.model_tester.prepare_config_and_inputs_for_common()
       UpperCamelCase_				:   int					    =							input_dict["""input_ids"""]
       UpperCamelCase_				:   Union[str, Any]					    =							FalconForCausalLM(__lowerCAmelCase )
       model.to(__lowerCAmelCase )
       model.eval()
       UpperCamelCase_				:   str					    =							model(__lowerCAmelCase			,     use_cache=__lowerCAmelCase )
       UpperCamelCase_				:   List[str]					    =							input_ids.shape[0]
       UpperCamelCase_				:   List[str]					    =							model._convert_to_rw_cache(result.past_key_values )
       UpperCamelCase_				:   str					    =							model._convert_cache_to_standard_format(__lowerCAmelCase			,     __lowerCAmelCase )
       for layer in range(len(__lowerCAmelCase ) ):
             for tensor_idx in range(2 ):
                   self.assertTrue(rw_cache[layer][tensor_idx].ndim == 3 )
                   self.assertTrue(result.past_key_values[layer][tensor_idx].ndim == 4 )
                   self.assertTrue(
                       torch.all(result.past_key_values[layer][tensor_idx] == standard_cache[layer][tensor_idx] ) )
 def   _UpperCAmelCase       (							self ):
       UpperCamelCase_    ,			UpperCamelCase_				:   List[str]					    =							self.model_tester.prepare_config_and_inputs_for_common()
       UpperCamelCase_				:   Any					    =							3
       UpperCamelCase_				:   Union[str, Any]					    =							"""multi_label_classification"""
       UpperCamelCase_				:   Optional[Any]					    =							input_dict["""input_ids"""]
       UpperCamelCase_				:   List[Any]					    =							input_ids.ne(1 ).to(__lowerCAmelCase )
       UpperCamelCase_				:   Tuple					    =							ids_tensor(
           [self.model_tester.batch_size, config.num_labels]			,     self.model_tester.type_sequence_label_size ).to(torch.float )
       UpperCamelCase_				:   Tuple					    =							FalconForSequenceClassification(__lowerCAmelCase )
       model.to(__lowerCAmelCase )
       model.eval()
       UpperCamelCase_				:   List[Any]					    =							model(__lowerCAmelCase			,     attention_mask=__lowerCAmelCase			,     labels=__lowerCAmelCase )
       self.assertEqual(result.logits.shape			,     (self.model_tester.batch_size, self.model_tester.num_labels) )





 def   _UpperCAmelCase       (							self ):
       # Falcon can have different numbers of KV-heads than the number of query heads, so we need
       # to override this test to use the right head counts.
       for model_class in self.all_generative_model_classes:
             UpperCamelCase_    ,			UpperCamelCase_				:   int					    =							self.model_tester.prepare_config_and_inputs_for_common()

             # If it doesn't support cache, pass the test
             if not hasattr(__lowerCAmelCase			,     """use_cache""" ):
                   return

             UpperCamelCase_				:   Dict					    =							model_class(__lowerCAmelCase ).to(__lowerCAmelCase )
             if "use_cache" not in inputs:
                   UpperCamelCase_				:   List[Any]					    =							True
             UpperCamelCase_				:   Optional[int]					    =							model(**__lowerCAmelCase )

             # If "past_key_values" is not returned, pass the test (e.g. RWKV uses a different cache name and format)
             if "past_key_values" not in outputs:
                   return

             UpperCamelCase_				:   Union[str, Any]					    =							(
                 getattr(__lowerCAmelCase			,     """decoder_layers"""			,     __lowerCAmelCase )
                 or getattr(__lowerCAmelCase			,     """num_decoder_layers"""			,     __lowerCAmelCase )
                 or config.num_hidden_layers
             )
             UpperCamelCase_				:   List[Any]					    =							getattr(__lowerCAmelCase			,     """num_kv_heads"""			,     config.num_attention_heads )
             UpperCamelCase_				:   Dict					    =							getattr(__lowerCAmelCase			,     """d_model"""			,     config.hidden_size )
             UpperCamelCase_				:   List[Any]					    =							embed_dim // num_attention_heads

             UpperCamelCase_				:   List[Any]					    =							outputs["""past_key_values"""]
             self.assertEqual(len(__lowerCAmelCase )			,     __lowerCAmelCase )

             UpperCamelCase_    ,			UpperCamelCase_				:   Optional[int]					    =							inputs["""input_ids"""].shape
             for i in range(__lowerCAmelCase ):
                   if config.new_decoder_architecture:
                         UpperCamelCase_				:   Any					    =							config.num_attention_heads
                   elif config.multi_query:
                         UpperCamelCase_				:   Dict					    =							1
                   self.assertEqual(len(past_kv[0] )			,     2 )  # K V for the decoder = 2
                   self.assertEqual(
                       past_kv[i][0].shape			,     (batch_size, num_attention_heads, seq_length, per_head_embed_dim) )
                   self.assertEqual(
                       past_kv[i][1].shape			,     (batch_size, num_attention_heads, seq_length, per_head_embed_dim) )






@require_torch
class     A    (      unittest.TestCase						):






 """simple docstring"""





 @slow
 def   _UpperCAmelCase       (							self ):
       UpperCamelCase_				:   Any					    =							AutoTokenizer.from_pretrained("""Rocketknight1/falcon-rw-1b""" )
       UpperCamelCase_				:   Dict					    =							FalconForCausalLM.from_pretrained("""Rocketknight1/falcon-rw-1b""" )
       model.eval()
       model.to(__lowerCAmelCase )
       UpperCamelCase_				:   Optional[int]					    =							tokenizer("""My favorite food is"""			,     return_tensors="""pt""" ).to(__lowerCAmelCase )

       UpperCamelCase_				:   Dict					    =							(
           """My favorite food is pizza. I love it so much that I have a pizza party every year for my birthday."""
       )

       UpperCamelCase_				:   Optional[Any]					    =							model.generate(**__lowerCAmelCase			,     do_sample=__lowerCAmelCase			,     max_new_tokens=19 )
       UpperCamelCase_				:   Dict					    =							tokenizer.batch_decode(__lowerCAmelCase )[0]

       self.assertEqual(__lowerCAmelCase			,     __lowerCAmelCase )
 @slow
 def   _UpperCAmelCase       (							self ):
       # The big models are way too big for the CI, so we use tiny random models that resemble their
       # architectures but with much smaller and fewer layers
       for repo in ["Rocketknight1/tiny-random-falcon-7b", "Rocketknight1/tiny-random-falcon-40b"]:
             UpperCamelCase_				:   Union[str, Any]					    =							AutoTokenizer.from_pretrained(__lowerCAmelCase )
             UpperCamelCase_				:   Any					    =							FalconForCausalLM.from_pretrained(__lowerCAmelCase )
             model.eval()
             model.to(__lowerCAmelCase )
             UpperCamelCase_				:   List[str]					    =							tokenizer("""My favorite food is"""			,     return_tensors="""pt""" ).to(__lowerCAmelCase )

             # We just test that these run without errors - the models are randomly initialized
             # and so the actual text outputs will be garbage
             model.generate(**__lowerCAmelCase			,     do_sample=__lowerCAmelCase			,     max_new_tokens=4 )
             model.generate(**__lowerCAmelCase			,     do_sample=__lowerCAmelCase			,     max_new_tokens=4 )
             model.generate(**__lowerCAmelCase			,     num_beams=2			,     max_new_tokens=4 )





 @slow
 def   _UpperCAmelCase       (							self ):
       # The big models are way too big for the CI, so we use tiny random models that resemble their
       # architectures but with much smaller and fewer layers
       with torch.no_grad():
             for repo in [
                 "Rocketknight1/falcon-rw-1b",
                 "Rocketknight1/tiny-random-falcon-7b",
                 "Rocketknight1/tiny-random-falcon-40b",
             ]:
                   UpperCamelCase_				:   Dict					    =							AutoTokenizer.from_pretrained(__lowerCAmelCase )
                   UpperCamelCase_				:   Optional[int]					    =							FalconForCausalLM.from_pretrained(__lowerCAmelCase )
                   model.eval()
                   model.to(device=__lowerCAmelCase )
                   UpperCamelCase_				:   Dict					    =							tokenizer("""My favorite food is"""			,     return_tensors="""pt""" ).to(__lowerCAmelCase )

                   # Test results are the same with and without cache
                   UpperCamelCase_				:   Optional[int]					    =							model.generate(**__lowerCAmelCase			,     do_sample=__lowerCAmelCase			,     max_new_tokens=20			,     use_cache=__lowerCAmelCase )
                   UpperCamelCase_				:   List[str]					    =							model.generate(**__lowerCAmelCase			,     do_sample=__lowerCAmelCase			,     max_new_tokens=20			,     use_cache=__lowerCAmelCase )
                   self.assertTrue((outputs_cache - outputs_no_cache).sum().item() == 0 )














'''simple docstring'''

def 							snake_case					(     a_							: int	)       ->				int:





      """simple docstring"""

      assert (
          isinstance(a_    ,   a_	) and number_of_steps > 0
      ), f"number_of_steps needs to be positive integer, your input {number_of_steps}"
      if number_of_steps == 1:
            return 1
      UpperCamelCase_    ,			UpperCamelCase_				:   str					    =							1, 1
      for _ in range(number_of_steps - 1	):
            UpperCamelCase_    ,			UpperCamelCase_				:   Tuple					    =							current + previous, current
      return current


if __name__ == "__main__":
      import doctest

      doctest.testmod()






