

import unittest

from transformers.testing_utils import is_torch_available, require_torch, tooslow

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


if is_torch_available():
					import torch

					from transformers import (
					    CpmAntConfig,
					    CpmAntForCausalLM,
					    CpmAntModel,
					    CpmAntTokenizer,
					)

@require_torch
class __UpperCamelCase    :






					'''simple docstring'''



					def __init__(							self							,			lowerCamelCase__							,			lowerCamelCase__=2							,			lowerCamelCase__=8							,			lowerCamelCase__=True							,			lowerCamelCase__=False							,			lowerCamelCase__=False							,			lowerCamelCase__=False							,			lowerCamelCase__=False							,			lowerCamelCase__=9_9							,			lowerCamelCase__=3_2							,			lowerCamelCase__=3							,			lowerCamelCase__=4							,			lowerCamelCase__=3_7							,			lowerCamelCase__=3_2							,			lowerCamelCase__=1_2_8							,			lowerCamelCase__=8							,			lowerCamelCase__=8							,			lowerCamelCase__=8							,			lowerCamelCase__=1.0							,			lowerCamelCase__=True							,			):
						UpperCAmelCase__:  Optional[Any]		       =   parent
						UpperCAmelCase__:  int		       =   batch_size
						UpperCAmelCase__:  Optional[Any]		       =   seq_length
						UpperCAmelCase__:  List[str]		       =   is_training
						UpperCAmelCase__:  str		       =   use_token_type_ids
						UpperCAmelCase__:  List[Any]		       =   use_input_mask
						UpperCAmelCase__:  Dict		       =   use_labels
						UpperCAmelCase__:  Optional[int]		       =   use_mc_token_ids
						UpperCAmelCase__:  Union[str, Any]		       =   vocab_size
						UpperCAmelCase__:  Dict		       =   hidden_size
						UpperCAmelCase__:  List[str]		       =   num_hidden_layers
						UpperCAmelCase__:  Tuple		       =   num_attention_heads
						UpperCAmelCase__:  List[Any]		       =   intermediate_size
						UpperCAmelCase__:  Union[str, Any]		       =   num_buckets
						UpperCAmelCase__:  str		       =   max_distance
						UpperCAmelCase__:  Union[str, Any]		       =   prompt_length
						UpperCAmelCase__:  Tuple		       =   prompt_types
						UpperCAmelCase__:  int		       =   segment_types
						UpperCAmelCase__:  Any		       =   init_std
						UpperCAmelCase__:  List[str]		       =   return_dict





					def       _UpperCAmelCase						(							self	):
						UpperCAmelCase__:  int		       =   {}
						UpperCAmelCase__:  Optional[int]		       =   ids_tensor([self.batch_size, self.seq_length]							,			self.vocab_size	).type(torch.intaa	)
						UpperCAmelCase__:  List[Any]		       =   False

						UpperCAmelCase__:  List[str]		       =   self.get_config()

						return (config, input_ids)





					def       _UpperCAmelCase						(							self	):
						return CpmAntConfig(
						    vocab_size=self.vocab_size							,			hidden_size=self.hidden_size							,			num_hidden_layers=self.num_hidden_layers							,			num_attention_heads=self.num_attention_heads							,			dim_ff=self.intermediate_size							,			position_bias_num_buckets=self.num_buckets							,			position_bias_max_distance=self.max_distance							,			prompt_types=self.prompt_types							,			prompt_length=self.prompt_length							,			segment_types=self.segment_types							,			use_cache=lowerCamelCase__							,			init_std=self.init_std							,			return_dict=self.return_dict							,			)





					def       _UpperCAmelCase						(							self							,			lowerCamelCase__							,			lowerCamelCase__							,			*lowerCamelCase__	):
						UpperCAmelCase__:  Optional[Any]		       =   CpmAntModel(config=lowerCamelCase__	)
						model.to(lowerCamelCase__	)
						model.eval()

						UpperCAmelCase__:  List[str]		       =   model(**lowerCamelCase__	).last_hidden_state

						self.parent.assertEqual(hidden_states.shape							,			(self.batch_size, self.seq_length, config.hidden_size)	)





					def       _UpperCAmelCase						(							self							,			lowerCamelCase__							,			lowerCamelCase__							,			*lowerCamelCase__	):
						UpperCAmelCase__:  Tuple		       =   CpmAntForCausalLM(lowerCamelCase__	)
						model.to(lowerCamelCase__	)
						UpperCAmelCase__:  int		       =   input_ids["input_ids"].to(lowerCamelCase__	)
						model.eval()

						UpperCAmelCase__:  str		       =   model(**lowerCamelCase__	)
						self.parent.assertEqual(
						    model_output.logits.shape							,			(self.batch_size, self.seq_length, config.vocab_size + config.prompt_types * config.prompt_length)							,			)





					def       _UpperCAmelCase						(							self	):
						UpperCAmelCase__       ,	UpperCAmelCase__:  Any		       =   self.prepare_config_and_inputs()
						return config, inputs_dict

@require_torch
class __UpperCamelCase    (							_a				,_a				,unittest.TestCase		):






					'''simple docstring'''



					__magic_name__     			=      (CpmAntModel, CpmAntForCausalLM) if is_torch_available() else ()
					__magic_name__     			=      (
					    {"feature-extraction": CpmAntModel, "text-generation": CpmAntForCausalLM} if is_torch_available() else {}
					)

					__magic_name__     			=      False
					__magic_name__     			=      False
					__magic_name__     			=      False
					__magic_name__     			=      False
					__magic_name__     			=      False





					def       _UpperCAmelCase						(							self	):
						UpperCAmelCase__:  Tuple		       =   CpmAntModelTester(self	)
						UpperCAmelCase__:  Dict		       =   ConfigTester(self							,			config_class=lowerCamelCase__	)





					def       _UpperCAmelCase						(							self	):
						self.config_tester.create_and_test_config_common_properties()
						self.config_tester.create_and_test_config_to_json_string()
						self.config_tester.create_and_test_config_to_json_file()
						self.config_tester.create_and_test_config_from_and_save_pretrained()
						self.config_tester.check_config_can_be_init_without_params()
						self.config_tester.check_config_arguments_init()





					def       _UpperCAmelCase						(							self	):
						unittest.skip("CPMAnt doesn't support input_embeds."	)(self.test_inputs_embeds	)





					def       _UpperCAmelCase						(							self	):
						unittest.skip(
						    "CPMAnt doesn't support retain grad in hidden_states or attentions, because prompt management will peel off the output.hidden_states from graph.\
                 So is attentions. We strongly recommand you use loss to tune model."	)(self.test_retain_grad_hidden_states_attentions	)





					def       _UpperCAmelCase						(							self	):
						UpperCAmelCase__       ,	UpperCAmelCase__:  Optional[int]		       =   self.model_tester.prepare_config_and_inputs()
						self.model_tester.create_and_check_cpmant_model(lowerCamelCase__							,			lowerCamelCase__	)





					def       _UpperCAmelCase						(							self	):
						UpperCAmelCase__       ,	UpperCAmelCase__:  List[Any]		       =   self.model_tester.prepare_config_and_inputs()
						self.model_tester.create_and_check_lm_head_model(lowerCamelCase__							,			lowerCamelCase__	)

@require_torch
class __UpperCamelCase    (							unittest.TestCase		):






					'''simple docstring'''



					@tooslow
					def       _UpperCAmelCase						(							self	):
						UpperCAmelCase__:  Optional[Any]		       =   "今天天气真好！"
						UpperCAmelCase__:  Optional[int]		       =   "openbmb/cpm-ant-10b"
						UpperCAmelCase__:  List[Any]		       =   CpmAntModel.from_pretrained(lowerCamelCase__	)
						UpperCAmelCase__:  Any		       =   CpmAntTokenizer.from_pretrained(lowerCamelCase__	)
						UpperCAmelCase__:  Union[str, Any]		       =   tokenizer(lowerCamelCase__							,			return_tensors="pt"	)
						UpperCAmelCase__:  List[Any]		       =   model(**lowerCamelCase__	).last_hidden_state

						UpperCAmelCase__:  Optional[int]		       =   torch.tensor(
						    [[[6.1_708, 5.9_244, 1.0_835], [6.5_207, 6.2_893, -11.3_324], [-1.0_107, -0.0_576, -5.9_577]]]							,			)
						self.assertTrue(torch.allclose(hidden_states[:, :3, :3]							,			lowerCamelCase__							,			atol=1e-2	)	)

@require_torch
class __UpperCamelCase    (							unittest.TestCase		):






					'''simple docstring'''



					@tooslow
					def       _UpperCAmelCase						(							self	):
						UpperCAmelCase__:  List[str]		       =   "今天天气真好！"
						UpperCAmelCase__:  Any		       =   "openbmb/cpm-ant-10b"
						UpperCAmelCase__:  List[str]		       =   CpmAntForCausalLM.from_pretrained(lowerCamelCase__	)
						UpperCAmelCase__:  Tuple		       =   CpmAntTokenizer.from_pretrained(lowerCamelCase__	)
						UpperCAmelCase__:  int		       =   tokenizer(lowerCamelCase__							,			return_tensors="pt"	)
						UpperCAmelCase__:  str		       =   model(**lowerCamelCase__	).logits

						UpperCAmelCase__:  int		       =   torch.tensor(
						    [[[-6.4_267, -6.4_083, -6.3_958], [-5.8_802, -5.9_447, -5.7_811], [-5.3_896, -5.4_820, -5.4_295]]]							,			)
						self.assertTrue(torch.allclose(hidden_states[:, :3, :3]							,			lowerCamelCase__							,			atol=1e-2	)	)





					@tooslow
					def       _UpperCAmelCase						(							self	):
						UpperCAmelCase__:  Any		       =   "openbmb/cpm-ant-10b"
						UpperCAmelCase__:  Tuple		       =   CpmAntForCausalLM.from_pretrained(lowerCamelCase__	)
						UpperCAmelCase__:  str		       =   CpmAntTokenizer.from_pretrained(lowerCamelCase__	)
						UpperCAmelCase__:  int		       =   "今天天气不错，"
						UpperCAmelCase__:  Tuple		       =   "今天天气不错，阳光明媚，我和妈妈一起去超市买东西。\n在超市里，我看到了一个很好玩的玩具，它的名字叫“机器人”。它有一个圆圆的脑袋，两只圆圆的眼睛，还有一个圆圆的"
						UpperCAmelCase__:  Dict		       =   tokenizer(lowerCamelCase__							,			return_tensors="pt"	)
						UpperCAmelCase__:  Tuple		       =   model.generate(**lowerCamelCase__	)
						UpperCAmelCase__:  Union[str, Any]		       =   tokenizer.batch_decode(lowerCamelCase__	)
						self.assertEqual(lowerCamelCase__							,			lowerCamelCase__	)





					@tooslow
					def       _UpperCAmelCase						(							self	):
						UpperCAmelCase__:  Any		       =   "openbmb/cpm-ant-10b"
						UpperCAmelCase__:  Union[str, Any]		       =   CpmAntForCausalLM.from_pretrained(lowerCamelCase__	)
						UpperCAmelCase__:  List[str]		       =   CpmAntTokenizer.from_pretrained(lowerCamelCase__	)
						UpperCAmelCase__:  Optional[int]		       =   ["今天天气不错，", "新年快乐，万事如意！"]
						UpperCAmelCase__:  List[str]		       =   [
						    "今天天气不错，阳光明媚，我和妈妈一起去超市买东西。\n在超市里，我看到了一个很好玩的玩具，它的名字叫“机器人”。它有一个圆圆的脑袋，两只圆圆的眼睛，还有一个圆圆的",
						    "新年快乐，万事如意！在这辞旧迎新的美好时刻，我谨代表《农村新技术》杂志社全体同仁，向一直以来关心、支持《农村新技术》杂志发展的各级领导、各界朋友和广大读者致以最诚挚的",
						]
						UpperCAmelCase__:  List[Any]		       =   tokenizer(lowerCamelCase__							,			return_tensors="pt"							,			padding=lowerCamelCase__	)
						UpperCAmelCase__:  List[Any]		       =   model.generate(**lowerCamelCase__	)
						UpperCAmelCase__:  int		       =   tokenizer.batch_decode(lowerCamelCase__	)
						self.assertEqual(lowerCamelCase__							,			lowerCamelCase__	)


import warnings

import numpy as np
import pandas as pd
from matplotlib import pyplot as plt
from sklearn.metrics import pairwise_distances

warnings.filterwarnings("""ignore""")

_lowerCAmelCase     :			str    ="""K-MEANS-CLUST/ """



def  _A  (			SCREAMING_SNAKE_CASE  ,SCREAMING_SNAKE_CASE  ,SCREAMING_SNAKE_CASE=None			):
	if seed is not None:  # useful for obtaining consistent results
		np.random.seed(SCREAMING_SNAKE_CASE			)
	UpperCAmelCase__:  Optional[Any]		       =   data.shape[0]  # number of data points

	# Pick K indices from range [0, N).
	UpperCAmelCase__:  Optional[int]		       =   np.random.randint(0  ,SCREAMING_SNAKE_CASE  ,SCREAMING_SNAKE_CASE			)

	# Keep centroids as dense format, as many entries will be nonzero due to averaging.
	# As long as at least one document in a cluster contains a word,
	# it will carry a nonzero weight in the TF-IDF vector of the centroid.
	UpperCAmelCase__:  Tuple		       =   data[rand_indices, :]

	return centroids



def  _A  (			SCREAMING_SNAKE_CASE  ,SCREAMING_SNAKE_CASE			):
	return pairwise_distances(SCREAMING_SNAKE_CASE  ,SCREAMING_SNAKE_CASE  ,metric="euclidean"			)



def  _A  (			SCREAMING_SNAKE_CASE  ,SCREAMING_SNAKE_CASE			):
	# Compute distances between each data point and the set of centroids:
	# Fill in the blank (RHS only)
	UpperCAmelCase__:  Union[str, Any]		       =   centroid_pairwise_dist(SCREAMING_SNAKE_CASE  ,SCREAMING_SNAKE_CASE			)

	# Compute cluster assignments for each data point:
	# Fill in the blank (RHS only)
	UpperCAmelCase__:  Dict		       =   np.argmin(SCREAMING_SNAKE_CASE  ,axis=1			)

	return cluster_assignment



def  _A  (			SCREAMING_SNAKE_CASE  ,SCREAMING_SNAKE_CASE  ,SCREAMING_SNAKE_CASE			):
	UpperCAmelCase__:  str		       =   []
	for i in range(SCREAMING_SNAKE_CASE			):
		# Select all data points that belong to cluster i. Fill in the blank (RHS only)
		UpperCAmelCase__:  Tuple		       =   data[cluster_assignment == i]
		# Compute the mean of the data points. Fill in the blank (RHS only)
		UpperCAmelCase__:  Any		       =   member_data_points.mean(axis=0			)
		new_centroids.append(SCREAMING_SNAKE_CASE			)
	UpperCAmelCase__:  List[Any]		       =   np.array(SCREAMING_SNAKE_CASE			)

	return new_centroids



def  _A  (			SCREAMING_SNAKE_CASE  ,SCREAMING_SNAKE_CASE  ,SCREAMING_SNAKE_CASE  ,SCREAMING_SNAKE_CASE			):
	UpperCAmelCase__:  Tuple		       =   0.0
	for i in range(SCREAMING_SNAKE_CASE			):
		# Select all data points that belong to cluster i. Fill in the blank (RHS only)
		UpperCAmelCase__:  Optional[Any]		       =   data[cluster_assignment == i, :]

		if member_data_points.shape[0] > 0:  # check if i-th cluster is non-empty
			# Compute distances from centroid to data points (RHS only)
			UpperCAmelCase__:  int		       =   pairwise_distances(
			    SCREAMING_SNAKE_CASE  ,[centroids[i]]  ,metric="euclidean"			)
			UpperCAmelCase__:  int		       =   distances**2
			heterogeneity += np.sum(SCREAMING_SNAKE_CASE			)

	return heterogeneity



def  _A  (			SCREAMING_SNAKE_CASE  ,SCREAMING_SNAKE_CASE			):
	plt.figure(figsize=(7, 4)			)
	plt.plot(SCREAMING_SNAKE_CASE  ,linewidth=4			)
	plt.xlabel("# Iterations"			)
	plt.ylabel("Heterogeneity"			)
	plt.title(f"Heterogeneity of clustering over time, K={k:d}"			)
	plt.rcParams.update({"font.size": 1_6}			)
	plt.show()



def  _A  (			SCREAMING_SNAKE_CASE  ,SCREAMING_SNAKE_CASE  ,SCREAMING_SNAKE_CASE  ,SCREAMING_SNAKE_CASE=5_0_0  ,SCREAMING_SNAKE_CASE=None  ,SCREAMING_SNAKE_CASE=False			):
	UpperCAmelCase__:  Optional[int]		       =   initial_centroids[:]
	UpperCAmelCase__:  List[str]		       =   None

	for itr in range(SCREAMING_SNAKE_CASE			):
		if verbose:
			print(SCREAMING_SNAKE_CASE  ,end=""			)

		# 1. Make cluster assignments using nearest centroids
		UpperCAmelCase__:  Optional[Any]		       =   assign_clusters(SCREAMING_SNAKE_CASE  ,SCREAMING_SNAKE_CASE			)

		# 2. Compute a new centroid for each of the k clusters, averaging all data
		#    points assigned to that cluster.
		UpperCAmelCase__:  Union[str, Any]		       =   revise_centroids(SCREAMING_SNAKE_CASE  ,SCREAMING_SNAKE_CASE  ,SCREAMING_SNAKE_CASE			)

		# Check for convergence: if none of the assignments changed, stop
		if (
		    prev_cluster_assignment is not None
		    and (prev_cluster_assignment == cluster_assignment).all()
		):
			break

		# Print number of new assignments
		if prev_cluster_assignment is not None:
			UpperCAmelCase__:  Union[str, Any]		       =   np.sum(prev_cluster_assignment != cluster_assignment			)
			if verbose:
				print(
				    f"    {num_changed:5d} elements changed their cluster assignment."			)

        # Record heterogeneity convergence metric
		if record_heterogeneity is not None:
			# YOUR CODE HERE
			UpperCAmelCase__:  str		       =   compute_heterogeneity(SCREAMING_SNAKE_CASE  ,SCREAMING_SNAKE_CASE  ,SCREAMING_SNAKE_CASE  ,SCREAMING_SNAKE_CASE			)
			record_heterogeneity.append(SCREAMING_SNAKE_CASE			)

		UpperCAmelCase__:  str		       =   cluster_assignment[:]

	return centroids, cluster_assignment


# Mock test below
if False:  # change to true to run this test case.
					from sklearn import datasets as ds

					_lowerCAmelCase     :			Optional[Any]    =ds.load_iris()
					_lowerCAmelCase     :			int    =3
					_lowerCAmelCase     :			List[str]    =[]
					_lowerCAmelCase     :			int    =get_initial_centroids(dataset["""data"""], k, seed=0)
					_lowerCAmelCase   ,  _lowerCAmelCase     :			Union[str, Any]    =kmeans(
					    dataset["""data"""],
					    k,
					    initial_centroids,
					    maxiter=4_00,
					    record_heterogeneity=heterogeneity,
					    verbose=True,
					)
					plot_heterogeneity(heterogeneity, k)



def  _A  (			SCREAMING_SNAKE_CASE  ,SCREAMING_SNAKE_CASE  ,SCREAMING_SNAKE_CASE=None			):
	# Fill missing values with given rules
	if fill_missing_report:
		UpperCAmelCase__:  int		       =   df.fillna(value=SCREAMING_SNAKE_CASE			)
	UpperCAmelCase__:  Any		       =   1
	UpperCAmelCase__:  Any		       =   df.select_dtypes(np.number			).columns
	UpperCAmelCase__:  List[Any]		       =   (
	    df.groupby(["Cluster"]			)[  # construct report dataframe
	        numeric_cols
	    ]  # group by cluster number
	    .agg(
	        [
	            ("sum", np.sum),
	            ("mean_with_zeros", lambda SCREAMING_SNAKE_CASE			: np.mean(np.nan_to_num(SCREAMING_SNAKE_CASE			)			)),
	            ("mean_without_zeros", lambda SCREAMING_SNAKE_CASE			: x.replace(0  ,np.NaN			).mean()),
	            (
	                "mean_25-75",
	                lambda SCREAMING_SNAKE_CASE			: np.mean(
	                    np.nan_to_num(
	                        sorted(SCREAMING_SNAKE_CASE			)[
	                            round(len(SCREAMING_SNAKE_CASE			) * 2_5 / 1_0_0			) : round(len(SCREAMING_SNAKE_CASE			) * 7_5 / 1_0_0			)
	                        ]			)			),
	            ),
	            ("mean_with_na", np.mean),
	            ("min", lambda SCREAMING_SNAKE_CASE			: x.min()),
	            ("5%", lambda SCREAMING_SNAKE_CASE			: x.quantile(0.05			)),
	            ("25%", lambda SCREAMING_SNAKE_CASE			: x.quantile(0.25			)),
	            ("50%", lambda SCREAMING_SNAKE_CASE			: x.quantile(0.50			)),
	            ("75%", lambda SCREAMING_SNAKE_CASE			: x.quantile(0.75			)),
	            ("95%", lambda SCREAMING_SNAKE_CASE			: x.quantile(0.95			)),
	            ("max", lambda SCREAMING_SNAKE_CASE			: x.max()),
	            ("count", lambda SCREAMING_SNAKE_CASE			: x.count()),
	            ("stdev", lambda SCREAMING_SNAKE_CASE			: x.std()),
	            ("mode", lambda SCREAMING_SNAKE_CASE			: x.mode()[0]),
	            ("median", lambda SCREAMING_SNAKE_CASE			: x.median()),
	            ("# > 0", lambda SCREAMING_SNAKE_CASE			: (x > 0).sum()),
	        ]			)
	    .T.reset_index()
	    .rename(index=SCREAMING_SNAKE_CASE  ,columns={"level_0": "Features", "level_1": "Type"}			)
	)  # rename columns
	# calculate the size of cluster(count of clientID's)
	UpperCAmelCase__:  str		       =   report[
	    (report["Features"] == "dummy") & (report["Type"] == "count")
	].copy()  # avoid SettingWithCopyWarning
	UpperCAmelCase__:  int		       =   (
	    "ClusterSize"  # rename created cluster df to match report column names
	)
	UpperCAmelCase__:  List[str]		       =   "# of Customers"
	UpperCAmelCase__:  int		       =   pd.DataFrame(
	    clustersize.iloc[:, 2:].values
	    / clustersize.iloc[:, 2:].values.sum()			)
	UpperCAmelCase__:  Dict		       =   "% of Customers"  # rename created cluster df to match report column names
	UpperCAmelCase__:  Any		       =   "ClusterProportion"
	UpperCAmelCase__:  int		       =   clusterproportion.columns.tolist()
	UpperCAmelCase__:  int		       =   cols[-2:] + cols[:-2]
	UpperCAmelCase__:  Optional[int]		       =   clusterproportion[cols]  # rearrange columns to match report
	UpperCAmelCase__:  Union[str, Any]		       =   report.columns
	UpperCAmelCase__:  int		       =   pd.DataFrame(
	    abs(
	        report[report["Type"] == "count"].iloc[:, 2:].values
	        - clustersize.iloc[:, 2:].values			)			)  # generating df with count of nan values
	UpperCAmelCase__:  Optional[int]		       =   0
	UpperCAmelCase__:  Tuple		       =   "# of nan"
	UpperCAmelCase__:  Any		       =   report[
	    report["Type"] == "count"
	].Features.tolist()  # filling values in order to match report
	UpperCAmelCase__:  int		       =   a.columns.tolist()
	UpperCAmelCase__:  Tuple		       =   cols[-2:] + cols[:-2]
	UpperCAmelCase__:  List[str]		       =   a[cols]  # rearrange columns to match report
	UpperCAmelCase__:  int		       =   report.columns  # rename columns to match report
	UpperCAmelCase__:  List[Any]		       =   report.drop(
	    report[report.Type == "count"].index			)  # drop count values except cluster size
	UpperCAmelCase__:  Optional[Any]		       =   pd.concat(
	    [report, a, clustersize, clusterproportion]  ,axis=0			)  # concat report with clustert size and nan values
	UpperCAmelCase__:  Any		       =   report["Features"].isin(SCREAMING_SNAKE_CASE			)
	UpperCAmelCase__:  Tuple		       =   report.columns.tolist()
	UpperCAmelCase__:  str		       =   cols[0:2] + cols[-1:] + cols[2:-1]
	UpperCAmelCase__:  int		       =   report[cols]
	UpperCAmelCase__:  str		       =   {
	    "ClusterSize": 9,
	    "ClusterProportion": 8,
	    "mean_with_zeros": 7,
	    "mean_with_na": 6,
	    "max": 5,
	    "50%": 4,
	    "min": 3,
	    "25%": 2,
	    "75%": 1,
	    "# of nan": 0,
	    "# > 0": -1,
	    "sum_with_na": -2,
	}
	UpperCAmelCase__:  int		       =   (
	    report.assign(
	        Sortera=lambda SCREAMING_SNAKE_CASE			: x.Type.map(SCREAMING_SNAKE_CASE			)  ,Sortera=lambda SCREAMING_SNAKE_CASE			: list(reversed(range(len(SCREAMING_SNAKE_CASE			)			)			)			)  ,)
	    .sort_values(["Sorter1", "Mark", "Sorter2"]  ,ascending=SCREAMING_SNAKE_CASE			)
	    .drop(["Sorter1", "Sorter2"]  ,axis=1			)
	)
	UpperCAmelCase__:  List[str]		       =   ""
	UpperCAmelCase__:  Any		       =   report.reset_index()
	UpperCAmelCase__:  Any		       =   report.drop(columns=["index"]			)
	return report


if __name__ == "__main__":
					import doctest

					doctest.testmod()