




from __future__ import annotations







def 			lowerCamelCase_		(       UpperCamelCase__				:      str ,     UpperCamelCase__				:      list[str] | None = None ,     UpperCamelCase__				:      dict[str, float] | None = None ,     UpperCamelCase__				:      bool = False ,     )     ->       tuple[int, float, str]:





				"""simple docstring"""


				__lowerCamelCase		       =    cipher_alphabet or [chr(UpperCamelCase__      ) for i in range(97 ,     123      )]

				# If the argument is None or the user provided an empty dictionary
				if not frequencies_dict:
								# Frequencies of letters in the english language (how much they show up)
								__lowerCamelCase		       =    {
								    'a': 0.0_84_97,
								    'b': 0.0_14_92,
								    'c': 0.0_22_02,
								    'd': 0.0_42_53,
								    'e': 0.1_11_62,
								    'f': 0.0_22_28,
								    'g': 0.0_20_15,
								    'h': 0.0_60_94,
								    'i': 0.0_75_46,
								    'j': 0.0_01_53,
								    'k': 0.0_12_92,
								    'l': 0.0_40_25,
								    'm': 0.0_24_06,
								    'n': 0.0_67_49,
								    'o': 0.0_75_07,
								    'p': 0.0_19_29,
								    'q': 0.0_00_95,
								    'r': 0.0_75_87,
								    's': 0.0_63_27,
								    't': 0.0_93_56,
								    'u': 0.0_27_58,
								    'v': 0.0_09_78,
								    'w': 0.0_25_60,
								    'x': 0.0_01_50,
								    'y': 0.0_19_94,
								    'z': 0.0_00_77,
								}
				else:
								# Custom frequencies dictionary
								__lowerCamelCase		       =    frequencies_dict

				if not case_sensitive:
								__lowerCamelCase		       =    ciphertext.lower()

				# Chi squared statistic values
				__lowerCamelCase		       =    {}

				# cycle through all of the shifts
				for shift in range(len(UpperCamelCase__      )      ):
								__lowerCamelCase		       =    ''

								# decrypt the message with the shift
								for letter in ciphertext:
												try:
																# Try to index the letter in the alphabet
																__lowerCamelCase		       =    (alphabet_letters.index(letter.lower()      ) - shift) % len(
																    UpperCamelCase__      )
																decrypted_with_shift += (
																    alphabet_letters[new_key].upper()
																    if case_sensitive and letter.isupper()
																    else alphabet_letters[new_key]
																)
												except ValueError:
																# Append the character if it isn't in the alphabet
																decrypted_with_shift += letter

								__lowerCamelCase		       =    0.0

								# Loop through each letter in the decoded message with the shift
								for letter in decrypted_with_shift:
												if case_sensitive:
																__lowerCamelCase		       =    letter.lower()
																if letter in frequencies:
																				# Get the amount of times the letter occurs in the message
																				__lowerCamelCase		       =    decrypted_with_shift.lower().count(UpperCamelCase__      )

																				# Get the excepcted amount of times the letter should appear based
																				# on letter frequencies
																				__lowerCamelCase		       =    frequencies[letter] * occurrences

																				# Complete the chi squared statistic formula
																				__lowerCamelCase		       =    ((occurrences - expected) ** 2) / expected

																				# Add the margin of error to the total chi squared statistic
																				chi_squared_statistic += chi_letter_value
												else:
																if letter.lower() in frequencies:
																				# Get the amount of times the letter occurs in the message
																				__lowerCamelCase		       =    decrypted_with_shift.count(UpperCamelCase__      )

																				# Get the excepcted amount of times the letter should appear based
																				# on letter frequencies
																				__lowerCamelCase		       =    frequencies[letter] * occurrences

																				# Complete the chi squared statistic formula
																				__lowerCamelCase		       =    ((occurrences - expected) ** 2) / expected

																				# Add the margin of error to the total chi squared statistic
																				chi_squared_statistic += chi_letter_value

        # Add the data to the chi_squared_statistic_values dictionary
								__lowerCamelCase		       =    (
								    chi_squared_statistic,
								    decrypted_with_shift,
								)

				# Get the most likely cipher by finding the cipher with the smallest chi squared
				# statistic
				def chi_squared_statistic_values_sorting_key(UpperCamelCase__				:      int      ) -> tuple[float, str]:
								return chi_squared_statistic_values[key]

				__lowerCamelCase		       =    min(
				    UpperCamelCase__ ,     key=UpperCamelCase__ ,     )

				# Get all the data from the most likely cipher (key, decoded message)
				(
				    (
				    __lowerCamelCase
				)       ,						(
				    __lowerCamelCase
				)       ,						
				)		       =    chi_squared_statistic_values[most_likely_cipher]

				# Return the data on the most likely shift
				return (
				    most_likely_cipher,
				    most_likely_cipher_chi_squared_value,
				    decoded_most_likely_cipher,
				)




from manim import *







class        A_   (			__lowerCamelCase   ):




	'''simple docstring'''


	def 	SCREAMING_SNAKE_CASE__						(       self       ):
		lowercase       =    Rectangle(height=0.5		,    width=0.5       )
		lowercase       =    Rectangle(height=0.25		,    width=0.25       )
		lowercase       =    Rectangle(height=0.46		,    width=0.46       ).set_stroke(width=0       )

		lowercase       =    [mem.copy() for i in range(6       )]
		lowercase       =    [mem.copy() for i in range(6       )]
		lowercase       =    VGroup(*snake_case       ).arrange(snake_case		,    buff=0       )
		lowercase       =    VGroup(*snake_case       ).arrange(snake_case		,    buff=0       )
		lowercase       =    VGroup(snake_case		,    snake_case       ).arrange(snake_case		,    buff=0       )
		lowercase       =    Text('CPU'		,    font_size=24       )
		lowercase       =    Group(snake_case		,    snake_case       ).arrange(snake_case		,    buff=0.5		,    aligned_edge=snake_case       )
		cpu.move_to([-2.5, -0.5, 0]       )
		self.add(snake_case       )

		lowercase       =    [mem.copy() for i in range(4       )]
		lowercase       =    VGroup(*snake_case       ).arrange(snake_case		,    buff=0       )
		lowercase       =    Text('GPU'		,    font_size=24       )
		lowercase       =    Group(snake_case		,    snake_case       ).arrange(snake_case		,    buff=0.5		,    aligned_edge=snake_case       )
		gpu.move_to([-1, -1, 0]       )
		self.add(snake_case       )

		lowercase       =    [mem.copy() for i in range(6       )]
		lowercase       =    VGroup(*snake_case       ).arrange(snake_case		,    buff=0       )

		lowercase       =    Text('Model'		,    font_size=24       )
		lowercase       =    Group(snake_case		,    snake_case       ).arrange(snake_case		,    buff=0.5		,    aligned_edge=snake_case       )
		model.move_to([3, -1.0, 0]       )
		self.add(snake_case       )

		lowercase       =    []
		lowercase       =    []
		lowercase       =    []

		for i, rect in enumerate(snake_case       ):
			rect.set_stroke(snake_case       )

			lowercase       =    Rectangle(height=0.46 / 4		,    width=0.46 / 3       ).set_stroke(width=0.0       ).set_fill(snake_case		,    opacity=0.7       )

			if i == 0:
				cpu_target.next_to(cpu_left_col_base[0].get_corner(DOWN + LEFT       )		,    buff=0.02		,    direction=snake_case       )
				cpu_target.set_x(cpu_target.get_x() + 0.1       )
			elif i == 3:
				cpu_target.next_to(model_cpu_arr[0]		,    direction=snake_case		,    buff=0.0       )
			else:
				cpu_target.next_to(model_cpu_arr[i - 1]		,    direction=snake_case		,    buff=0.0       )
			self.add(snake_case       )
			model_cpu_arr.append(snake_case       )

		self.add(*snake_case		,    *snake_case		,    *snake_case       )

		lowercase       =    [mem.copy() for i in range(6       )]
		lowercase       =    VGroup(*snake_case       ).arrange(snake_case		,    buff=0       )

		lowercase       =    Text('Loaded Checkpoint'		,    font_size=24       )
		lowercase       =    Group(snake_case		,    snake_case       ).arrange(snake_case		,    buff=0.5		,    aligned_edge=snake_case       )
		checkpoint.move_to([3, 0.5, 0]       )

		self.add(snake_case       )

		lowercase       =    []
		lowercase       =    []

		for i, rect in enumerate(snake_case       ):
			lowercase       =    fill.copy().set_fill(snake_case		,    opacity=0.7       )
			target.move_to(snake_case       )
			ckpt_arr.append(snake_case       )

			lowercase       =    target.copy()
			if i < 5:
				cpu_target.move_to(cpu_left_col_base[i + 1]       )
			else:
				cpu_target.move_to(cpu_right_col_base[i - 5]       )
			ckpt_cpu_arr.append(snake_case       )
		self.add(*snake_case		,    *snake_case       )

		lowercase       =    Square(side_length=2.2       )
		key.move_to([-5, 2, 0]       )

		lowercase       =    MarkupText(
		    F'''<b>Key:</b>\n\n<span fgcolor=\'{YELLOW}\'>●</span> Empty Model'''		,    font_size=18		,    )

		key_text.move_to([-5, 2.4, 0]       )

		self.add(snake_case		,    snake_case       )

		lowercase       =    MarkupText(
		    F'''<span fgcolor=\'{BLUE}\'>●</span> Checkpoint'''		,    font_size=18		,    )

		blue_text.next_to(snake_case		,    DOWN * 2.4		,    aligned_edge=key_text.get_left()       )
		self.add(snake_case       )

		lowercase       =    MarkupText(
		    F'''Based on the passed in configuration, weights are stored in\na variety of np.memmaps on disk or to a particular device.'''		,    font_size=24		,    )
		step_a.move_to([2, 2, 0]       )

		lowercase       =    [meta_mem.copy() for i in range(6       )]
		lowercase       =    [meta_mem.copy() for i in range(6       )]
		lowercase       =    VGroup(*snake_case       ).arrange(snake_case		,    buff=0       )
		lowercase       =    VGroup(*snake_case       ).arrange(snake_case		,    buff=0       )
		lowercase       =    VGroup(snake_case		,    snake_case       ).arrange(snake_case		,    buff=0       )
		lowercase       =    Text('Disk'		,    font_size=24       )
		lowercase       =    Group(snake_case		,    snake_case       ).arrange(snake_case		,    buff=0.5		,    aligned_edge=snake_case       )
		disk.move_to([-4.0, -1.25, 0]       )
		self.play(Write(snake_case		,    run_time=3       )		,    Write(snake_case		,    run_time=1       )		,    Create(snake_case		,    run_time=1       )       )

		lowercase       =    []
		for i, rect in enumerate(snake_case       ):
			lowercase       =    rect.copy()
			target.generate_target()
			target.target.move_to(disk_left_col_base[i]       ).scale(0.5       )
			animations.append(MoveToTarget(snake_case		,    run_time=1.5       )       )
		self.play(*snake_case       )

		self.play(FadeOut(snake_case       )       )

		lowercase       =    MarkupText(F'''Then, the checkpoint is removed from memory\nthrough garbage collection.'''		,    font_size=24       )
		step_a.move_to([2, 2, 0]       )

		self.play(Write(snake_case		,    run_time=3       )       )

		self.play(
		    FadeOut(snake_case		,    snake_case		,    *snake_case		,    *snake_case       )		,    )

		self.wait()

