


'''simple docstring'''







from collections import OrderedDict
from dataclasses import fields
from typing import Any, Tuple

import numpy as np

from .import_utils import is_torch_available





def 						snake_case__ (lowerCAmelCase_	):
    if is_torch_available():
        import torch

        if isinstance(lowerCAmelCase_					,  torch.Tensor	):
            return True

    return isinstance(lowerCAmelCase_					,  np.ndarray	)





class       lowerCamelCase_							(	lowerCAmelCase_  ):






   '''simple docstring'''

   def 	_UpperCamelCase       (  self ):
       UpperCamelCase__      =			fields(self )

       # Safety and consistency checks
       if not len(__UpperCamelCase ):
           raise ValueError(f'{self.__class__.__name__} has no fields.' )

       UpperCamelCase__      =			getattr(self     ,						class_fields[0].name )
       UpperCamelCase__      =			all(getattr(self     ,						field.name ) is None for field in class_fields[1:] )

       if other_fields_are_none and isinstance(__UpperCamelCase     ,						__UpperCamelCase ):
           for key, value in first_field.items():
               UpperCamelCase__      =			value
       else:
           for field in class_fields:
               UpperCamelCase__      =			getattr(self     ,						field.name )
               if v is not None:
                   UpperCamelCase__      =			v


   def __delitem__(  self     ,						*__UpperCamelCase     ,						**__UpperCamelCase ):
       raise Exception(f'You cannot use ``__delitem__`` on a {self.__class__.__name__} instance.' )


   def 	_UpperCamelCase       (  self     ,						*__UpperCamelCase     ,						**__UpperCamelCase ):
       raise Exception(f'You cannot use ``setdefault`` on a {self.__class__.__name__} instance.' )


   def 	_UpperCamelCase       (  self     ,						*__UpperCamelCase     ,						**__UpperCamelCase ):
       raise Exception(f'You cannot use ``pop`` on a {self.__class__.__name__} instance.' )


   def 	_UpperCamelCase       (  self     ,						*__UpperCamelCase     ,						**__UpperCamelCase ):
       raise Exception(f'You cannot use ``update`` on a {self.__class__.__name__} instance.' )


   def __getitem__(  self     ,						__UpperCamelCase ):
       if isinstance(__UpperCamelCase     ,						__UpperCamelCase ):
           UpperCamelCase__      =			dict(self.items() )
           return inner_dict[k]
       else:
           return self.to_tuple()[k]


   def __setattr__(  self     ,						__UpperCamelCase     ,						__UpperCamelCase ):
       if name in self.keys() and value is not None:
           # Don't call self.__setitem__ to avoid recursion errors
           super().__setitem__(__UpperCamelCase     ,						__UpperCamelCase )
       super().__setattr__(__UpperCamelCase     ,						__UpperCamelCase )


   def __setitem__(  self     ,						__UpperCamelCase     ,						__UpperCamelCase ):
       # Will raise a KeyException if needed
       super().__setitem__(__UpperCamelCase     ,						__UpperCamelCase )
       # Don't call self.__setattr__ to avoid recursion errors
       super().__setattr__(__UpperCamelCase     ,						__UpperCamelCase )







   def 	_UpperCamelCase       (  self ):
       return tuple(self[k] for k in self.keys() )









'''simple docstring'''







from math import radians as angle_to_radians
from math import sin

# Acceleration Constant on Earth (unit m/s^2)
lowercase__     :  str    					=			9.8_0_6_6_5





def 						snake_case__ (lowerCAmelCase_					,  lowerCAmelCase_	):

    # Ensure valid instance
    if not isinstance(lowerCAmelCase_					,  (int, float)	):
        raise TypeError("Invalid velocity. Should be a positive number."	)

    if not isinstance(lowerCAmelCase_					,  (int, float)	):
        raise TypeError("Invalid angle. Range is 1-90 degrees."	)

    # Ensure valid angle
    if angle > 90 or angle < 1:
        raise ValueError("Invalid angle. Range is 1-90 degrees."	)

    # Ensure valid velocity
    if init_velocity < 0:
        raise ValueError("Invalid velocity. Should be a positive number."	)





def 						snake_case__ (lowerCAmelCase_					,  lowerCAmelCase_	):
    check_args(lowerCAmelCase_					,  lowerCAmelCase_	)
    UpperCamelCase__      =			angle_to_radians(2 * angle	)
    return round(init_velocity**2 * sin(lowerCAmelCase_	) / g					,  2	)





def 						snake_case__ (lowerCAmelCase_					,  lowerCAmelCase_	):
    check_args(lowerCAmelCase_					,  lowerCAmelCase_	)
    UpperCamelCase__      =			angle_to_radians(lowerCAmelCase_	)
    return round(init_velocity**2 * sin(lowerCAmelCase_	) ** 2 / (2 * g)					,  2	)





def 						snake_case__ (lowerCAmelCase_					,  lowerCAmelCase_	):
    check_args(lowerCAmelCase_					,  lowerCAmelCase_	)
    UpperCamelCase__      =			angle_to_radians(lowerCAmelCase_	)
    return round(2 * init_velocity * sin(lowerCAmelCase_	) / g					,  2	)





def 						snake_case__ ():
    UpperCamelCase__    ,  UpperCamelCase__      =			25, 20
    assert horizontal_distance(lowerCAmelCase_					,  lowerCAmelCase_	) == 40.97
    assert max_height(lowerCAmelCase_					,  lowerCAmelCase_	) == 3.73
    assert total_time(lowerCAmelCase_					,  lowerCAmelCase_	) == 1.74


if __name__ == "__main__":
      from doctest import testmod

      testmod()

      # Get input from user
      lowercase__     :  Union[str, Any]    					=			float(input('Initial Velocity: ').strip())

      # Get input from user
      lowercase__     :  Any    					=			float(input('angle: ').strip())

      # Print results
      print()
      print('Results: ')
      print(F'''Horizontal Distance: {horizontal_distance(init_vel, angle)!s} [m]''')
      print(F'''Maximum Height: {max_height(init_vel, angle)!s} [m]''')
      print(F'''Total Time: {total_time(init_vel, angle)!s} [s]''')




