{"record":{"id":"f8954241cdf9271e","repo":"TheAlgorithms/Python","slug":"parameters-chain-length-and-number-limit-must-be-i","errorCode":null,"errorMessage":"Parameters chain_length and number_limit must be int","messagePattern":"Parameters chain_length and number_limit must be int","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"project_euler/problem_074/sol2.py","lineNumber":102,"sourceCode":"        ...\n    TypeError: Parameters chain_length and number_limit must be int\n\n    >>> solution(0, 1000)\n    Traceback (most recent call last):\n        ...\n    ValueError: Parameters chain_length and number_limit must be greater than 0\n\n    >>> solution(10, 0)\n    Traceback (most recent call last):\n        ...\n    ValueError: Parameters chain_length and number_limit must be greater than 0\n\n    >>> solution(10, 1000)\n    26\n    \"\"\"\n\n    if not isinstance(chain_length, int) or not isinstance(number_limit, int):\n        raise TypeError(\"Parameters chain_length and number_limit must be int\")\n\n    if chain_length <= 0 or number_limit <= 0:\n        raise ValueError(\n            \"Parameters chain_length and number_limit must be greater than 0\"\n        )\n\n    # the counter for the chains with the exact desired length\n    chains_counter = 0\n    # the cached sizes of the previous chains\n    chain_sets_lengths: dict[int, int] = {}\n\n    for start_chain_element in range(1, number_limit):\n        # The temporary set will contain the elements of the chain\n        chain_set = set()\n        chain_set_length = 0\n\n        # Stop computing the chain when you find a cached size, a repeating item or the\n        # length is greater then the desired one.","sourceCodeStart":84,"sourceCodeEnd":120,"githubUrl":"https://github.com/TheAlgorithms/Python/blob/f5988cc09713315817df6a7e327e258013a94440/project_euler/problem_074/sol2.py#L84-L120","documentation":"Raised by solution() in project_euler/problem_074/sol2.py when either chain_length or number_limit is not an int. The function runs range(1, number_limit) and dict-based chain caching that assume plain integers; floats (even integral ones like 10.0, per the doctest) and strings are rejected with TypeError before any computation.","triggerScenarios":"solution(10.0, 1000), solution(\"60\", 1000000), solution(60, 1e6) (1e6 is float), solution(None, 100).","commonSituations":"Scientific-notation literals (1e6) in scripts; JSON/YAML config parsed floats; passing parameters via argparse without type=int.","solutions":["Use int literals: solution(60, 1000000).","With argparse, add type=int to the argument definition.","Coerce near the call: solution(int(chain_length), int(number_limit)) once validated as integral."],"exampleFix":"# before\nsolution(60, 1e6)  # TypeError: 1e6 is float\n\n# after\nsolution(60, 1_000_000)","handlingStrategy":"type-guard","validationCode":"for p in (chain_length, number_limit):\n    if not isinstance(p, int) or isinstance(p, bool):\n        raise TypeError(f\"parameters must be int, got {p!r}\")\nsolution(chain_length, number_limit)","typeGuard":"def are_int_params(*values) -> bool:\n    return all(isinstance(v, int) and not isinstance(v, bool) for v in values)","tryCatchPattern":"try:\n    count = solution(chain_length, number_limit)\nexcept TypeError:\n    count = solution(int(chain_length), int(number_limit))\nexcept ValueError:\n    raise  # non-positive params; fix config","preventionTips":["Write limits as int literals (1_000_000), never 1e6.","Use argparse type=int / pydantic int fields for these parameters.","Both parameters are checked together; one bad value rejects the call."],"tags":["project-euler","type-check","typeerror","input-validation"],"backgroundTag":null,"analyzedSha":"f5988cc09713315817df6a7e327e258013a94440","analyzedAt":"2026-08-14T17:30:07.041Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}