code: 
  
  
  
  from __future__ import annotations
  
  import random
  
  from matplotlib import animation
  from matplotlib import pyplot as plt
  
  # Frame rate of the animation
  lowerCAmelCase__	:  Dict 		=20
  
  # Time between time steps in seconds
  lowerCAmelCase__	:  Optional[Any] 		=INTERVAL / 1000
  
  class      UpperCAmelCase_						:
  
        '''simple docstring'''
  
  
  
  
        def __init__(					self   ,							_A   ,							_A   ,							_A   ,							_A   ,							_A = 1.0   ,							_A = 1.0   ,							_A = "blue"   ,							):
  
  
  
  
  
  
  
               '''simple docstring'''
  
               __SCREAMING_SNAKE_CASE								=      position_x
               __SCREAMING_SNAKE_CASE								=      position_y
               __SCREAMING_SNAKE_CASE								=      velocity_x
               __SCREAMING_SNAKE_CASE								=      velocity_y
               __SCREAMING_SNAKE_CASE								=      mass
               __SCREAMING_SNAKE_CASE								=      size
               __SCREAMING_SNAKE_CASE								=      color
  
  
  
  
  
  
        @property
        def  _A			(					self	):
  
  
  
  
  
  
  
               '''simple docstring'''
  
               return self.position_x, self.position_y
  
  
  
  
  
  
        @property
        def  _A			(					self	):
  
  
  
  
  
  
  
               '''simple docstring'''
  
               return self.velocity_x, self.velocity_y
  
  
  
  
  
  
        def  _A			(					self   ,							_A   ,							_A   ,							_A	):
  
  
  
  
  
  
  
               '''simple docstring'''
  
               self.velocity_x += force_x * delta_time
               self.velocity_y += force_y * delta_time
  
  
  
  
  
  
        def  _A			(					self   ,							_A	):
  
  
  
  
  
  
  
               '''simple docstring'''
  
               self.position_x += self.velocity_x * delta_time
               self.position_y += self.velocity_y * delta_time
  
  
  
  
  
  
  
  class      UpperCAmelCase_						:
  
        '''simple docstring'''
  
  
  
  
        def __init__(					self   ,							_A   ,							_A = 1.0   ,							_A = 1.0   ,							_A = 0.0   ,							):
  
  
  
  
  
  
  
               '''simple docstring'''
  
               __SCREAMING_SNAKE_CASE								=      bodies
               __SCREAMING_SNAKE_CASE								=      gravitation_constant
               __SCREAMING_SNAKE_CASE								=      time_factor
               __SCREAMING_SNAKE_CASE								=      softening_factor
  
  
  
  
  
  
        def __len__(					self	):
  
  
  
  
  
  
  
               '''simple docstring'''
  
               return len(self.bodies	)
  
  
  
  
  
  
        def  _A			(					self   ,							_A	):
  
  
  
  
  
  
  
               '''simple docstring'''
  
               for bodya in self.bodies:
                      __SCREAMING_SNAKE_CASE								=      0.0
                      __SCREAMING_SNAKE_CASE								=      0.0
                      for bodya in self.bodies:
                             if bodya != bodya:
                                    __SCREAMING_SNAKE_CASE								=      bodya.position_x - bodya.position_x
                                    __SCREAMING_SNAKE_CASE								=      bodya.position_y - bodya.position_y
  
                                    # Calculation of the distance using Pythagoras's theorem
                                    # Extra factor due to the softening technique
                                    __SCREAMING_SNAKE_CASE								=      (dif_x**2 + dif_y**2 + self.softening_factor) ** (
                                        1 / 2
                                    )
  
                                    # Newton's law of universal gravitation.
                                    force_x += (
                                        self.gravitation_constant * bodya.mass * dif_x / distance**3
                                    )
                                    force_y += (
                                        self.gravitation_constant * bodya.mass * dif_y / distance**3
                                    )
  
              # Update the body's velocity once all the force components have been added
                      bodya.update_velocity(_A   ,							_A   ,							delta_time * self.time_factor	)
  
               # Update the positions only after all the velocities have been updated
               for body in self.bodies:
                      body.update_position(delta_time * self.time_factor	)
  
  
  
  
  
  
  
  def 			__lowercase     (				a__							,     a__							,     a__     )       ->				List[Any]:
         body_system.update_system(lowercase__     )
  
         # Update the positions of the patches
         for patch, body in zip(lowercase__							,     body_system.bodies     ):
                __SCREAMING_SNAKE_CASE								=      (body.position_x, body.position_y)
  
  
  
  
  
  
  def 			__lowercase     (				a__							,     a__							,     a__ = -1							,     a__ = 1							,     a__ = -1							,     a__ = 1							,     )       ->				List[Any]:
         __SCREAMING_SNAKE_CASE								=      plt.figure()
         fig.canvas.set_window_title(lowercase__     )
         __SCREAMING_SNAKE_CASE								=      plt.axes(
             xlim=(x_start, x_end)							,     ylim=(y_start, y_end)     )  # Set section to be plotted
         plt.gca().set_aspect('equal'     )  # Fix aspect ratio
  
         # Each body is drawn as a patch by the plt-function
         __SCREAMING_SNAKE_CASE								=      [
             plt.Circle((body.position_x, body.position_y)							,     body.size							,     fc=body.color     )
             for body in body_system.bodies
         ]
  
         for patch in patches:
                ax.add_patch(lowercase__     )
  
         # Function called at each step of the animation
         def update(a__     ) -> list[plt.Circle]:
                update_step(lowercase__							,     lowercase__							,     lowercase__     )
                return patches
  
         __SCREAMING_SNAKE_CASE								=      animation.FuncAnimation(  # noqa: F841
             lowercase__							,     lowercase__							,     interval=lowercase__							,     blit=lowercase__     )
  
         plt.show()
  
  
  
  
  
  
  def 			__lowercase     (				)       ->				Any:
         __SCREAMING_SNAKE_CASE								=      0.9700436
         __SCREAMING_SNAKE_CASE								=      -0.24308753
         __SCREAMING_SNAKE_CASE								=      0.466203685
         __SCREAMING_SNAKE_CASE								=      0.43236573
  
         __SCREAMING_SNAKE_CASE								=      [
             Body(lowercase__							,     lowercase__							,     lowercase__							,     lowercase__							,     size=0.2							,     color='red'     ),
             Body(-position_x							,     -position_y							,     lowercase__							,     lowercase__							,     size=0.2							,     color='green'     ),
             Body(0							,     0							,     -2 * velocity_x							,     -2 * velocity_y							,     size=0.2							,     color='blue'     ),
         ]
         return BodySystem(lowercase__							,     time_factor=3     )
  
  
  
  
  
  
  def 			__lowercase     (				)       ->				int:
         __SCREAMING_SNAKE_CASE								=      7.3476E22
         __SCREAMING_SNAKE_CASE								=      5.972E24
         __SCREAMING_SNAKE_CASE								=      10_22
         __SCREAMING_SNAKE_CASE								=      3_84_39_90_00
         __SCREAMING_SNAKE_CASE								=      6.674E-11
  
         # Calculation of the respective velocities so that total impulse is zero,
         # i.e. the two bodies together don't move
         __SCREAMING_SNAKE_CASE								=      earth_mass * velocity_dif / (earth_mass + moon_mass)
         __SCREAMING_SNAKE_CASE								=      moon_velocity - velocity_dif
  
         __SCREAMING_SNAKE_CASE								=      Body(-earth_moon_distance							,     0							,     0							,     lowercase__							,     lowercase__							,     10_00_00_00							,     'grey'     )
         __SCREAMING_SNAKE_CASE								=      Body(0							,     0							,     0							,     lowercase__							,     lowercase__							,     50_00_00_00							,     'blue'     )
         return BodySystem([earth, moon]							,     lowercase__							,     time_factor=1_00_00_00     )
  
  
  
  
  
  
  def 			__lowercase     (				)       ->				Tuple:
         __SCREAMING_SNAKE_CASE								=      []
         for _ in range(10     ):
                __SCREAMING_SNAKE_CASE								=      random.uniform(-0.5							,     0.5     )
                __SCREAMING_SNAKE_CASE								=      random.uniform(-0.5							,     0.5     )
  
                # Bodies are created pairwise with opposite velocities so that the
                # total impulse remains zero
                bodies.append(
                    Body(
                        random.uniform(-0.5							,     0.5     )							,     random.uniform(-0.5							,     0.5     )							,     lowercase__							,     lowercase__							,     size=0.05							,     )     )
                bodies.append(
                    Body(
                        random.uniform(-0.5							,     0.5     )							,     random.uniform(-0.5							,     0.5     )							,     -velocity_x							,     -velocity_y							,     size=0.05							,     )     )
         return BodySystem(lowercase__							,     0.01							,     10							,     0.1     )
  
  
  if __name__ == "__main__":
     plot('''Figure-8 solution to the 3-body-problem''', example_a(), -2, 2, -2, 2)
     plot(
         '''Moon\'s orbit around the earth''',
         example_a(),
         -430000000,
         430000000,
         -430000000,
         430000000,
     )
     plot('''Random system with many bodies''', example_a(), -1.5, 1.5, -1.5, 1.5)
  
  
  
  
  
  
  
style_context: 
  
  
  
  from __future__ import annotations
  
  from collections.abc import Iterable
  from dataclasses import dataclass
  from typing import Any
  
  class      UpperCAmelCase_						:
  
  						'''simple docstring'''
  
  
  
  
  						UpperCamelCase__    :				List[str]       						=						('''_front''', '''_back''', '''_len''')
  
  						@dataclass
  						class      UpperCAmelCase_						:
  
  												'''simple docstring'''
  
  
  
  
  												UpperCamelCase__    :				Any       						=						None
  												UpperCamelCase__    :				Deque._Node | None       						=						None
  												UpperCamelCase__    :				Deque._Node | None       						=						None
  
  
  
  
  
  
  
  						class      UpperCAmelCase_						:
  
  												'''simple docstring'''
  
  
  
  
  												UpperCamelCase__    :				Optional[int]       						=						('''_cur''',)
  
  
  
  
  
  
  												def __init__(					self   ,							_A	):
  
  
  
  
  
  
  
  																			'''simple docstring'''
  
  																			__SCREAMING_SNAKE_CASE								=      cur
  
  
  
  
  
  
  												def __iter__(					self	):
  
  
  
  
  
  
  
  																			'''simple docstring'''
  
  																			return self
  
  
  
  
  
  
  												def  _A			(					self	):
  
  
  
  
  
  
  
  																			'''simple docstring'''
  
  																			if self._cur is None:
  																										# finished iterating
  																										raise StopIteration
  																			__SCREAMING_SNAKE_CASE								=      self._cur.val
  																			__SCREAMING_SNAKE_CASE								=      self._cur.next_node
  
  																			return val
  
  
  
  
  
  
  
  						def __init__(					self   ,							_A = None	):
  
  
  
  
  
  
  
  													'''simple docstring'''
  
  													__SCREAMING_SNAKE_CASE								=      None
  													__SCREAMING_SNAKE_CASE								=      None
  													__SCREAMING_SNAKE_CASE								=      0
  
  													if iterable is not None:
  																				# append every value to the deque
  																				for val in iterable:
  																											self.append(_A	)
  
  
  
  
  
  
  						def  _A			(					self   ,							_A	):
  
  
  
  
  
  
  
  													'''simple docstring'''
  
  													__SCREAMING_SNAKE_CASE								=      self._Node(_A   ,							_A   ,							_A	)
  													if self.is_empty():
  																				# front = back
  																				__SCREAMING_SNAKE_CASE								=      __SCREAMING_SNAKE_CASE								=      node
  																				__SCREAMING_SNAKE_CASE								=      1
  													else:
  																				# connect nodes
  																				__SCREAMING_SNAKE_CASE								=      node
  																				__SCREAMING_SNAKE_CASE								=      self._back
  																				__SCREAMING_SNAKE_CASE								=      node  # assign new back to the new node
  
  																				self._len += 1
  
  																				# make sure there were no errors
  																				assert not self.is_empty(), "Error on appending value."
  
  
  
  
  
  
  						def  _A			(					self   ,							_A	):
  
  
  
  
  
  
  
  													'''simple docstring'''
  
  													__SCREAMING_SNAKE_CASE								=      self._Node(_A   ,							_A   ,							_A	)
  													if self.is_empty():
  																				# front = back
  																				__SCREAMING_SNAKE_CASE								=      __SCREAMING_SNAKE_CASE								=      node
  																				__SCREAMING_SNAKE_CASE								=      1
  													else:
  																				# connect nodes
  																				__SCREAMING_SNAKE_CASE								=      self._front
  																				__SCREAMING_SNAKE_CASE								=      node
  																				__SCREAMING_SNAKE_CASE								=      node  # assign new front to the new node
  
  																				self._len += 1
  
  																				# make sure there were no errors
  																				assert not self.is_empty(), "Error on appending value."
  
  
  
  
  
  
  						def  _A			(					self   ,							_A	):
  
  
  
  
  
  
  
  													'''simple docstring'''
  
  													for val in iterable:
  																				self.append(_A	)
  
  
  
  
  
  
  						def  _A			(					self   ,							_A	):
  
  
  
  
  
  
  
  													'''simple docstring'''
  
  													for val in iterable:
  																				self.appendleft(_A	)
  
  
  
  
  
  
  						def  _A			(					self	):
  
  
  
  
  
  
  
  													'''simple docstring'''
  
  													assert not self.is_empty(), "Deque is empty."
  
  													__SCREAMING_SNAKE_CASE								=      self._back
  													__SCREAMING_SNAKE_CASE								=      self._back.prev_node  # set new back
  													# drop the last node - python will deallocate memory automatically
  													__SCREAMING_SNAKE_CASE								=      None
  
  													self._len -= 1
  
  													return topop.val
  
  
  
  
  
  
  						def  _A			(					self	):
  
  
  
  
  
  
  
  													'''simple docstring'''
  
  													assert not self.is_empty(), "Deque is empty."
  
  													__SCREAMING_SNAKE_CASE								=      self._front
  													__SCREAMING_SNAKE_CASE								=      self._front.next_node  # set new front and drop the first node
  													__SCREAMING_SNAKE_CASE								=      None
  
  													self._len -= 1
  
  													return topop.val
  
  
  
  
  
  
  						def  _A			(					self	):
  
  
  
  
  
  
  
  													'''simple docstring'''
  
  													return self._front is None
  
  
  
  
  
  
  						def __len__(					self	):
  
  
  
  
  
  
  
  													'''simple docstring'''
  
  													return self._len
  
  
  
  
  
  
  						def __eq__(					self   ,							_A	):
  
  
  
  
  
  
  
  													'''simple docstring'''
  
  													if not isinstance(_A   ,							_A	):
  																				return NotImplemented
  
  													__SCREAMING_SNAKE_CASE								=      self._front
  													__SCREAMING_SNAKE_CASE								=      other._front
  
  													# if the length of the dequeues are not the same, they are not equal
  													if len(self	) != len(_A	):
  																				return False
  
  													while me is not None and oth is not None:
  																				# compare every value
  																				if me.val != oth.val:
  																											return False
  																				__SCREAMING_SNAKE_CASE								=      me.next_node
  																				__SCREAMING_SNAKE_CASE								=      oth.next_node
  
  													return True
  
  
  
  
  
  
  						def __iter__(					self	):
  
  
  
  
  
  
  
  													'''simple docstring'''
  
  													return Deque._Iterator(self._front	)
  
  
  
  
  
  
  						def __repr__(					self	):
  
  
  
  
  
  
  
  													'''simple docstring'''
  
  													__SCREAMING_SNAKE_CASE								=      []
  													__SCREAMING_SNAKE_CASE								=      self._front
  													while aux is not None:
  																				# append the values in a list to display
  																				values_list.append(aux.val	)
  																				__SCREAMING_SNAKE_CASE								=      aux.next_node
  
  													return f"""[{", ".join(repr(_A	) for val in values_list	)}]"""
  
  
  if __name__ == "__main__":
  			import doctest
  
  			doctest.testmod()
  
  
  
  
  
  
  