{"record":{"id":"9fa41361875287b9","repo":"TheAlgorithms/Python","slug":"invalid-strand","errorCode":null,"errorMessage":"Invalid Strand","messagePattern":"Invalid Strand","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"strings/dna.py","lineNumber":22,"sourceCode":"def dna(dna: str) -> str:\n    \"\"\"\n    https://en.wikipedia.org/wiki/DNA\n    Returns the second side of a DNA strand\n\n    >>> dna(\"GCTA\")\n    'CGAT'\n    >>> dna(\"ATGC\")\n    'TACG'\n    >>> dna(\"CTGA\")\n    'GACT'\n    >>> dna(\"GFGG\")\n    Traceback (most recent call last):\n        ...\n    ValueError: Invalid Strand\n    \"\"\"\n\n    if len(re.findall(\"[ATCG]\", dna)) != len(dna):\n        raise ValueError(\"Invalid Strand\")\n\n    return dna.translate(dna.maketrans(\"ATCG\", \"TAGC\"))\n\n\nif __name__ == \"__main__\":\n    import doctest\n\n    doctest.testmod()\n","sourceCodeStart":4,"sourceCodeEnd":31,"githubUrl":"https://github.com/TheAlgorithms/Python/blob/f5988cc09713315817df6a7e327e258013a94440/strings/dna.py#L4-L31","documentation":"Raised by the dna complement function in strings/dna.py when the input strand contains any character outside the DNA alphabet A, T, C, G. The function computes the complement by counting regex matches of [ATCG] and comparing to the strand length; any mismatch (lowercase letters, U for RNA, N, whitespace, digits) means the input is not a valid DNA strand and ValueError('Invalid Strand') is raised before the translate step.","triggerScenarios":"dna('GFGG'); dna('atgc') (lowercase fails the regex); dna('AUCG') (RNA U fails); dna('ATGC ') (trailing space); dna('ATG1').","commonSituations":"Reading FASTA/sequence files without stripping newlines and headers; case-inconsistent data from databases; accidentally passing RNA strands or sequences with ambiguity codes (N, R, Y).","solutions":["Normalize before calling: dna(strand.strip().upper()) handles whitespace and case.","Convert RNA to DNA if that is the intent: strand.replace('U', 'T').","Filter or reject ambiguity codes: if set(strand) - set('ATCG'): raise/report bad record."],"exampleFix":"# before\ndna(line)  # line = 'atgc\\n' -> ValueError: Invalid Strand\n\n# after\ndna(line.strip().upper())","handlingStrategy":"validation","validationCode":"strand = strand.strip().upper()\nif set(strand) - set('ATCG'):\n    raise ValueError(f'invalid DNA characters: {set(strand) - set(\"ATCG\")}')\ncomplement = dna(strand)","typeGuard":"def is_dna_strand(s: str) -> bool:\n    return isinstance(s, str) and not set(s.upper()) - set('ATCG')","tryCatchPattern":"try:\n    comp = dna(strand)\nexcept ValueError:\n    comp = dna(strand.strip().upper().replace('U', 'T'))  # tolerate RNA/case/whitespace","preventionTips":["Normalize sequence data early: strip newlines/whitespace and uppercase.","Reject ambiguity codes (N, R, Y) explicitly so bad records are visible, not silent.","If processing RNA, convert U to T before using this DNA complement function."],"tags":["strings","bioinformatics","dna","validation","alphabet"],"backgroundTag":null,"analyzedSha":"f5988cc09713315817df6a7e327e258013a94440","analyzedAt":"2026-08-14T17:30:07.041Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}