{"record":{"id":"372f5062015db478","repo":"TheAlgorithms/Python","slug":"factorial-not-defined-for-negative-values","errorCode":null,"errorMessage":"factorial() not defined for negative values","messagePattern":"factorial\\(\\) not defined for negative values","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"data_structures/binary_tree/number_of_possible_binary_trees.py","lineNumber":74,"sourceCode":"    return binomial_coefficient(2 * node_count, node_count) // (node_count + 1)\n\n\ndef factorial(n: int) -> int:\n    \"\"\"\n    Return the factorial of a number.\n    :param n: Number to find the Factorial of.\n    :return: Factorial of n.\n\n    >>> import math\n    >>> all(factorial(i) == math.factorial(i) for i in range(10))\n    True\n    >>> factorial(-5)  # doctest: +ELLIPSIS\n    Traceback (most recent call last):\n        ...\n    ValueError: factorial() not defined for negative values\n    \"\"\"\n    if n < 0:\n        raise ValueError(\"factorial() not defined for negative values\")\n    result = 1\n    for i in range(1, n + 1):\n        result *= i\n    return result\n\n\ndef binary_tree_count(node_count: int) -> int:\n    \"\"\"\n    Return the number of possible of binary trees.\n    :param n: number of nodes\n    :return: Number of possible binary trees\n\n    >>> binary_tree_count(5)\n    5040\n    >>> binary_tree_count(6)\n    95040\n    \"\"\"\n    return catalan_number(node_count) * factorial(node_count)","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/TheAlgorithms/Python/blob/f5988cc09713315817df6a7e327e258013a94440/data_structures/binary_tree/number_of_possible_binary_trees.py#L56-L92","documentation":"Raised by factorial(n) in number_of_possible_binary_trees when n < 0. Factorial is undefined for negative integers, and this iterative implementation (result = 1; for i in range(1, n+1)) would silently return 1 for negative n without the guard, so the check is essential, not cosmetic. The message intentionally matches CPython's math.factorial error text.","triggerScenarios":"factorial(-5); binary_tree_count(node_count) with negative node_count (it calls catalan_number * factorial); computing n! from user input parsed as a negative number.","commonSituations":"Subtraction-based index math producing -1 (e.g. factorial(k - 1) with k == 0); unvalidated CLI input; reusing the helper for general combinatorics where args can go negative.","solutions":["Clamp or reject negatives at the boundary: `if n < 0: raise/input again` before calling","Fix the caller's arithmetic (k - 1 with k == 0 usually means the loop bound or edge case is wrong)","Use math.factorial for general use — same error, but you avoid shipping a hand-rolled loop"],"exampleFix":"# before\nn = int(input())  # user types -3\nfactorial(n)  # ValueError\n\n# after\nn = max(0, int(input()))\nfactorial(n)","handlingStrategy":"validation","validationCode":"if n < 0:\n    raise ValueError(f'n must be >= 0, got {n}')\nfactorial(n)","typeGuard":"def is_non_negative_int(n: object) -> bool:\n    return isinstance(n, int) and not isinstance(n, bool) and n >= 0","tryCatchPattern":"try:\n    f = factorial(n)\nexcept ValueError:\n    f = 1  # or clamp: f = factorial(max(0, n))","preventionTips":["Prefer math.factorial in production code; validate n >= 0 at input boundaries","Audit k - 1 style index math for k == 0 edge cases","Reject negative user input where it enters the program, not deep in math helpers"],"tags":["math","factorial","negative-argument","validation"],"backgroundTag":null,"analyzedSha":"f5988cc09713315817df6a7e327e258013a94440","analyzedAt":"2026-08-14T17:30:07.041Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}