{"record":{"id":"45c77798c753ce5f","repo":"TheAlgorithms/Python","slug":"all-days-elements-should-be-less-than-366","errorCode":null,"errorMessage":"All days elements should be less than 366","messagePattern":"All days elements should be less than 366","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"dynamic_programming/minimum_tickets_cost.py","lineNumber":105,"sourceCode":"     ...\n    ValueError: The parameter costs should be a list of three integers\n    \"\"\"\n\n    # Validation\n    if not isinstance(days, list) or not all(isinstance(day, int) for day in days):\n        raise ValueError(\"The parameter days should be a list of integers\")\n\n    if len(costs) != 3 or not all(isinstance(cost, int) for cost in costs):\n        raise ValueError(\"The parameter costs should be a list of three integers\")\n\n    if len(days) == 0:\n        return 0\n\n    if min(days) <= 0:\n        raise ValueError(\"All days elements should be greater than 0\")\n\n    if max(days) >= 366:\n        raise ValueError(\"All days elements should be less than 366\")\n\n    days_set = set(days)\n\n    @functools.cache\n    def dynamic_programming(index: int) -> int:\n        if index > 365:\n            return 0\n\n        if index not in days_set:\n            return dynamic_programming(index + 1)\n\n        return min(\n            costs[0] + dynamic_programming(index + 1),\n            costs[1] + dynamic_programming(index + 7),\n            costs[2] + dynamic_programming(index + 30),\n        )\n\n    return dynamic_programming(1)","sourceCodeStart":87,"sourceCodeEnd":123,"githubUrl":"https://github.com/TheAlgorithms/Python/blob/f5988cc09713315817df6a7e327e258013a94440/dynamic_programming/minimum_tickets_cost.py#L87-L123","documentation":"Raised by mincost_tickets() when any travel day is >= 366. The DP function dynamic_programming(index) terminates at index > 365, so the model only covers a single non-leap year (days 1..365). Day 366 or beyond would fall outside the memoized recursion and is rejected.","triggerScenarios":"Calling mincost_tickets([200, 366], [2, 7, 15]) or with day 365+1 from date arithmetic. Any max(days) >= 366 triggers it, including day 400 or 1000.","commonSituations":"Using day-of-year values from a leap year (Dec 31 = day 366); passing raw day-of-year from datetime.timetuple().tm_ydata for a leap year; accidentally passing a day count across two years.","solutions":["Clamp or split data to a single non-leap year: filter days to 1..365 and handle the remainder separately.","If processing a leap year, map day 366 to 365 or treat the year as two calls.","Validate before calling: if max(days) >= 366: raise/split the input."],"exampleFix":"# before\nmincost_tickets([1, 200, 366], [2, 7, 15])  # ValueError\n\n# after\nmincost_tickets([d for d in [1, 200, 366] if d <= 365], [2, 7, 15])","handlingStrategy":"validation","validationCode":"def valid_days(days: list[int]) -> bool:\n    return len(days) > 0 and max(days) <= 365 and min(days) >= 1","typeGuard":null,"tryCatchPattern":"try:\n    mincost_tickets(days, costs)\nexcept ValueError as e:\n    if 'less than 366' in str(e):\n        days = [d for d in days if d <= 365]  # or split the year\n    else:\n        raise","preventionTips":["Remember the model covers a single non-leap year (1..365).","For leap years, clamp or split day 366 into a second call.","Validate max(days) <= 365 before calling."],"tags":["dynamic-programming","input-validation","calendar"],"backgroundTag":null,"analyzedSha":"f5988cc09713315817df6a7e327e258013a94440","analyzedAt":"2026-08-14T17:30:07.041Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}