| name | python-bio-variables |
| description | Declare and manipulate Python variables and core data types (int, float, str, bool, None) for bioinformatics scripts — naming, mutability, references, string slicing/indexing of DNA/RNA/protein sequences. Use when writing beginner Python for biology, explaining variable assignment/reassignment, debugging aliasing or mutable-default-argument bugs, or parsing sequence strings and FASTA headers with slicing/split/join. |
| tool_type | python |
| primary_tool | Python |
Variables and Data Types
When to Use
- Writing or reviewing introductory Python bioinformatics scripts that assign sequences, counts, or scores to variables.
- Explaining why
alias = original doesn't copy a list/dict, or why seq = seq + "AAA" doesn't mutate the original string.
- Choosing between
int, float, str, bool, None for genomic data (coordinates, GC content, E-values, sequences, missing annotations).
- Slicing/indexing DNA/RNA/protein strings (start/stop codons, reverse complement setup, coding regions).
- Parsing simple text formats (FASTA headers, delimited fields) with
split()/join()/strip().
Version Compatibility
Python ≥3.9 (f-strings, arbitrary-precision int — no special version dependency; syntax here works on any Python 3.x).
Prerequisites
None — this is foundational Python, no external packages required. Useful next step: bio-sequence-manipulation-seq-objects for Bio.Seq objects once past raw strings.
Naming rules and conventions
Rules (breaking these is a SyntaxError):
- Names may contain letters, digits, and underscores; must start with a letter or underscore (not a digit).
- Names are case-sensitive (
gene and Gene are different variables).
- Python keywords (
if, for, class, ...) cannot be used as names.
Conventions:
snake_case for variables/functions: gene_name, sequence_length.
UPPER_CASE for constants: AVOGADRO = 6.022e23.
- Descriptive names:
gc_content, not gc or x.
sequence_length = 1500
gene_name = "TP53"
melting_temperature = 65.5
x = 1500
seqLen = 1500
three = 1
Data Types Overview
| Type | Example | Bioinformatics use |
|---|
int | 42 | Sequence length, read count, coordinate |
float | 0.487 | GC content, E-value, p-value |
str | "ATGCGA" | DNA/RNA/protein sequence, gene name |
bool | True | Is valid? Has stop codon? Passed QC? |
NoneType | None | Missing annotation, unset default argument |
def describe_types(values):
"""Print the runtime type of each value in an iterable.
Mirrors a common bioinformatics debugging step: confirming a parsed
field (from a VCF, FASTA header, or config file) came back as the
expected type rather than a string.
"""
for v in values:
print(f"{str(v):25s} -> {type(v).__name__}")
describe_types([15_000_000, 0.52, "Escherichia coli", True, None])
Variables are references, not boxes
Goal: understand why aliasing a list/dict silently shares mutations, while aliasing a string/number does not.
Approach: inspect id() before and after reassignment vs. in-place mutation.
def show_reference_semantics():
"""Demonstrate immutable reassignment vs. mutable in-place mutation."""
sequence = "ATGCGATCG"
before_id = id(sequence)
sequence = sequence + "AAA"
assert id(sequence) != before_id
reads = ["read1", "read2"]
alias = reads
alias.append("read3")
assert reads == ["read1", "read2", "read3"]
coverage_a = coverage_b = []
coverage_a.append(10)
assert coverage_b == [10]
show_reference_semantics()
Numeric types for bioinformatics
sequence_length = 3_088_286_401
read_depth = 30
print(f"Genome: {sequence_length:,} bp, target coverage: {read_depth}x")
gc_content = 0.508
e_value = 1.5e-42
print(f"GC%: {gc_content * 100:.1f}% E-value: {e_value:.2e}")
result, expected, tolerance = 0.1 + 0.2, 0.3, 1e-9
is_close_enough = abs(result - expected) < tolerance
assert is_close_enough
String slicing and parsing (sequences, FASTA headers)
Goal: extract start/stop codons, reverse a sequence, and parse a FASTA header.
Approach: string[start:stop:step] — start inclusive, stop exclusive, negative step reverses.
def parse_orf(dna):
"""Extract start codon, stop codon, and coding region from a raw ORF string.
dna: full open reading frame including start (ATG) and a stop codon.
Returns a dict with start_codon, stop_codon, coding_region, reversed.
"""
return {
"start_codon": dna[0:3],
"stop_codon": dna[-3:],
"coding_region": dna[3:-3],
"has_valid_stop": dna.endswith(("TAA", "TAG", "TGA")),
"reversed": dna[::-1],
}
orf = parse_orf("ATGAAACCCGGGTAA")
assert orf["start_codon"] == "ATG"
assert orf["stop_codon"] == "TAA"
assert orf["coding_region"] == "AAACCCGGG"
assert orf["has_valid_stop"] is True
def parse_fasta_header(header):
"""Parse a UniProt-style FASTA header: '>db|accession|entry_name description'."""
parts = header.lstrip(">").split("|")
db, accession, rest = parts[0], parts[1], parts[2]
entry_name = rest.split()[0]
return {"database": db, "accession": accession, "entry_name": entry_name}
result = parse_fasta_header()
result == {: , : , : }
dna =
rna = dna.replace(, )
rna ==
clean_line = .strip()
clean_line ==
Pitfalls
- Aliasing shares mutable objects:
alias = original does not copy a list/dict — both names reference the same object; mutating through one is visible through the other. Immutable types (str, int, float, tuple) don't have this problem.
a = b = [] creates ONE shared list, not two independent empty lists. Use a, b = [], [] for independence.
- Mutable default arguments: never write
def f(x=[]) — the default list is created once and shared across calls. Use def f(x=None) and set x = x or [] inside.
- Off-by-one errors: Python slicing is half-open
[start, stop), but genomic coordinates (GFF, 1-based VCF POS) are often 1-based inclusive — convert explicitly (gff_start - 1) before slicing a Python string.
- Deep vs. shallow copy:
list.copy() only copies the top level; nested structures (list of lists, dict of lists) need copy.deepcopy().
- Floating-point equality: never compare floats with
==; use abs(a - b) < tolerance.
See Also
bio-sequence-manipulation-seq-objects — move from raw strings to Bio.Seq objects.
bio-sequence-manipulation-sequence-slicing — deeper slicing patterns for sequences.
bio-sequence-manipulation-reverse-complement — building on string reversal shown here.
bio-sequence-io-read-sequences — reading real FASTA/FASTQ files instead of inline strings.