{"record":{"id":"8aa0300117874e71","repo":"TheAlgorithms/Python","slug":"undefined-for-non-integers","errorCode":null,"errorMessage":"Undefined for non-integers","messagePattern":"Undefined for non-integers","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"maths/chudnovsky_algorithm.py","lineNumber":40,"sourceCode":"\n    This algorithm correctly calculates around 14 digits of PI per iteration\n\n    >>> pi(10)\n    '3.14159265'\n    >>> pi(100)\n    '3.14159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706'\n    >>> pi('hello')\n    Traceback (most recent call last):\n        ...\n    TypeError: Undefined for non-integers\n    >>> pi(-1)\n    Traceback (most recent call last):\n        ...\n    ValueError: Undefined for non-natural numbers\n    \"\"\"\n\n    if not isinstance(precision, int):\n        raise TypeError(\"Undefined for non-integers\")\n    elif precision < 1:\n        raise ValueError(\"Undefined for non-natural numbers\")\n\n    getcontext().prec = precision\n    num_iterations = ceil(precision / 14)\n    constant_term = 426880 * Decimal(10005).sqrt()\n    exponential_term = 1\n    linear_term = 13591409\n    partial_sum = Decimal(linear_term)\n    for k in range(1, num_iterations):\n        multinomial_term = factorial(6 * k) // (factorial(3 * k) * factorial(k) ** 3)\n        linear_term += 545140134\n        exponential_term *= -262537412640768000\n        partial_sum += Decimal(multinomial_term * linear_term) / exponential_term\n    return str(constant_term / partial_sum)[:-1]\n\n\nif __name__ == \"__main__\":","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/TheAlgorithms/Python/blob/f5988cc09713315817df6a7e327e258013a94440/maths/chudnovsky_algorithm.py#L22-L58","documentation":"Raised by pi() (Chudnovsky algorithm) in maths/chudnovsky_algorithm.py when the precision argument is not an int. The number of significant digits must be a whole number because it is assigned directly to decimal.getcontext().prec and used to compute iteration count ceil(precision / 14); non-integers are rejected up front with TypeError.","triggerScenarios":"Calling pi('hello'), pi(10.5), pi(True is fine but pi(2.0) or any float/str precision triggers it. The guard is not isinstance(precision, int).","commonSituations":"Precision read from argv or config as a string ('100' instead of 100); precision computed as a float (e.g. n * 1.5 or results of numpy scalars); API boundaries where JSON numbers arrive as floats.","solutions":["Convert the argument to int before calling: pi(int(precision)).","If precision comes from the command line, wrap with int(sys.argv[1]) and handle the conversion error separately.","Ensure numpy floats are cast with int() since np.int64 passes isinstance(x, int) checks only via casting on some platforms."],"exampleFix":"# before\npi('100')   # TypeError: Undefined for non-integers\npi(10.5)    # TypeError\n\n# after\npi(int('100'))\npi(int(10.5))  # or round first if you meant a fractional size","handlingStrategy":"type-guard","validationCode":"if not isinstance(precision, int) or isinstance(precision, bool):\n    precision = int(precision)  # after your own validation\nresult = pi(precision)","typeGuard":"def is_int_precision(p) -> bool:\n    return isinstance(p, int) and not isinstance(p, bool)","tryCatchPattern":"try:\n    digits = pi(precision)\nexcept TypeError:\n    digits = pi(int(float(precision)))  # last-resort coercion of numeric strings","preventionTips":["Convert argv/config values with int() at the boundary.","Cast numpy scalars and JSON numbers to int before passing precision arguments."],"tags":["maths","pi","decimal","typeerror","validation"],"backgroundTag":null,"analyzedSha":"f5988cc09713315817df6a7e327e258013a94440","analyzedAt":"2026-08-14T17:30:07.041Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}