Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Slice, extract, and concatenate biological sequences using Biopython. Use when extracting subsequences, joining sequences, or manipulating sequence regions by position.
.claude/skills/bio-sequence-slicing/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-12 | ✗→✓ | ▲ Improved | 70% | 0% |
| case-02 | ✓→✓ | = Same ✓ | 430% | 0% |
| case-03 | ✓→✓ | = Same ✓ | 214% | 0% |
| case-01 | ✓→✓ | = Same ✓ | 418% | 0% |
| case-15 | ✓→✓ | = Same ✓ | 303% | 0% |
<!--
#
#
-->
Extract, slice, and concatenate sequences using Biopython's Seq objects.
pythonfrom Bio.Seq import Seq
pythonseq = Seq('ATGCGATCG') seq[0] # 'A' - first base (0-indexed) seq[-1] # 'G' - last base seq[3] # 'C' - fourth base
pythonseq = Seq('ATGCGATCGATCG') seq[0:3] # Seq('ATG') - first 3 bases seq[3:6] # Seq('CGA') - positions 3-5 seq[:5] # Seq('ATGCG') - first 5 seq[-5:] # Seq('GATCG') - last 5 seq[::2] # Seq('AGGTGTG') - every 2nd base seq[::-1] # Seq('GCTAGCTAGCGTA') - reversed
Note: Slicing returns a Seq object, not a string.
pythonseq1 = Seq('ATGC') seq2 = Seq('GGGG') combined = seq1 + seq2 # Seq('ATGCGGGG')
Can also concatenate with strings:
pythonseq = Seq('ATGC') extended = seq + 'NNNN' # Seq('ATGCNNNN')
pythongenome = Seq('NNNNATGCGATCGATCGTAANNN') cds_start, cds_end = 4, 21 cds = genome[cds_start:cds_end]
Biology often uses 1-based coordinates. Convert to 0-based:
pythondef extract_1based(seq, start, end): '''Extract using 1-based inclusive coordinates''' return seq[start - 1:end] genome = Seq('ATGCGATCGATCG') region = extract_1based(genome, 1, 3) # Seq('ATG')
pythondef split_codons(seq): return [seq[i:i+3] for i in range(0, len(seq) - len(seq) % 3, 3)] seq = Seq('ATGCGATCGATCG') codons = split_codons(seq) # [Seq('ATG'), Seq('CGA'), ...]
pythondef chunk_sequence(seq, size): return [seq[i:i+size] for i in range(0, len(seq), size)] seq = Seq('ATGCGATCGATCGATCGATCG') chunks = chunk_sequence(seq, 10)
pythonseqs = [Seq('ATGC'), Seq('GGGG'), Seq('TTTT')] linker = Seq('NNN') joined = linker.join(seqs) # Seq('ATGCNNNGGGGNNTTTT')
Or manually:
pythonlinker = 'NNN' joined = Seq(linker.join(str(s) for s in seqs))
pythondef extract_regions(seq, regions): '''Extract and concatenate multiple regions''' return sum((seq[start:end] for start, end in regions), Seq('')) exon_coords = [(0, 50), (100, 150), (200, 250)] mrna = extract_regions(genomic_seq, exon_coords)
pythondef get_flanking(seq, position, flank_size): '''Get sequence around a position''' start = max(0, position - flank_size) end = min(len(seq), position + flank_size + 1) return seq[start:end] seq = Seq('ATGCGATCGATCGATCGATCG') flanking = get_flanking(seq, 10, 5) # 5 bp on each side of position 10
pythondef sliding_windows(seq, window_size, step=1): for i in range(0, len(seq) - window_size + 1, step): yield seq[i:i + window_size] seq = Seq('ATGCGATCGATCG') for window in sliding_windows(seq, 5, 2): print(window)
pythonfrom Bio import SeqIO for record in SeqIO.parse('sequence.gb', 'genbank'): for feature in record.features: if feature.type == 'CDS': cds_seq = feature.extract(record.seq) print(f'{feature.qualifiers.get("gene", ["?"])[0]}: {cds_seq[:30]}...')
pythonfrom Bio.SeqRecord import SeqRecord original = SeqRecord(Seq('ATGCGATCGATCGATCG'), id='full', description='Full sequence') subset = SeqRecord(original.seq[5:15], id='subset', description=f'Positions 5-15 of {original.id}')
| System | Position 1 | Example | |--------|------------|---------| | 0-based (Python) | Index 0 | seq[0:3] gets positions 0, 1, 2 | | 1-based (Biology) | Index 1 | Position 1-3 = seq[0:3] | | 0-based half-open | Start inclusive, end exclusive | Standard Python slicing |
| Error | Cause | Solution | |-------|-------|----------| | IndexError | Index out of range | Check sequence length first | | Unexpected length | Off-by-one error | Remember end index is exclusive | | Empty result | Start >= end | Check coordinate order | | Wrong positions | 1-based vs 0-based confusion | Convert coordinates explicitly |
Need to extract or combine sequences?
├── Single position?
│ └── Use indexing: seq[i]
├── Contiguous region?
│ └── Use slicing: seq[start:end]
├── Multiple non-contiguous regions?
│ └── Extract each, concatenate with +
├── Join sequences?
│ ├── No linker: seq1 + seq2
│ └── With linker: linker.join(seqs)
├── Split into parts?
│ └── List comprehension with slicing
└── From GenBank features?
└── Use feature.extract(record.seq)<!-- 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-02 | pass→pass | 2,533 | 2,454 | -3% | 1 | 1 | 0% | 418 | 2,215 | +430% | 0 | 0 | — |
case-03 | pass→pass | 3,805 | 2,465 | -35% | 1 | 1 | 0% | 715 | 2,244 | +214% | 0 | 0 | — |
case-01 | pass→pass | 2,471 | 1,983 | -20% | 1 | 1 | 0% | 414 | 2,146 | +418% | 0 | 0 | — |
case-15 | pass→pass | 3,012 | 2,553 | -15% | 1 | 1 | 0% | 517 | 2,082 | +303% | 0 | 0 | — |
case-20 | pass→pass | 5,162 | 2,819 | -45% | 1 | 1 | 0% | 939 | 2,286 | +143% | 0 | 0 | — |
case-21 | pass→pass | 2,312 | 1,680 | -27% | 1 | 1 | 0% | 428 | 2,072 | +384% | 0 | 0 | — |
case-04 | pass→pass | 6,007 | 5,052 | -16% | 1 | 1 | 0% | 1,287 | 2,848 | +121% | 0 | 0 | — |
case-14 | pass→pass | 4,177 | 2,488 | -40% | 1 | 1 | 0% | 767 | 2,196 | +186% | 0 | 0 | — |
case-13 | pass→pass | 2,336 | 2,296 | -2% | 1 | 1 | 0% | 393 | 2,115 | +438% | 0 | 0 | — |
case-05 | pass→pass | 8,916 | 4,643 | -48% | 1 | 1 | 0% | 1,746 | 2,679 | +53% | 0 | 0 | — |
case-06 | pass→pass | 5,363 | 4,267 | -20% | 1 | 1 | 0% | 1,034 | 2,502 | +142% | 0 | 0 | — |
case-07 | pass→pass | 2,821 | 2,007 | -29% | 1 | 1 | 0% | 447 | 2,157 | +383% | 0 | 0 | — |
case-08 | pass→pass | 12,892 | 5,533 | -57% | 1 | 1 | 0% | 2,659 | 2,850 | +7% | 0 | 0 | — |
case-09 | pass→pass | 7,258 | 4,820 | -34% | 1 | 1 | 0% | 1,497 | 2,730 | +82% | 0 | 0 | — |
case-10 | pass→pass | 8,008 | 6,051 | -24% | 1 | 1 | 0% | 1,747 | 2,943 | +68% | 0 | 0 | — |
case-11 | pass→pass | 8,166 | 3,378 | -59% | 1 | 1 | 0% | 1,492 | 2,426 | +63% | 0 | 0 | — |
case-12 | fail→pass | 11,996 | 4,720 | -61% | 1 | 1 | 0% | 1,624 | 2,765 | +70% | 0 | 0 | — |
case-16 | pass→pass | 3,563 | 2,212 | -38% | 1 | 1 | 0% | 625 | 2,134 | +241% | 0 | 0 | — |
case-17 | pass→pass | 12,010 | 6,083 | -49% | 1 | 1 | 0% | 2,469 | 2,989 | +21% | 0 | 0 | — |
case-18 | pass→pass | 4,116 | 2,055 | -50% | 1 | 1 | 0% | 811 | 2,126 | +162% | 0 | 0 | — |
case-19 | pass→pass | 8,375 | 5,699 | -32% | 1 | 1 | 0% | 1,714 | 2,921 | +70% | 0 | 0 | — |
case-22 | pass→pass | 3,803 | 2,474 | -35% | 1 | 1 | 0% | 704 | 2,182 | +210% | 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 +5 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/26/2026 | +9% |
Other measured skills in the registry, with their headline benchmark lift.