input: from typing import Tuple
  
  class Vector3D:
      """Represents a 3D Vector with x, y, and z components.
      >>> vec = Vector3D(1, 2, 3)
      >>> str(vec)
      '(1, 2, 3)'
      >>> vec2 = Vector3D(4, 5, 6)
      >>> str(vec2)
      '(4, 5, 6)'
      """
      def __init__(self, x: float, y: float, z: float):
          self.x = x
          self.y = y
          self.z = z
      
      def __str__(self) -> str:
          return "(" + str(self.x) + ", " + str(self.y) + ", " + str(self.z) + ")"
output:     def __add__(self, other: 'Vector3D') -> 'Vector3D':
          return Vector3D(self.x + other.x, self.y + other.y, self.z + other.z)
      
      def __sub__(self, other: 'Vector3D') -> 'Vector3D':
          return Vector3D(self.x - other.x, self.y - other.y, self.z - other.z)
      
      def __mul__(self, scalar: float) -> 'Vector3D':
          return Vector3D(self.x * scalar, self.y * scalar, self.z * scalar)
      
      def __rmul__(self, scalar: float) -> 'Vector3D':
          return self.__mul__(scalar)
      
      def dot(self, other: 'Vector3D') -> float:
          return self.x * other.x + self.y * other.y + self.z * other.z
      
      def cross(self, other: 'Vector3D') -> 'Vector3D':
          return Vector3D(self.y * other.z - self.z * other.y,
                          self.z * other.x - self.x * other.z,
                          self.x * other.y - self.y * other.x)
      
      def magnitude(self) -> float:
          return (self.x ** 2 + self.y ** 2 + self.z ** 2) ** 0.5
      
      def normalize(self) -> 'Vector3D':
          mag = self.magnitude()
          if mag == 0:
              raise ValueError("Cannot normalize a zero vector")
          return Vector3D(self.x / mag, self.y / mag, self.z / mag)