Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Generate reverse complements and complements of DNA/RNA sequences using Biopython. Use when working with opposite strands, primer design, or converting between template and coding strands.
.claude/skills/bio-reverse-complement/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-10 | ✗→✓ | ▲ Improved | 35% | 0% |
| case-02 | ✗→✓ | ▲ Improved | 97% | 0% |
| case-03 | ✗→✓ | ▲ Improved | 117% | 0% |
| case-04 | ✗→✓ | ▲ Improved | 190% | 0% |
| case-05 | ✓→✓ | = Same ✓ | 60% | 0% |
<!--
#
#
-->
Generate complementary and reverse complementary sequences using Biopython.
pythonfrom Bio.Seq import Seq
Returns the reverse complement (5' to 3' of the opposite strand).
pythonseq = Seq('ATGCGATCG') rc = seq.reverse_complement() # Returns Seq('CGATCGCAT')
This is the most commonly used operation - it gives you the sequence of the opposite strand in the conventional 5' to 3' direction.
Returns the complement without reversing.
pythonseq = Seq('ATGCGATCG') comp = seq.complement() # Returns Seq('TACGCTAGC')
Less commonly used - gives the opposite strand but in 3' to 5' direction.
For RNA sequences (uses U instead of T):
pythonrna = Seq('AUGCGAUCG') rc_rna = rna.reverse_complement_rna() # Returns Seq('CGAUCGCAU')
pythonrna = Seq('AUGCGAUCG') comp_rna = rna.complement_rna() # Returns Seq('UACGCUAGC')
| Base | Complement | |------|------------| | A | T | | T | A | | G | C | | C | G |
| Base | Complement | |------|------------| | A | U | | U | A | | G | C | | C | G |
| Code | Bases | Complement | |------|-------|------------| | R | A/G | Y | | Y | C/T | R | | S | G/C | S | | W | A/T | W | | K | G/T | M | | M | A/C | K | | B | C/G/T | V | | D | A/G/T | H | | H | A/C/T | D | | V | A/C/G | B | | N | A/C/G/T | N |
Biopython handles IUPAC ambiguity codes correctly.
pythonseq = Seq('ATGCGATCGATCG') rc = seq.reverse_complement() print(f'Original: 5\'-{seq}-3\'') print(f'RevComp: 5\'-{rc}-3\'')
pythondef show_dsdna(seq): comp = seq.complement() print(f"5'-{seq}-3'") print(f" {'|' * len(seq)}") print(f"3'-{comp}-5'") seq = Seq('ATGCGATCG') show_dsdna(seq)
pythondef is_palindrome(seq): return seq == seq.reverse_complement() seq1 = Seq('GAATTC') # EcoRI site - palindrome seq2 = Seq('ATGCGA') # Not a palindrome print(f'GAATTC is palindrome: {is_palindrome(seq1)}') print(f'ATGCGA is palindrome: {is_palindrome(seq2)}')
pythonfrom Bio import SeqIO from Bio.SeqRecord import SeqRecord def reverse_complement_records(records): for record in records: rc_record = SeqRecord( record.seq.reverse_complement(), id=record.id + '_rc', description=record.description + ' reverse complement' ) yield rc_record records = SeqIO.parse('sequences.fasta', 'fasta') rc_records = reverse_complement_records(records) SeqIO.write(rc_records, 'sequences_rc.fasta', 'fasta')
pythondef design_primer_pair(template, start, end): '''Design forward and reverse primers for a region''' forward = template[start:start + 20] reverse = template[end - 20:end].reverse_complement() return forward, reverse template = Seq('ATGCGATCGATCGATCGATCGATCGATCGATCGATCGATCG') fwd, rev = design_primer_pair(template, 0, 40) print(f'Forward primer (5\'-3\'): {fwd}') print(f'Reverse primer (5\'-3\'): {rev}')
pythondef search_both_strands(seq, motif): '''Search for a motif on both strands''' motif = Seq(motif) results = [] pos = seq.find(motif) while pos != -1: results.append(('+', pos)) pos = seq.find(motif, pos + 1) rc = seq.reverse_complement() pos = rc.find(motif) while pos != -1: results.append(('-', len(seq) - pos - len(motif))) pos = rc.find(motif, pos + 1) return results seq = Seq('ATGCGAATTCGATCGATGAATTCGATC') hits = search_both_strands(seq, 'GAATTC') for strand, pos in hits: print(f'Found on {strand} strand at position {pos}')
| Task | Method | |------|--------| | Get opposite strand | reverse_complement() | | Primer for opposite strand | reverse_complement() of target region | | Template strand from coding | reverse_complement() | | Check palindrome | seq == seq.reverse_complement() | | Search both strands | Search original and reverse_complement |
| Error | Cause | Solution | |-------|-------|----------| | Wrong bases in result | Mixing DNA/RNA methods | Use reverse_complement_rna() for RNA | | TypeError | Passing string instead of Seq | Wrap in Seq() first |
Need to work with strand orientation?
├── Get opposite strand sequence (5' to 3')?
│ └── Use reverse_complement()
├── Get base-paired sequence (same direction)?
│ └── Use complement()
├── Working with RNA?
│ └── Use reverse_complement_rna()
├── Check if restriction site (palindrome)?
│ └── seq == seq.reverse_complement()
└── Designing primers?
└── Reverse primer = reverse_complement() of 3' end<!-- AUTHOR_SIGNATURE: 9a7f3c2e-MD-BABU-MIA-2026-MSSM-SECURE -->
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-05 | pass→pass | 6,928 | 2,874 | -59% | 1 | 1 | 0% | 1,451 | 2,315 | +60% | 0 | 0 | — |
case-10 | fail→pass | 11,112 | 5,846 | -47% | 1 | 1 | 0% | 2,237 | 3,023 | +35% | 0 | 0 | — |
case-01 | pass→pass | 5,359 | 4,358 | -19% | 1 | 1 | 0% | 1,169 | 2,611 | +123% | 0 | 0 | — |
case-02 | fail→pass | 6,916 | 4,764 | -31% | 1 | 1 | 0% | 1,334 | 2,625 | +97% | 0 | 0 | — |
case-03 | fail→pass | 7,019 | 5,035 | -28% | 1 | 1 | 0% | 1,315 | 2,851 | +117% | 0 | 0 | — |
case-04 | fail→pass | 4,665 | 5,475 | +17% | 1 | 1 | 0% | 985 | 2,857 | +190% | 0 | 0 | — |
case-06 | pass→pass | 5,640 | 1,806 | -68% | 1 | 1 | 0% | 632 | 2,081 | +229% | 0 | 0 | — |
case-07 | pass→pass | 3,790 | 3,306 | -13% | 1 | 1 | 0% | 760 | 2,190 | +188% | 0 | 0 | — |
case-08 | pass→pass | 7,135 | 4,243 | -41% | 1 | 1 | 0% | 1,397 | 2,625 | +88% | 0 | 0 | — |
case-09 | pass→pass | 11,897 | 7,708 | -35% | 1 | 1 | 0% | 2,615 | 3,540 | +35% | 0 | 0 | — |
case-11 | pass→pass | 19,952 | 11,949 | -40% | 1 | 1 | 0% | 4,246 | 4,426 | +4% | 0 | 0 | — |
case-12 | pass→pass | 5,918 | 9,010 | +52% | 1 | 1 | 0% | 1,157 | 2,364 | +104% | 0 | 0 | — |
case-13 | pass→pass | 8,560 | 4,581 | -46% | 1 | 1 | 0% | 1,758 | 2,642 | +50% | 0 | 0 | — |
case-14 | pass→pass | 4,050 | 2,330 | -42% | 1 | 1 | 0% | 781 | 2,189 | +180% | 0 | 0 | — |
case-15 | pass→pass | 7,132 | 5,625 | -21% | 1 | 1 | 0% | 1,371 | 2,939 | +114% | 0 | 0 | — |
case-16 | pass→pass | 7,707 | 6,224 | -19% | 1 | 1 | 0% | 1,591 | 3,142 | +97% | 0 | 0 | — |
case-17 | pass→pass | 14,964 | 8,253 | -45% | 1 | 1 | 0% | 2,657 | 3,393 | +28% | 0 | 0 | — |
case-18 | pass→pass | 3,745 | 2,870 | -23% | 1 | 1 | 0% | 773 | 2,375 | +207% | 0 | 0 | — |
case-19 | pass→pass | 3,957 | 5,052 | +28% | 1 | 1 | 0% | 791 | 2,809 | +255% | 0 | 0 | — |
case-20 | pass→pass | 6,667 | 2,966 | -56% | 1 | 1 | 0% | 1,203 | 2,346 | +95% | 0 | 0 | — |
case-21 | pass→pass | 10,893 | 6,311 | -42% | 1 | 1 | 0% | 2,278 | 2,992 | +31% | 0 | 0 | — |
case-22 | pass→pass | 12,549 | 8,452 | -33% | 1 | 1 | 0% | 2,461 | 3,395 | +38% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +18 percentage points is the difference between those two pass rates over the 22 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
| Model | Method | Date | Lift |
|---|---|---|---|
| gemini-3.6-flash | verified | 7/24/2026 | +45% |
Other measured skills in the registry, with their headline benchmark lift.