{"record":{"id":"c1c28a84833b3a06","repo":"TheAlgorithms/Python","slug":"please-use-3-unique-rotors-not-unique-rotsel","errorCode":null,"errorMessage":"Please use 3 unique rotors (not {unique_rotsel})","messagePattern":"Please use 3 unique rotors \\(not (.+?)\\)","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"ciphers/enigma_machine2.py","lineNumber":94,"sourceCode":") -> tuple[RotorPositionT, RotorSelectionT, dict[str, str]]:\n    \"\"\"\n    Checks if the values can be used for the ``enigma`` function\n\n    >>> _validator((1,1,1), (rotor1, rotor2, rotor3), 'POLAND')\n    ((1, 1, 1), ('EGZWVONAHDCLFQMSIPJBYUKXTR', 'FOBHMDKEXQNRAULPGSJVTYICZW', \\\n'ZJXESIUQLHAVRMDOYGTNFWPBKC'), \\\n{'P': 'O', 'O': 'P', 'L': 'A', 'A': 'L', 'N': 'D', 'D': 'N'})\n\n    :param rotpos: rotor_positon\n    :param rotsel: rotor_selection\n    :param pb: plugb -> validated and transformed\n    :return: (`rotpos`, `rotsel`, `pb`)\n    \"\"\"\n    # Checks if there are 3 unique rotors\n\n    if (unique_rotsel := len(set(rotsel))) < 3:\n        msg = f\"Please use 3 unique rotors (not {unique_rotsel})\"\n        raise Exception(msg)\n\n    # Checks if rotor positions are valid\n    rotorpos1, rotorpos2, rotorpos3 = rotpos\n    if not 0 < rotorpos1 <= len(abc):\n        msg = f\"First rotor position is not within range of 1..26 ({rotorpos1}\"\n        raise ValueError(msg)\n    if not 0 < rotorpos2 <= len(abc):\n        msg = f\"Second rotor position is not within range of 1..26 ({rotorpos2})\"\n        raise ValueError(msg)\n    if not 0 < rotorpos3 <= len(abc):\n        msg = f\"Third rotor position is not within range of 1..26 ({rotorpos3})\"\n        raise ValueError(msg)\n\n    # Validates string and returns dict\n    pbdict = _plugboard(pb)\n\n    return rotpos, rotsel, pbdict\n","sourceCodeStart":76,"sourceCodeEnd":112,"githubUrl":"https://github.com/TheAlgorithms/Python/blob/f5988cc09713315817df6a7e327e258013a94440/ciphers/enigma_machine2.py#L76-L112","documentation":"Raised by the Enigma machine's input validator (ciphers/enigma_machine2.py) when fewer than 3 unique rotors are selected: len(set(rotsel)) < 3. The historical machine needs three distinct physical rotors, so duplicates (e.g. [1, 2, 2] or [5, 5, 5]) are rejected. Note it raises bare Exception, not a more specific type.","triggerScenarios":"Calling enigma with rotsel like (1, 2, 2), (3, 3, 3), or any tuple with duplicate rotor ids; passing strings vs ints inconsistently so set() collapses them ('1', 1) is not the issue here but duplicates are.","commonSituations":"Random rotor selection code that samples with replacement; UI defaults that repeat rotor I; refactoring from a 2-rotor toy example to the 3-rotor API.","solutions":["Pass three distinct rotor selectors, e.g. rotsel=(1, 2, 3)","If generating randomly, use random.sample(range(1, 6), 3) (without replacement)","Check len(set(rotsel)) == 3 before calling the API"],"exampleFix":"# before\nrotsel = (1, 2, 2)\nenigma(rotpos, rotsel, pb)\n\n# after\nimport random\nrotsel = tuple(random.sample(range(1, 6), 3))  # 3 distinct rotors\nenigma(rotpos, rotsel, pb)","handlingStrategy":"validation","validationCode":"if len(set(rotsel)) < 3:\n    raise ValueError(\"select 3 distinct rotors\")","typeGuard":"def valid_rotor_selection(rotsel) -> bool:\n    return len(set(rotsel)) == 3","tryCatchPattern":"try:\n    settings = validate_and_transform(rotpos, rotsel, pb)\nexcept Exception as exc:  # module raises bare Exception here\n    if \"unique rotors\" in str(exc):\n        rotsel = (1, 2, 3)  # fall back to distinct defaults\n    else:\n        raise","preventionTips":["Always pass three distinct rotor ids","Use random.sample(range(1, 6), 3) for random selection","Check len(set(rotsel)) == 3 in your settings loader"],"tags":["enigma","rotor","validation","input-validation"],"backgroundTag":null,"analyzedSha":"f5988cc09713315817df6a7e327e258013a94440","analyzedAt":"2026-08-14T17:30:07.041Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}