{"record":{"id":"aa277adc1e5365f3","repo":"TheAlgorithms/Python","slug":"invalid-velocity-should-be-a-positive-number","errorCode":null,"errorMessage":"Invalid velocity. Should be a positive number.","messagePattern":"Invalid velocity\\. Should be a positive number\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"physics/horizontal_projectile_motion.py","lineNumber":45,"sourceCode":"def check_args(init_velocity: float, angle: float) -> None:\n    \"\"\"\n    Check that the arguments are valid\n    \"\"\"\n\n    # Ensure valid instance\n    if not isinstance(init_velocity, (int, float)):\n        raise TypeError(\"Invalid velocity. Should be an integer or float.\")\n\n    if not isinstance(angle, (int, float)):\n        raise TypeError(\"Invalid angle. Should be an integer or float.\")\n\n    # Ensure valid angle\n    if angle > 90 or angle < 1:\n        raise ValueError(\"Invalid angle. Range is 1-90 degrees.\")\n\n    # Ensure valid velocity\n    if init_velocity < 0:\n        raise ValueError(\"Invalid velocity. Should be a positive number.\")\n\n\ndef horizontal_distance(init_velocity: float, angle: float) -> float:\n    r\"\"\"\n    Returns the horizontal distance that the object cover\n\n    Formula:\n        .. math::\n            \\frac{v_0^2 \\cdot \\sin(2 \\alpha)}{g}\n\n            v_0 - \\text{initial velocity}\n\n            \\alpha - \\text{angle}\n\n    >>> horizontal_distance(30, 45)\n    91.77\n    >>> horizontal_distance(100, 78)\n    414.76","sourceCodeStart":27,"sourceCodeEnd":63,"githubUrl":"https://github.com/TheAlgorithms/Python/blob/f5988cc09713315817df6a7e327e258013a94440/physics/horizontal_projectile_motion.py#L27-L63","documentation":"Raised by the input validator in physics/horizontal_projectile_motion.py before any projectile calculation when init_velocity is negative. The library treats init_velocity as a speed magnitude combined with a launch angle (1-90 degrees), so a negative magnitude is meaningless. Note the guard is `init_velocity < 0`, so 0 is silently accepted (yielding zero distance) even though the message says 'positive'.","triggerScenarios":"Calling horizontal_distance(-30, 45) or any function in the module that runs this validator with a negative init_velocity. Non-numeric inputs raise TypeError first; the angle check (1-90) runs independently of this one.","commonSituations":"Passing a signed velocity component (e.g. modeling leftward motion as -v) instead of magnitude+angle; piping raw sensor or CSV data that encodes direction in the sign; off-by-one defaults like -1 used as an 'unset' sentinel.","solutions":["Pass the speed magnitude (>= 0) and express direction through the angle parameter, e.g. horizontal_distance(30, 45) instead of horizontal_distance(-30, 45).","Pre-validate inputs with abs(init_velocity) or an explicit `if init_velocity < 0` check before calling.","Wrap the call in try/except ValueError to convert the message into a user-facing error."],"exampleFix":"# before\nhorizontal_distance(-30, 45)  # ValueError\n\n# after\nhorizontal_distance(abs(-30), 45)  # or horizontal_distance(30, 45)","handlingStrategy":"validation","validationCode":"def valid_projectile_inputs(v: float, angle: float) -> bool:\n    return isinstance(v, (int, float)) and v >= 0 and 1 <= angle <= 90\n\nif valid_projectile_inputs(init_velocity, angle):\n    horizontal_distance(init_velocity, angle)","typeGuard":null,"tryCatchPattern":"try:\n    horizontal_distance(v, angle)\nexcept ValueError as e:\n    raise ValueError(f\"Projectile input rejected: {e} (v={v}, angle={angle})\") from e","preventionTips":["Keep speed and direction separate: magnitude to init_velocity, direction to angle.","Sanitize external data: abs() the velocity before passing it in.","Remember 0 velocity passes the guard but returns 0 distance."],"tags":["physics","projectile-motion","input-validation","valueerror"],"backgroundTag":null,"analyzedSha":"f5988cc09713315817df6a7e327e258013a94440","analyzedAt":"2026-08-14T17:30:07.041Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}