






from manim import *


class 					__lowercase					(		snake_case__     ):







     '''simple docstring'''




     def 						lowerCAmelCase_   ( self				:	Union[str, Any] ):


         """simple docstring"""



         __A   			=		Rectangle(height=0.5       ,		width=0.5 )
         __A   			=		Rectangle(height=0.46       ,		width=0.46 ).set_stroke(width=0 )
         __A   			=		Rectangle(height=0.25       ,		width=0.25 )

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

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

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

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

         __A   			=		[]
         __A   			=		[]

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

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

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

         self.add(*__UpperCAmelCase       ,		*__UpperCAmelCase )

         __A   			=		[meta_mem.copy() for i in range(6 )]
         __A   			=		[meta_mem.copy() for i in range(6 )]
         __A   			=		VGroup(*__UpperCAmelCase ).arrange(__UpperCAmelCase       ,		buff=0 )
         __A   			=		VGroup(*__UpperCAmelCase ).arrange(__UpperCAmelCase       ,		buff=0 )
         __A   			=		VGroup(__UpperCAmelCase       ,		__UpperCAmelCase ).arrange(__UpperCAmelCase       ,		buff=0 )
         __A   			=		Text("""Disk"""       ,		font_size=24 )
         __A   			=		Group(__UpperCAmelCase       ,		__UpperCAmelCase ).arrange(__UpperCAmelCase       ,		buff=0.5       ,		aligned_edge=__UpperCAmelCase )
         disk.move_to([-4.0, -1.25, 0] )
         self.add(__UpperCAmelCase       ,		__UpperCAmelCase )

         __A   			=		[]

         for i in range(6 ):
             __A   			=		fill.copy().set_fill(__UpperCAmelCase       ,		opacity=0.8 )
             target.move_to(disk_left_col_base[i] ).scale(0.5 )
             cpu_disk_arr.append(__UpperCAmelCase )

         self.add(*__UpperCAmelCase )

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

         __A   			=		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(__UpperCAmelCase       ,		__UpperCAmelCase )

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

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

         __A   			=		MarkupText(F"The offloaded weights are all sent to the CPU."       ,		font_size=24 )
         step_a.move_to([2, 2, 0] )

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

         for i in range(6 ):
             __A   			=		cpu_disk_arr[i]
             __A   			=		rect.copy().set_fill(__UpperCAmelCase       ,		opacity=0.8 ).scale(2.0 )
             cpa.generate_target()
             cpa.target.move_to(model_base[i] )

             if i == 0:
                 rect.set_fill(__UpperCAmelCase       ,		opacity=0.8 )
                 rect.generate_target()
                 rect.target.move_to(cpu_left_col_base[0] ).scale(2.0 )

                 self.remove(
                     *__UpperCAmelCase       ,		*__UpperCAmelCase       ,		)

             else:
                 rect.generate_target()
                 rect.target.move_to(cpu_left_col_base[i] ).scale(2.0 )
             self.play(MoveToTarget(__UpperCAmelCase )       ,		MoveToTarget(__UpperCAmelCase )       ,		model_base[i].animate.set_stroke(__UpperCAmelCase ) )
         self.play(FadeOut(__UpperCAmelCase ) )

         __A   			=		MarkupText(
             F"Finally, hooks are added to each weight in the model\nto transfer the weights from CPU to GPU\n\t\tand back when needed."       ,		font_size=24       ,		)
         step_a.move_to([2, 2, 0] )

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

         __A   			=		[]
         __A   			=		[]
         for i in range(6 ):
             __A   			=		Arrow(start=__UpperCAmelCase       ,		end=__UpperCAmelCase       ,		color=__UpperCAmelCase       ,		buff=0.5 )
             a.next_to(model_base[i].get_left()       ,		__UpperCAmelCase       ,		buff=0.2 )
             arrows.append(__UpperCAmelCase )
             animations.append(Write(__UpperCAmelCase ) )
         self.play(*__UpperCAmelCase )
         self.wait()









def        __a     (    lowerCAmelCase_   :					int				)      -> int:






						'''simple docstring'''



						if number != int(lowerCAmelCase_				):
												raise ValueError("""factorial() only accepts integral values"""				)
						if number < 0:
												raise ValueError("""factorial() not defined for negative values"""				)
						UpperCAmelCase_=   1
						for i in range(1			,number + 1				):
												value *= i
						return value



def        __a     (    lowerCAmelCase_   :					int				)      -> int:






						'''simple docstring'''



						if not isinstance(lowerCAmelCase_			,lowerCAmelCase_				):
												raise ValueError("""factorial() only accepts integral values"""				)
						if n < 0:
												raise ValueError("""factorial() not defined for negative values"""				)
						return 1 if n == 0 or n == 1 else n * factorial(n - 1				)


if __name__ == "__main__":
	import doctest

	doctest.testmod()

	__A				    =						int(input('''Enter a positive integer: ''').strip() or 0)
	print(f'factorial{n} is {factorial(n)}')




