"""simple docstring"""







import argparse
import logging
import os
import sys
import tempfile
from pathlib import Path

import lightning_base
import pytest
import pytorch_lightning as pl
import torch
from convert_pl_checkpoint_to_hf import convert_pl_to_hf
from distillation import distill_main
from finetune import SummarizationModule, main
from huggingface_hub import list_models
from parameterized import parameterized
from run_eval import generate_summaries_or_translations
from torch import nn

from transformers import AutoConfig, AutoModelForSeqaSeqLM
from transformers.testing_utils import CaptureStderr, CaptureStdout, TestCasePlus, require_torch_gpu, slow
from utils import label_smoothed_nll_loss, lmap, load_json


logging.basicConfig(level=logging.DEBUG)

UpperCamelCase_							:							str				 =		logging.getLogger()
UpperCamelCase_							:							List[Any]				 =		torch.cuda.is_available()
UpperCamelCase_							:							List[str]				 =		{
    """max_tokens_per_batch""": None,
    """supervise_forward""": True,
    """normalize_hidden""": True,
    """label_smoothing""": 0.2,
    """eval_max_gen_length""": None,
    """eval_beams""": 1,
    """val_metric""": """loss""",
    """save_top_k""": 1,
    """adafactor""": True,
    """early_stopping_patience""": 2,
    """logger_name""": """default""",
    """length_penalty""": 0.5,
    """cache_dir""": """""",
    """task""": """summarization""",
    """num_workers""": 2,
    """alpha_hid""": 0,
    """freeze_embeds""": True,
    """enc_only""": False,
    """tgt_suffix""": """""",
    """resume_from_checkpoint""": None,
    """sortish_sampler""": True,
    """student_decoder_layers""": 1,
    """val_check_interval""": 1.0,
    """output_dir""": """""",
    """fp16""": False,  # TODO(SS): set this to CUDA_AVAILABLE if ci installs apex or start using native amp
    """no_teacher""": False,
    """fp16_opt_level""": """O1""",
    """gpus""": 1 if CUDA_AVAILABLE else 0,
    """n_tpu_cores""": 0,
    """max_grad_norm""": 1.0,
    """do_train""": True,
    """do_predict""": True,
    """accumulate_grad_batches""": 1,
    """server_ip""": """""",
    """server_port""": """""",
    """seed""": 42,
    """model_name_or_path""": """sshleifer/bart-tiny-random""",
    """config_name""": """""",
    """tokenizer_name""": """facebook/bart-large""",
    """do_lower_case""": False,
    """learning_rate""": 0.3,
    """lr_scheduler""": """linear""",
    """weight_decay""": 0.0,
    """adam_epsilon""": 1e-08,
    """warmup_steps""": 0,
    """max_epochs""": 1,
    """train_batch_size""": 2,
    """eval_batch_size""": 2,
    """max_source_length""": 12,
    """max_target_length""": 12,
    """val_max_target_length""": 12,
    """test_max_target_length""": 12,
    """fast_dev_run""": False,
    """no_cache""": False,
    """n_train""": -1,
    """n_val""": -1,
    """n_test""": -1,
    """student_encoder_layers""": 1,
    """freeze_encoder""": False,
    """auto_scale_batch_size""": False,
    """overwrite_output_dir""": False,
    """student""": None,
}


def 	a__   (		UpperCAmelCase__							:      str		,      UpperCAmelCase__							:      Dict      )->						Optional[Any]:
						UpperCAmelCase__       						=		"""\n""".join(_a      )
						Path(_a      ).open("""w"""      ).writelines(_a      )


UpperCamelCase_							:							str				 =		[""" Sam ate lunch today.""", """Sams lunch ingredients."""]
UpperCamelCase_							:							str				 =		["""A very interesting story about what I ate for lunch.""", """Avocado, celery, turkey, coffee"""]
UpperCamelCase_							:							Union[str, Any]				 =		"""patrickvonplaten/t5-tiny-random"""
UpperCamelCase_							:							str				 =		"""sshleifer/t5-tinier-random"""
UpperCamelCase_							:							str				 =		"""sshleifer/bart-tiny-random"""
UpperCamelCase_							:							List[Any]				 =		"""sshleifer/tiny-mbart"""
UpperCamelCase_							:							str				 =		"""sshleifer/tiny-marian-en-de"""
UpperCamelCase_							:							Dict				 =		"""stas/tiny-wmt19-en-de"""


UpperCamelCase_							:							str				 =		logging.StreamHandler(sys.stdout)
logger.addHandler(stream_handler)
logging.disable(logging.CRITICAL)  # remove noisy download output from tracebacks


def 	a__   (		UpperCAmelCase__							:      str      )->						Optional[int]:




						for split in ["train", "val", "test"]:
												_dump_articles(os.path.join(_a		,      f'{split}.source'      )		,      _a      )
												_dump_articles(os.path.join(_a		,      f'{split}.target'      )		,      _a      )
						return tmp_dir


class       _lowercase		( lowercase_	):

				@classmethod
				def 							A			(  cls							:     Union[str, Any]  ):


										'''simple docstring'''
										logging.disable(logging.CRITICAL  )  # remove noisy download output from tracebacks
										return cls

				@slow
				@require_torch_gpu
				def 							A			(  self							:     Optional[Any]  ):


										'''simple docstring'''
										UpperCAmelCase__       						=		list_models()
										UpperCAmelCase__       						=		"""sshleifer"""
										UpperCAmelCase__       						=		[x.modelId for x in model_list if x.modelId.startswith(a__  )]
										UpperCAmelCase__       						=		["""sshleifer/blenderbot-3B""", """sshleifer/blenderbot-90M"""]
										UpperCAmelCase__       						=		[]
										for m in model_ids:
																if m in allowed_to_be_broken:
																						continue
																try:
																						AutoConfig.from_pretrained(a__  )
																except Exception:
																						failures.append(a__  )
										assert not failures, f'The following models could not be loaded through AutoConfig: {failures}'

				def 							A			(  self							:     Tuple  ):


										'''simple docstring'''
										UpperCAmelCase__       						=		{"""student_encoder_layers""": 2, """student_decoder_layers""": 1, """no_teacher""": True}
										self._test_distiller_cli(a__  )

				def 							A			(  self							:     Optional[Any]  ):


										'''simple docstring'''
										UpperCAmelCase__       						=		{
										    """student_encoder_layers""": 2,
										    """student_decoder_layers""": 1,
										    """max_epochs""": 4,
										    """val_check_interval""": 0.25,
										    """alpha_hid""": 2.0,
										    """model_name_or_path""": """IGNORE_THIS_IT_DOESNT_GET_USED""",
										}
										UpperCAmelCase__       						=		self._test_distiller_cli(a__							,     check_contents=a__  )

										UpperCAmelCase__       						=		list(Path(model.output_dir  ).glob("""*.ckpt"""  )  )
										self.assertEqual(1							,     len(a__  )  )
										UpperCAmelCase__       						=		list(Path(model.output_dir  ).glob("""**/*.bin"""  )  )
										self.assertEqual(len(a__  )							,     2  )
										UpperCAmelCase__       						=		lmap(str.strip							,     Path(model.hparams.data_dir  ).joinpath("""test.source"""  ).open().readlines()  )
										UpperCAmelCase__       						=		tempfile.mktemp()  # XXX: not being cleaned up
										generate_summaries_or_translations(a__							,     a__							,     str(model.output_dir / """best_tfmr"""  )  )
										self.assertTrue(Path(a__  ).exists()  )

										UpperCAmelCase__       						=		self.get_auto_remove_tmp_dir()
										convert_pl_to_hf(ckpts[0]							,     transformer_ckpts[0].parent							,     a__  )
										assert os.path.exists(os.path.join(a__							,     """pytorch_model.bin"""  )  )

				def 							A			(  self							:     List[Any]  ):


										'''simple docstring'''
										UpperCAmelCase__       						=		AutoModelForSeqaSeqLM.from_pretrained(a__  )
										UpperCAmelCase__						,   UpperCAmelCase__       						=		model.dummy_inputs["""input_ids"""], model.dummy_inputs["""attention_mask"""]
										UpperCAmelCase__       						=		torch.tensor([[0, 4, 8, 2], [0, 8, 2, 1]]							,     dtype=torch.long							,     device=model.device  )
										UpperCAmelCase__       						=		target_ids[:, :-1].contiguous()  # Why this line?
										UpperCAmelCase__       						=		target_ids[:, 1:].clone()  # why clone?
										UpperCAmelCase__       						=		model(
										    a__							,     attention_mask=a__							,     decoder_input_ids=a__							,     labels=a__							,     use_cache=a__  ).loss

										UpperCAmelCase__       						=		model(a__							,     attention_mask=a__							,     decoder_input_ids=a__							,     use_cache=a__  ).logits

										UpperCAmelCase__       						=		nn.functional.log_softmax(a__							,     dim=-1  )
										UpperCAmelCase__						,   UpperCAmelCase__       						=		label_smoothed_nll_loss(
										    a__							,     a__							,     0.1							,     ignore_index=model.config.pad_token_id  )
										with self.assertRaises(a__  ):
																# TODO: understand why this breaks
																self.assertEqual(a__							,     a__  )

				def 							A			(  self							:     List[str]  ):


										'''simple docstring'''
										UpperCAmelCase__       						=		{
										    """student_encoder_layers""": 2,
										    """student_decoder_layers""": 1,
										    """num_train_epochs""": 4,
										    """val_check_interval""": 0.25,
										    """alpha_hid""": 2.0,
										    """task""": """translation""",
										    """model_name_or_path""": """IGNORE_THIS_IT_DOESNT_GET_USED""",
										    """tokenizer_name""": MBART_TINY,
										    """teacher""": MBART_TINY,
										    """src_lang""": """en_XX""",
										    """tgt_lang""": """ro_RO""",
										}
										UpperCAmelCase__       						=		self._test_distiller_cli(a__							,     check_contents=a__  )
										assert model.model.config.model_type == "mbart"

										UpperCAmelCase__       						=		list(Path(model.output_dir  ).glob("""*.ckpt"""  )  )
										self.assertEqual(1							,     len(a__  )  )
										UpperCAmelCase__       						=		list(Path(model.output_dir  ).glob("""**/*.bin"""  )  )
										UpperCAmelCase__       						=		list(Path(model.output_dir  ).glob("""best_tfmr/*"""  )  )
										assert len(a__  ) > 2
										self.assertEqual(len(a__  )							,     2  )

				def 							A			(  self							:     str  ):


										'''simple docstring'''
										UpperCAmelCase__       						=		{
										    """student_encoder_layers""": 1,
										    """student_decoder_layers""": 1,
										    """alpha_hid""": 2.0,
										    """teacher""": T5_TINY,
										    """model_name_or_path""": T5_TINY,
										    """tokenizer_name""": T5_TINY,
										}
										self._test_distiller_cli(a__  )

				def 							A			(  self							:     int  ):


										'''simple docstring'''
										UpperCAmelCase__       						=		{
										    """teacher""": T5_TINY,
										    """student""": T5_TINIER,
										    """model_name_or_path""": T5_TINIER,
										    """tokenizer_name""": T5_TINIER,
										}
										self._test_distiller_cli(a__  )

				def 							A			(  self							:     Any							,     _lowercase							:     Union[str, Any]							,     _lowercase							:     Union[str, Any]=True  ):


										'''simple docstring'''
										UpperCAmelCase__       						=		{
										    """label_smoothing""": 0.0,
										    """early_stopping_patience""": -1,
										    """train_batch_size""": 1,
										    """eval_batch_size""": 2,
										    """max_epochs""": 2,
										    """alpha_mlm""": 0.2,
										    """alpha_ce""": 0.8,
										    """do_predict""": True,
										    """model_name_or_path""": """sshleifer/tinier_bart""",
										    """teacher""": CHEAP_ARGS["""model_name_or_path"""],
										    """val_check_interval""": 0.5,
										}
										default_updates.update(a__  )
										UpperCAmelCase__       						=		CHEAP_ARGS.copy()
										UpperCAmelCase__       						=		make_test_data_dir(tmp_dir=self.get_auto_remove_tmp_dir()  )
										UpperCAmelCase__       						=		self.get_auto_remove_tmp_dir()

										args_d.update(data_dir=a__							,     output_dir=a__							,     **a__  )
										UpperCAmelCase__       						=		distill_main(argparse.Namespace(**a__  )  )
										if not check_contents:
																return model
										UpperCAmelCase__       						=		os.listdir(a__  )
										UpperCAmelCase__       						=		{os.path.basename(a__  ) for p in contents}
										UpperCAmelCase__       						=		[p for p in contents if p.endswith("""ckpt"""  )]
										assert len(a__  ) > 0

										self.assertIn("""test_generations.txt"""							,     a__  )
										self.assertIn("""test_results.txt"""							,     a__  )

										UpperCAmelCase__       						=		load_json(model.metrics_save_path  )
										UpperCAmelCase__       						=		metrics["""val"""][-1]
										self.assertGreaterEqual(last_step_stats["""val_avg_gen_time"""]							,     0.01  )
										self.assertGreaterEqual(1.0							,     last_step_stats["""val_avg_gen_time"""]  )
										self.assertIsInstance(last_step_stats[f'val_avg_{model.val_metric}']							,     a__  )
										UpperCAmelCase__       						=		int(args_d["""max_epochs"""] * (1 / args_d["""val_check_interval"""]) + 1  )
										self.assertEqual(len(metrics["""val"""]  )							,     a__  )
										self.assertEqual(len(metrics["""test"""]  )							,     1  )
										return model


class       _lowercase		( lowercase_	):

				@parameterized.expand(
				    [T5_TINY, BART_TINY, MBART_TINY, MARIAN_TINY, FSMT_TINY]							,     )
				def 							A			(  self							:     Tuple							,     _lowercase							:     Tuple  ):


										'''simple docstring'''
										UpperCAmelCase__       						=		CHEAP_ARGS.copy()
										UpperCAmelCase__       						=		"""translation""" if model in [MBART_TINY, MARIAN_TINY, FSMT_TINY] else """summarization"""
										UpperCAmelCase__       						=		0.1 if task == """translation""" else 0

										UpperCAmelCase__       						=		make_test_data_dir(tmp_dir=self.get_auto_remove_tmp_dir()  )
										UpperCAmelCase__       						=		self.get_auto_remove_tmp_dir()
										args_d.update(
										    data_dir=a__							,     model_name_or_path=a__							,     tokenizer_name=a__							,     train_batch_size=2							,     eval_batch_size=2							,     output_dir=a__							,     do_predict=a__							,     task=a__							,     src_lang="""en_XX"""							,     tgt_lang="""ro_RO"""							,     freeze_encoder=a__							,     freeze_embeds=a__							,     )
										assert "n_train" in args_d
										UpperCAmelCase__       						=		argparse.Namespace(**a__  )
										UpperCAmelCase__       						=		main(a__  )

										UpperCAmelCase__       						=		module.model.get_input_embeddings()
										assert not input_embeds.weight.requires_grad
										if model == T5_TINY:
																UpperCAmelCase__       						=		module.model.lm_head
																assert not lm_head.weight.requires_grad
																assert (lm_head.weight == input_embeds.weight).all().item()
										elif model == FSMT_TINY:
																UpperCAmelCase__       						=		module.model.model
																UpperCAmelCase__       						=		fsmt.decoder.embed_positions
																assert not embed_pos.weight.requires_grad
																assert not fsmt.decoder.embed_tokens.weight.requires_grad
																# check that embeds are not the same
																assert fsmt.decoder.embed_tokens != fsmt.encoder.embed_tokens
										else:
																UpperCAmelCase__       						=		module.model.model
																UpperCAmelCase__       						=		bart.decoder.embed_positions
																assert not embed_pos.weight.requires_grad
																assert not bart.shared.weight.requires_grad
																# check that embeds are the same
																assert bart.decoder.embed_tokens == bart.encoder.embed_tokens
																assert bart.decoder.embed_tokens == bart.shared

										UpperCAmelCase__       						=		load_json(module.output_dir / """text_batch.json"""  )
										assert isinstance(a__							,     a__  )
										assert len(a__  ) >= 4

				def 							A			(  self							:     Any  ):


										'''simple docstring'''
										UpperCAmelCase__       						=		CHEAP_ARGS.copy()

										UpperCAmelCase__       						=		"""summarization"""
										UpperCAmelCase__       						=		make_test_data_dir(tmp_dir=self.get_auto_remove_tmp_dir()  )

										args_d.update(
										    data_dir=a__							,     tokenizer_name=a__							,     train_batch_size=2							,     eval_batch_size=2							,     do_predict=a__							,     task=a__							,     src_lang="""en_XX"""							,     tgt_lang="""ro_RO"""							,     freeze_encoder=a__							,     freeze_embeds=a__							,     )

										# test models whose config includes the extra_model_args
										UpperCAmelCase__       						=		BART_TINY
										UpperCAmelCase__       						=		self.get_auto_remove_tmp_dir()
										UpperCAmelCase__       						=		args_d.copy()
										args_da.update(
										    model_name_or_path=a__							,     output_dir=a__							,     )
										UpperCAmelCase__       						=		("""encoder_layerdrop""", """decoder_layerdrop""", """dropout""", """attention_dropout""")
										for p in extra_model_params:
																UpperCAmelCase__       						=		0.5
										UpperCAmelCase__       						=		argparse.Namespace(**a__  )
										UpperCAmelCase__       						=		main(a__  )
										for p in extra_model_params:
																assert getattr(model.config							,     a__  ) == 0.5, f'failed to override the model config for param {p}'

										# test models whose config doesn't include the extra_model_args
										UpperCAmelCase__       						=		T5_TINY
										UpperCAmelCase__       						=		self.get_auto_remove_tmp_dir()
										UpperCAmelCase__       						=		args_d.copy()
										args_da.update(
										    model_name_or_path=a__							,     output_dir=a__							,     )
										UpperCAmelCase__       						=		"""encoder_layerdrop"""
										UpperCAmelCase__       						=		0.5
										UpperCAmelCase__       						=		argparse.Namespace(**a__  )
										with pytest.raises(a__  ) as excinfo:
																UpperCAmelCase__       						=		main(a__  )
										assert str(excinfo.value  ) == f'model config doesn\'t have a `{unsupported_param}` attribute'

				def 							A			(  self							:     Tuple  ):


										'''simple docstring'''
										UpperCAmelCase__       						=		CHEAP_ARGS.copy()

										UpperCAmelCase__       						=		"""summarization"""
										UpperCAmelCase__       						=		make_test_data_dir(tmp_dir=self.get_auto_remove_tmp_dir()  )

										UpperCAmelCase__       						=		BART_TINY
										UpperCAmelCase__       						=		self.get_auto_remove_tmp_dir()

										args_d.update(
										    data_dir=a__							,     model_name_or_path=a__							,     output_dir=a__							,     tokenizer_name=a__							,     train_batch_size=2							,     eval_batch_size=2							,     do_predict=a__							,     task=a__							,     src_lang="""en_XX"""							,     tgt_lang="""ro_RO"""							,     freeze_encoder=a__							,     freeze_embeds=a__							,     )

										# emulate finetune.py
										UpperCAmelCase__       						=		argparse.ArgumentParser()
										UpperCAmelCase__       						=		pl.Trainer.add_argparse_args(a__  )
										UpperCAmelCase__       						=		SummarizationModule.add_model_specific_args(a__							,     os.getcwd()  )
										UpperCAmelCase__       						=		{"""--help""": True}

										# --help test
										with pytest.raises(a__  ) as excinfo:
																with CaptureStdout() as cs:
																						UpperCAmelCase__       						=		parser.parse_args(a__  )
																assert False, "--help is expected to sys.exit"
										assert excinfo.type == SystemExit
										UpperCAmelCase__       						=		lightning_base.arg_to_scheduler_metavar
										assert expected in cs.out, "--help is expected to list the supported schedulers"

										# --lr_scheduler=non_existing_scheduler test
										UpperCAmelCase__       						=		"""non_existing_scheduler"""
										UpperCAmelCase__       						=		{f'--lr_scheduler={unsupported_param}'}
										with pytest.raises(a__  ) as excinfo:
																with CaptureStderr() as cs:
																						UpperCAmelCase__       						=		parser.parse_args(a__  )
																assert False, "invalid argument is expected to sys.exit"
										assert excinfo.type == SystemExit
										UpperCAmelCase__       						=		f'invalid choice: \'{unsupported_param}\''
										assert expected in cs.err, f'should have bailed on invalid choice of scheduler {unsupported_param}'

										# --lr_scheduler=existing_scheduler test
										UpperCAmelCase__       						=		"""cosine"""
										UpperCAmelCase__       						=		args_d.copy()
										UpperCAmelCase__       						=		supported_param
										UpperCAmelCase__       						=		argparse.Namespace(**a__  )
										UpperCAmelCase__       						=		main(a__  )
										assert (
										    getattr(model.hparams							,     """lr_scheduler"""  ) == supported_param
										), f'lr_scheduler={supported_param} shouldn\'t fail'



import random

class 		__magic_name__				:


  """simple docstring"""





  def __init__(					self	,		a__	,		a__	,		a__ = 0.01	,		a__ = 10_00	,		a__ = -1	,		):
    _lowerCamelCase      =						sample
    if len(self.sample		) == 0:
      raise ValueError('''Sample data can not be empty'''		)
    _lowerCamelCase      =						target
    if len(self.target		) == 0:
      raise ValueError('''Target data can not be empty'''		)
    if len(self.sample		) != len(self.target		):
      raise ValueError('''Sample data and Target data do not have matching lengths'''		)
    _lowerCamelCase      =						learning_rate
    _lowerCamelCase      =						epoch_number
    _lowerCamelCase      =						bias
    _lowerCamelCase      =						len(a__		)
    _lowerCamelCase      =						len(sample[0]		)  # number of columns in dataset
    _lowerCamelCase      =						[]


  def     _UpperCAmelCase  (					self		):
    for sample in self.sample:
      sample.insert(0	,		self.bias		)

    for _ in range(self.col_sample		):
      self.weight.append(random.random()		)

    self.weight.insert(0	,		self.bias		)

    _lowerCamelCase      =						0

    while True:
      _lowerCamelCase      =						False
      for i in range(self.number_sample		):
        _lowerCamelCase      =						0
        for j in range(self.col_sample + 1		):
          _lowerCamelCase      =						u + self.weight[j] * self.sample[i][j]
        _lowerCamelCase      =						self.sign(a__		)
        if y != self.target[i]:
          for j in range(self.col_sample + 1		):
            _lowerCamelCase      =						(
                self.weight[j]
                + self.learning_rate
                * (self.target[i] - y)
                * self.sample[i][j]
            )
          _lowerCamelCase      =						True
            # print('Epoch: \n',epoch_count)
      _lowerCamelCase      =						epoch_count + 1
      # if you want control the epoch or just by error
      if not has_misclassified:
        print(('''\nEpoch:\n''', epoch_count)		)
        print('''------------------------\n'''		)
        # if epoch_count > self.epoch_number or not error:
        break


  def     _UpperCAmelCase  (					self	,		a__		):
    if len(self.sample		) == 0:
      raise ValueError('''Sample data can not be empty'''		)
    sample.insert(0	,		self.bias		)
    _lowerCamelCase      =						0
    for i in range(self.col_sample + 1		):
      _lowerCamelCase      =						u + self.weight[i] * sample[i]

    _lowerCamelCase      =						self.sign(a__		)

    if y == -1:
      print(('''Sample: ''', sample)		)
      print('''classification: P1'''		)
    else:
      print(('''Sample: ''', sample)		)
      print('''classification: P2'''		)


  def     _UpperCAmelCase  (					self	,		a__		):
    return 1 if u >= 0 else -1







_UpperCAmelCase    			=					[
    [-0.6_5_0_8, 0.1_0_9_7, 4.0_0_0_9],
    [-1.4_4_9_2, 0.8_8_9_6, 4.4_0_0_5],
    [2.0_8_5_0, 0.6_8_7_6, 1_2.0_7_1_0],
    [0.2_6_2_6, 1.1_4_7_6, 7.7_9_8_5],
    [0.6_4_1_8, 1.0_2_3_4, 7.0_4_2_7],
    [0.2_5_6_9, 0.6_7_3_0, 8.3_2_6_5],
    [1.1_1_5_5, 0.6_0_4_3, 7.4_4_4_6],
    [0.0_9_1_4, 0.3_3_9_9, 7.0_6_7_7],
    [0.0_1_2_1, 0.5_2_5_6, 4.6_3_1_6],
    [-0.0_4_2_9, 0.4_6_6_0, 5.4_3_2_3],
    [0.4_3_4_0, 0.6_8_7_0, 8.2_2_8_7],
    [0.2_7_3_5, 1.0_2_8_7, 7.1_9_3_4],
    [0.4_8_3_9, 0.4_8_5_1, 7.4_8_5_0],
    [0.4_0_8_9, -0.1_2_6_7, 5.5_0_1_9],
    [1.4_3_9_1, 0.1_6_1_4, 8.5_8_4_3],
    [-0.9_1_1_5, -0.1_9_7_3, 2.1_9_6_2],
    [0.3_6_5_4, 1.0_4_7_5, 7.4_8_5_8],
    [0.2_1_4_4, 0.7_5_1_5, 7.1_6_9_9],
    [0.2_0_1_3, 1.0_0_1_4, 6.5_4_8_9],
    [0.6_4_8_3, 0.2_1_8_3, 5.8_9_9_1],
    [-0.1_1_4_7, 0.2_2_4_2, 7.2_4_3_5],
    [-0.7_9_7_0, 0.8_7_9_5, 3.8_7_6_2],
    [-1.0_6_2_5, 0.6_3_6_6, 2.4_7_0_7],
    [0.5_3_0_7, 0.1_2_8_5, 5.6_8_8_3],
    [-1.2_2_0_0, 0.7_7_7_7, 1.7_2_5_2],
    [0.3_9_5_7, 0.1_0_7_6, 5.6_6_2_3],
    [-0.1_0_1_3, 0.5_9_8_9, 7.1_8_1_2],
    [2.4_4_8_2, 0.9_4_5_5, 1_1.2_0_9_5],
    [2.0_1_4_9, 0.6_1_9_2, 1_0.9_2_6_3],
    [0.2_0_1_2, 0.2_6_1_1, 5.4_6_3_1],
]

_UpperCAmelCase    			=					[
    -1,
    -1,
    -1,
    1,
    1,
    -1,
    1,
    -1,
    1,
    1,
    -1,
    1,
    -1,
    -1,
    -1,
    -1,
    1,
    1,
    1,
    1,
    -1,
    1,
    1,
    1,
    1,
    -1,
    -1,
    1,
    -1,
    1,
]


if __name__ == "__main__":
  import doctest

  doctest.testmod()

  _UpperCAmelCase    			=					Perceptron(
      sample=samples, target=target, learning_rate=0.0_1, epoch_number=1000, bias=-1
  )
  network.training()
  print("Finished training perceptron")
  print("Enter values to predict or q to exit")
  while True:
    _UpperCAmelCase    			=					[]
    for i in range(len(samples[0])):
      _UpperCAmelCase    			=					input("value: ").strip()
      if user_input == "q":
        break
      _UpperCAmelCase    			=					float(user_input)
      sample.insert(i, observation)
    network.sort(sample)




