bioLOLPython 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. biololpython-0.1.0/LICENSE +21 -0
  2. biololpython-0.1.0/PKG-INFO +22 -0
  3. biololpython-0.1.0/bioLOLPython/__init__.py +0 -0
  4. biololpython-0.1.0/bioLOLPython/__main__.py +3 -0
  5. biololpython-0.1.0/bioLOLPython/bio/__init__.py +0 -0
  6. biololpython-0.1.0/bioLOLPython/bio/sequence.py +59 -0
  7. biololpython-0.1.0/bioLOLPython/cli.py +88 -0
  8. biololpython-0.1.0/bioLOLPython/dialects/__init__.py +67 -0
  9. biololpython-0.1.0/bioLOLPython/dialects/base.py +105 -0
  10. biololpython-0.1.0/bioLOLPython/dialects/brainrot.py +64 -0
  11. biololpython-0.1.0/bioLOLPython/dialects/definitions/__init__.py +0 -0
  12. biololpython-0.1.0/bioLOLPython/dialects/definitions/brainrot.yaml +71 -0
  13. biololpython-0.1.0/bioLOLPython/dialects/definitions/gen_z.yaml +71 -0
  14. biololpython-0.1.0/bioLOLPython/dialects/definitions/index.txt +3 -0
  15. biololpython-0.1.0/bioLOLPython/dialects/definitions/lolcat.yaml +71 -0
  16. biololpython-0.1.0/bioLOLPython/dialects/gen_z.py +64 -0
  17. biololpython-0.1.0/bioLOLPython/dialects/lolcat.py +64 -0
  18. biololpython-0.1.0/bioLOLPython/dialects/remote.py +91 -0
  19. biololpython-0.1.0/bioLOLPython/interpreter.py +1049 -0
  20. biololpython-0.1.0/bioLOLPython.egg-info/PKG-INFO +22 -0
  21. biololpython-0.1.0/bioLOLPython.egg-info/SOURCES.txt +28 -0
  22. biololpython-0.1.0/bioLOLPython.egg-info/dependency_links.txt +1 -0
  23. biololpython-0.1.0/bioLOLPython.egg-info/entry_points.txt +2 -0
  24. biololpython-0.1.0/bioLOLPython.egg-info/requires.txt +3 -0
  25. biololpython-0.1.0/bioLOLPython.egg-info/top_level.txt +1 -0
  26. biololpython-0.1.0/pyproject.toml +38 -0
  27. biololpython-0.1.0/setup.cfg +4 -0
  28. biololpython-0.1.0/tests/test_dialects.py +197 -0
  29. biololpython-0.1.0/tests/test_interpreter.py +315 -0
  30. biololpython-0.1.0/tests/test_sequence.py +113 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024-2026 Chen Hsieh
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,22 @@
1
+ Metadata-Version: 2.4
2
+ Name: bioLOLPython
3
+ Version: 0.1.0
4
+ Summary: A meme-inspired biological language interpreter — internet slang meets bioinformatics
5
+ Author-email: Chen Hsieh <chen.hsieh.uga@gmail.com>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/ChenHsieh/bioLOLPython
8
+ Project-URL: Repository, https://github.com/ChenHsieh/bioLOLPython
9
+ Project-URL: Issues, https://github.com/ChenHsieh/bioLOLPython/issues
10
+ Keywords: bioinformatics,esoteric-language,meme,lolcode,dna,genomics
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Intended Audience :: Education
13
+ Classifier: Intended Audience :: Science/Research
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
16
+ Requires-Python: >=3.8
17
+ Description-Content-Type: text/markdown
18
+ License-File: LICENSE
19
+ Requires-Dist: biopython
20
+ Requires-Dist: ply
21
+ Requires-Dist: pyyaml
22
+ Dynamic: license-file
File without changes
@@ -0,0 +1,3 @@
1
+ from bioLOLPython.cli import main
2
+
3
+ main()
File without changes
@@ -0,0 +1,59 @@
1
+ import re
2
+ from Bio.Seq import Seq
3
+
4
+ IUPAC_DNA_RNA = set("ACGTUNRYSWKMBDHVacgtunryswkmbdhv")
5
+
6
+
7
+ class BioSeq:
8
+ def __init__(self, sequence, validate=True):
9
+ if validate and sequence:
10
+ invalid = set(sequence) - IUPAC_DNA_RNA
11
+ if invalid:
12
+ raise ValueError(
13
+ f"Invalid characters in sequence: {''.join(sorted(invalid))}. "
14
+ f"Only IUPAC nucleotide codes are allowed (ACGTUNRYSWKMBDHV)."
15
+ )
16
+ self.seq = Seq(sequence)
17
+
18
+ def reverse_complement(self):
19
+ return str(self.seq.reverse_complement())
20
+
21
+ def complement(self):
22
+ return str(self.seq.complement())
23
+
24
+ def gc_content(self):
25
+ length = len(self.seq)
26
+ if length == 0:
27
+ gc = 0.0
28
+ else:
29
+ g = self.seq.upper().count('G')
30
+ c = self.seq.upper().count('C')
31
+ gc = (g + c) / length * 100
32
+ return gc
33
+
34
+ def length(self):
35
+ return len(self.seq)
36
+
37
+ def find_orf(self):
38
+ """Find the first open reading frame (ATG to stop codon)."""
39
+ seq_str = str(self.seq).upper()
40
+ start = seq_str.find("ATG")
41
+ if start == -1:
42
+ return None
43
+ stop_codons = ("TAA", "TAG", "TGA")
44
+ for i in range(start, len(seq_str) - 2, 3):
45
+ codon = seq_str[i:i+3]
46
+ if codon in stop_codons and i > start:
47
+ return seq_str[start:i+3]
48
+ # No stop codon found — return from ATG to end
49
+ return seq_str[start:]
50
+
51
+ def find_motif(self, pattern):
52
+ """Find all occurrences of a motif pattern in the sequence."""
53
+ matches = []
54
+ for m in re.finditer(pattern, str(self.seq), re.IGNORECASE):
55
+ matches.append((m.start() + 1, m.end())) # 1-indexed
56
+ return matches
57
+
58
+ def __str__(self):
59
+ return str(self.seq)
@@ -0,0 +1,88 @@
1
+ # bioLOLPython/cli.py
2
+ import sys
3
+ from bioLOLPython.interpreter import handle_line, reset_bio_vars, set_dialect
4
+ from bioLOLPython.dialects import list_dialects, dialect_names, reload_dialects
5
+
6
+
7
+ def repl(dialect_name="lolcat"):
8
+ """Interactive REPL mode."""
9
+ set_dialect(dialect_name)
10
+ print(f"🐾 bioLOL REPL v0.1 ({dialect_name} mode)")
11
+ print(f" Type bio commands. Ctrl+C or 'exit' to quit.\n")
12
+ reset_bio_vars()
13
+ try:
14
+ while True:
15
+ try:
16
+ line = input("> ").strip()
17
+ except EOFError:
18
+ break
19
+ if line.lower() in ("exit", "quit"):
20
+ break
21
+ if line:
22
+ handle_line(line, dialect_name=dialect_name)
23
+ except KeyboardInterrupt:
24
+ pass
25
+ print("\n👋 kthxbye!")
26
+
27
+
28
+ def print_dialects():
29
+ """Print available dialects."""
30
+ print("Available dialects:\n")
31
+ for d in list_dialects():
32
+ print(f" {d['name']:12s} {d['era']:14s} {d['description']}")
33
+ print()
34
+
35
+
36
+ def do_update(force=False):
37
+ """Fetch latest dialects from remote registry."""
38
+ from bioLOLPython.dialects.remote import update_dialects
39
+ print("🔄 Updating dialects from remote registry...")
40
+ results = update_dialects(force=force)
41
+ for name, status in results:
42
+ icon = "✅" if status == "updated" else "📦" if status == "cached" else "❌"
43
+ print(f" {icon} {name}: {status}")
44
+ reload_dialects()
45
+ print(f"\n{len(dialect_names())} dialect(s) available.")
46
+
47
+
48
+ def main():
49
+ dialect = "lolcat"
50
+ args = sys.argv[1:]
51
+
52
+ if "--list-dialects" in args:
53
+ print_dialects()
54
+ return
55
+
56
+ if "--update" in args:
57
+ force = "--force" in args
58
+ do_update(force=force)
59
+ return
60
+
61
+ if "--dialect" in args:
62
+ idx = args.index("--dialect")
63
+ if idx + 1 < len(args):
64
+ dialect = args[idx + 1]
65
+ if dialect not in dialect_names():
66
+ print(f"❌ Unknown dialect '{dialect}'.")
67
+ print_dialects()
68
+ return
69
+ args = args[:idx] + args[idx + 2:]
70
+ else:
71
+ print("❌ --dialect requires a name argument.")
72
+ print_dialects()
73
+ return
74
+
75
+ if not args:
76
+ repl(dialect)
77
+ return
78
+
79
+ filename = args[0]
80
+ reset_bio_vars()
81
+ set_dialect(dialect)
82
+ with open(filename) as f:
83
+ for line in f:
84
+ handle_line(line.strip(), dialect_name=dialect)
85
+
86
+
87
+ if __name__ == "__main__":
88
+ main()
@@ -0,0 +1,67 @@
1
+ """
2
+ Dialect registry for bioLOLPython.
3
+
4
+ Each dialect maps internet slang from a specific era to bioinformatics commands.
5
+ Dialects are loaded from YAML files in this order (later overrides earlier):
6
+ 1. Bundled definitions (bioLOLPython/dialects/definitions/*.yaml)
7
+ 2. User definitions (~/.bioLOL/dialects/*.yaml)
8
+ """
9
+ from bioLOLPython.dialects.base import (
10
+ BUNDLED_DIR,
11
+ USER_DIR,
12
+ compile_dialect,
13
+ discover_yaml_dialects,
14
+ load_yaml_dialect,
15
+ validate_dialect,
16
+ )
17
+
18
+ _DIALECTS = {}
19
+
20
+
21
+ def _load_all():
22
+ """Load dialects from YAML files (bundled + user)."""
23
+ global _DIALECTS
24
+ _DIALECTS = discover_yaml_dialects(BUNDLED_DIR, USER_DIR)
25
+
26
+ # Fallback: if no YAML files found, load from Python modules
27
+ if not _DIALECTS:
28
+ from bioLOLPython.dialects.lolcat import DIALECT as _lolcat
29
+ from bioLOLPython.dialects.gen_z import DIALECT as _gen_z
30
+ from bioLOLPython.dialects.brainrot import DIALECT as _brainrot
31
+ for d in (_lolcat, _gen_z, _brainrot):
32
+ compiled = compile_dialect(d)
33
+ _DIALECTS[compiled["name"]] = compiled
34
+
35
+
36
+ _load_all()
37
+
38
+
39
+ def reload_dialects():
40
+ """Reload all dialects from disk. Useful after fetching remote dialects."""
41
+ _load_all()
42
+
43
+
44
+ def register_dialect(dialect_def):
45
+ """Register a dialect from a Python dict (for programmatic use)."""
46
+ validate_dialect(dialect_def)
47
+ compiled = compile_dialect(dialect_def)
48
+ _DIALECTS[compiled["name"]] = compiled
49
+ return compiled
50
+
51
+
52
+ def get_dialect(name):
53
+ if name not in _DIALECTS:
54
+ available = ", ".join(sorted(_DIALECTS.keys()))
55
+ raise ValueError(f"Unknown dialect '{name}'. Available: {available}")
56
+ return _DIALECTS[name]
57
+
58
+
59
+ def list_dialects():
60
+ return [
61
+ {"name": d["name"], "era": d["era"], "description": d["description"]}
62
+ for d in _DIALECTS.values()
63
+ ]
64
+
65
+
66
+ def dialect_names():
67
+ return sorted(_DIALECTS.keys())
@@ -0,0 +1,105 @@
1
+ """
2
+ Base dialect infrastructure.
3
+
4
+ Each dialect defines patterns for bio commands using a template syntax:
5
+ - {name}, {a}, {b} -> capture a variable name (word characters)
6
+ - {seq} -> capture a quoted sequence string
7
+ - {pattern} -> capture a quoted pattern string
8
+ - Remaining text -> matched literally (case-sensitive)
9
+
10
+ Patterns are compiled into regexes at registration time.
11
+ Dialects can be defined as YAML files or Python dicts.
12
+ """
13
+ import re
14
+ import os
15
+ import yaml
16
+ from pathlib import Path
17
+
18
+ # Template placeholders -> regex groups
19
+ _PLACEHOLDER_RE = re.compile(r"\{(\w+)\}")
20
+
21
+ _PLACEHOLDER_PATTERNS = {
22
+ "seq": r'"(?P<seq>[^"]*)"',
23
+ "pattern": r'"(?P<pattern>[^"]*)"',
24
+ }
25
+
26
+ # Required commands every dialect must define
27
+ REQUIRED_COMMANDS = [
28
+ "init", "end", "declare", "reverse", "gc_content",
29
+ "print", "transcribe", "translate", "align", "mutate",
30
+ "length", "complement", "find_orf", "motif",
31
+ ]
32
+
33
+ # Bundled YAML definitions directory
34
+ BUNDLED_DIR = Path(__file__).parent / "definitions"
35
+
36
+ # User dialect directory
37
+ USER_DIR = Path.home() / ".bioLOL" / "dialects"
38
+
39
+
40
+ def _compile_pattern(template):
41
+ """Compile a dialect pattern template into a regex."""
42
+ parts = _PLACEHOLDER_RE.split(template)
43
+ regex_parts = []
44
+ for i, part in enumerate(parts):
45
+ if i % 2 == 0:
46
+ # Literal text — escape and normalize spaces to \s+
47
+ escaped = re.escape(part.strip())
48
+ escaped = escaped.replace(r"\ ", r"\s+")
49
+ regex_parts.append(escaped)
50
+ else:
51
+ # Placeholder name
52
+ if part in _PLACEHOLDER_PATTERNS:
53
+ regex_parts.append(_PLACEHOLDER_PATTERNS[part])
54
+ else:
55
+ regex_parts.append(rf"(?P<{part}>\w+)")
56
+ return re.compile(r"^\s*" + r"\s+".join(p for p in regex_parts if p) + r"(?:\s+.*)?$")
57
+
58
+
59
+ def compile_dialect(dialect_def):
60
+ """Compile all patterns in a dialect definition, adding 'matcher' to each command."""
61
+ for cmd_name, cmd_def in dialect_def["commands"].items():
62
+ cmd_def["matcher"] = _compile_pattern(cmd_def["pattern"])
63
+ return dialect_def
64
+
65
+
66
+ def validate_dialect(dialect_def):
67
+ """Validate a dialect definition has all required fields."""
68
+ for field in ("name", "era", "description", "commands"):
69
+ if field not in dialect_def:
70
+ raise ValueError(f"Dialect missing required field: '{field}'")
71
+ for cmd in REQUIRED_COMMANDS:
72
+ if cmd not in dialect_def["commands"]:
73
+ raise ValueError(
74
+ f"Dialect '{dialect_def['name']}' missing command: '{cmd}'"
75
+ )
76
+ if "pattern" not in dialect_def["commands"][cmd]:
77
+ raise ValueError(
78
+ f"Dialect '{dialect_def['name']}' command '{cmd}' missing 'pattern'"
79
+ )
80
+ return True
81
+
82
+
83
+ def load_yaml_dialect(path):
84
+ """Load and compile a dialect from a YAML file."""
85
+ with open(path, "r") as f:
86
+ dialect_def = yaml.safe_load(f)
87
+ validate_dialect(dialect_def)
88
+ return compile_dialect(dialect_def)
89
+
90
+
91
+ def discover_yaml_dialects(*dirs):
92
+ """Discover all .yaml dialect files in the given directories.
93
+ Later directories override earlier ones (user overrides bundled)."""
94
+ dialects = {}
95
+ for d in dirs:
96
+ if not d.is_dir():
97
+ continue
98
+ for path in sorted(d.glob("*.yaml")):
99
+ try:
100
+ dialect = load_yaml_dialect(path)
101
+ dialects[dialect["name"]] = dialect
102
+ except Exception as e:
103
+ # Skip invalid files silently in discovery
104
+ print(f"⚠️ Skipping {path.name}: {e}")
105
+ return dialects
@@ -0,0 +1,64 @@
1
+ DIALECT = {
2
+ "name": "brainrot",
3
+ "era": "~2023-2026",
4
+ "description": "skibidi DNA sigma rizz. Gen Alpha brainrot meets bioinformatics.",
5
+ "commands": {
6
+ "init": {
7
+ "pattern": "SKIBIDI GENOME",
8
+ "greeting": "🚽 SKIBIDI BIOLAB ACTIVATED sigma grindset 🧬",
9
+ },
10
+ "end": {
11
+ "pattern": "MOGGER OUT",
12
+ },
13
+ "declare": {
14
+ "pattern": "SIGMA {name} RIZZ {seq}",
15
+ },
16
+ "reverse": {
17
+ "pattern": "FANUM TAX {name}",
18
+ },
19
+ "gc_content": {
20
+ "pattern": "AURA CHECK {name}",
21
+ "response": "✨ GC aura: {value:.2f}% {rating} 🧬",
22
+ },
23
+ "print": {
24
+ "pattern": "HAWK TUAH",
25
+ },
26
+ "transcribe": {
27
+ "pattern": "EDGING {name}",
28
+ },
29
+ "translate": {
30
+ "pattern": "LOOKSMAX {name}",
31
+ },
32
+ "align": {
33
+ "pattern": "MEWING CONTEST {a} VS {b}",
34
+ "response": "🗿 MEWING SCOREZ: {score:.2f} {rating}",
35
+ },
36
+ "mutate": {
37
+ "pattern": "ONLY IN OHIO {name}",
38
+ "response": "💀 ohio moment for {name} at pos {pos}: {old} ➜ {new}",
39
+ },
40
+ "length": {
41
+ "pattern": "GYATT HOW LONG {name}",
42
+ "response": "📏 {name} is {value} bases long gyatt",
43
+ },
44
+ "complement": {
45
+ "pattern": "REVERSE UNO {name}",
46
+ },
47
+ "find_orf": {
48
+ "pattern": "SIGMA GRIND {name}",
49
+ "orf_found": "💪 sigma ORF found: {orf} ({length} bp) W",
50
+ "orf_missing": "💀 {name} is not sigma (no ATG start codon) L",
51
+ },
52
+ "motif": {
53
+ "pattern": "SUSSY SEARCH {name} FOR {pattern}",
54
+ "found": "🔍 '{pattern}' is sus in {name} {count} time(s):",
55
+ "position": " pos {start}-{end}",
56
+ "not_found": "🔍 '{pattern}' is not sus in {name}",
57
+ },
58
+ },
59
+ "examples": {
60
+ "GC Content": 'SKIBIDI GENOME\nSIGMA X RIZZ "ATGCATGC"\nAURA CHECK X\nMOGGER OUT',
61
+ "Protein Translation": 'SKIBIDI GENOME\nSIGMA Y RIZZ "ATGGAGGAGCC"\nLOOKSMAX Y\nHAWK TUAH "Protein: " + Y\nMOGGER OUT',
62
+ "Alignment": 'SKIBIDI GENOME\nSIGMA A RIZZ "ATGCGTAGG"\nSIGMA B RIZZ "ATGCGTACG"\nMEWING CONTEST A VS B\nMOGGER OUT',
63
+ },
64
+ }
@@ -0,0 +1,71 @@
1
+ name: brainrot
2
+ era: "~2023-2026"
3
+ description: "skibidi DNA sigma rizz. Gen Alpha brainrot meets bioinformatics."
4
+
5
+ commands:
6
+ init:
7
+ pattern: "SKIBIDI GENOME"
8
+ greeting: "🚽 SKIBIDI BIOLAB ACTIVATED sigma grindset 🧬"
9
+ end:
10
+ pattern: "MOGGER OUT"
11
+ declare:
12
+ pattern: 'SIGMA {name} RIZZ {seq}'
13
+ reverse:
14
+ pattern: "FANUM TAX {name}"
15
+ gc_content:
16
+ pattern: "AURA CHECK {name}"
17
+ response: "✨ GC aura: {value:.2f}% {rating} 🧬"
18
+ print:
19
+ pattern: "HAWK TUAH"
20
+ transcribe:
21
+ pattern: "EDGING {name}"
22
+ translate:
23
+ pattern: "LOOKSMAX {name}"
24
+ align:
25
+ pattern: "MEWING CONTEST {a} VS {b}"
26
+ response: "🗿 MEWING SCOREZ: {score:.2f} {rating}"
27
+ mutate:
28
+ pattern: "ONLY IN OHIO {name}"
29
+ response: "💀 ohio moment for {name} at pos {pos}: {old} ➜ {new}"
30
+ length:
31
+ pattern: "GYATT HOW LONG {name}"
32
+ response: "📏 {name} is {value} bases long gyatt"
33
+ complement:
34
+ pattern: "REVERSE UNO {name}"
35
+ find_orf:
36
+ pattern: "SIGMA GRIND {name}"
37
+ orf_found: "💪 sigma ORF found: {orf} ({length} bp) W"
38
+ orf_missing: "💀 {name} is not sigma (no ATG start codon) L"
39
+ motif:
40
+ pattern: 'SUSSY SEARCH {name} FOR {pattern}'
41
+ found: "🔍 '{pattern}' is sus in {name} {count} time(s):"
42
+ position: " pos {start}-{end}"
43
+ not_found: "🔍 '{pattern}' is not sus in {name}"
44
+
45
+ examples:
46
+ GC Content: |
47
+ SKIBIDI GENOME
48
+ SIGMA X RIZZ "ATGCATGC"
49
+ AURA CHECK X
50
+ MOGGER OUT
51
+ Protein Translation: |
52
+ SKIBIDI GENOME
53
+ SIGMA Y RIZZ "ATGGAGGAGCC"
54
+ LOOKSMAX Y
55
+ HAWK TUAH "Protein: " + Y
56
+ MOGGER OUT
57
+ Alignment: |
58
+ SKIBIDI GENOME
59
+ SIGMA A RIZZ "ATGCGTAGG"
60
+ SIGMA B RIZZ "ATGCGTACG"
61
+ MEWING CONTEST A VS B
62
+ MOGGER OUT
63
+ Sequence Analysis: |
64
+ SKIBIDI GENOME
65
+ SIGMA X RIZZ "AAATGCCCCCCTAAGG"
66
+ GYATT HOW LONG X
67
+ SIGMA GRIND X
68
+ SUSSY SEARCH X FOR "CCC"
69
+ REVERSE UNO X
70
+ HAWK TUAH "complement: " + X
71
+ MOGGER OUT
@@ -0,0 +1,71 @@
1
+ name: gen_z
2
+ era: "~2018-2023"
3
+ description: "no cap this DNA is bussin fr fr. TikTok-era slang meets molecular biology."
4
+
5
+ commands:
6
+ init:
7
+ pattern: "YO ITS GIVING GENOME"
8
+ greeting: "💅 ok bestie let's sequence this slay 🧬"
9
+ end:
10
+ pattern: "PERIODT"
11
+ declare:
12
+ pattern: 'NO CAP {name} IS {seq}'
13
+ reverse:
14
+ pattern: "UNO REVERSE {name}"
15
+ gc_content:
16
+ pattern: "VIBE CHECK {name}"
17
+ response: "💅 GC content: {value:.2f}% no cap 🧬"
18
+ print:
19
+ pattern: "SPILL"
20
+ transcribe:
21
+ pattern: "MAIN CHARACTER {name}"
22
+ translate:
23
+ pattern: "GLOW UP {name}"
24
+ align:
25
+ pattern: "RIZZ CHECK {a} AND {b}"
26
+ response: "✨ RIZZ SCOREZ: {score:.2f} it's giving {rating}"
27
+ mutate:
28
+ pattern: "CAUGHT IN 4K {name}"
29
+ response: "📸 caught {name} in 4K at pos {pos}: {old} ➜ {new} sus"
30
+ length:
31
+ pattern: "BESTIE HOW LONG {name}"
32
+ response: "📏 {name} is {value} bases long bestie"
33
+ complement:
34
+ pattern: "MIRROR CHECK {name}"
35
+ find_orf:
36
+ pattern: "UNDERSTOOD THE ASSIGNMENT {name}"
37
+ orf_found: "💯 ORF understood: {orf} ({length} bp) slay"
38
+ orf_missing: "💀 {name} did NOT understand the assignment (no ATG)"
39
+ motif:
40
+ pattern: 'LIVING RENT FREE {name} FOR {pattern}'
41
+ found: "🏠 '{pattern}' found living rent free in {name} {count} time(s):"
42
+ position: " pos {start}-{end}"
43
+ not_found: "🏠 '{pattern}' is NOT living rent free in {name}"
44
+
45
+ examples:
46
+ GC Content: |
47
+ YO ITS GIVING GENOME
48
+ NO CAP X IS "ATGCATGC"
49
+ VIBE CHECK X
50
+ PERIODT
51
+ Protein Translation: |
52
+ YO ITS GIVING GENOME
53
+ NO CAP Y IS "ATGGAGGAGCC"
54
+ GLOW UP Y
55
+ SPILL "Protein: " + Y
56
+ PERIODT
57
+ Alignment: |
58
+ YO ITS GIVING GENOME
59
+ NO CAP A IS "ATGCGTAGG"
60
+ NO CAP B IS "ATGCGTACG"
61
+ RIZZ CHECK A AND B
62
+ PERIODT
63
+ Sequence Analysis: |
64
+ YO ITS GIVING GENOME
65
+ NO CAP X IS "AAATGCCCCCCTAAGG"
66
+ BESTIE HOW LONG X
67
+ UNDERSTOOD THE ASSIGNMENT X
68
+ LIVING RENT FREE X FOR "CCC"
69
+ MIRROR CHECK X
70
+ SPILL "complement: " + X
71
+ PERIODT
@@ -0,0 +1,3 @@
1
+ lolcat
2
+ gen_z
3
+ brainrot
@@ -0,0 +1,71 @@
1
+ name: lolcat
2
+ era: "~2005-2012"
3
+ description: "I CAN HAS BIOINFORMATICS? Classic lolspeak from the cheezburger era."
4
+
5
+ commands:
6
+ init:
7
+ pattern: "HAI GENZOME"
8
+ greeting: "🐾 LOADING bioLOLCODE V1... LETZ GOOOO 💥"
9
+ end:
10
+ pattern: "KTHXBYE"
11
+ declare:
12
+ pattern: 'DNA GO {name} ITZ {seq}'
13
+ reverse:
14
+ pattern: "REVERSE THAT {name}"
15
+ gc_content:
16
+ pattern: "GC BOMB {name}"
17
+ response: "💥 GC content: {value:.2f}% 🧬"
18
+ print:
19
+ pattern: "VISIBLE"
20
+ transcribe:
21
+ pattern: "TRANSCRIBE {name}"
22
+ translate:
23
+ pattern: "TRANSLATE {name}"
24
+ align:
25
+ pattern: "ALIGN {a} WIT {b}"
26
+ response: "🌈 ALINE SCOREZ: {score:.2f} 🔥 itz {rating}!!"
27
+ mutate:
28
+ pattern: "I CRAVE VIOLENCE {name}"
29
+ response: "💣 mutated {name} at pos {pos}: {old} ➜ {new}"
30
+ length:
31
+ pattern: "HOW LONG {name}"
32
+ response: "📏 {name} iz {value} bases long"
33
+ complement:
34
+ pattern: "COMPLEMENT {name}"
35
+ find_orf:
36
+ pattern: "FIND ORF {name}"
37
+ orf_found: "🔍 ORF found: {orf} ({length} bp)"
38
+ orf_missing: "🔍 No ORF found in {name} (no ATG start codon)"
39
+ motif:
40
+ pattern: 'MOTIF HUNT {name} FOR {pattern}'
41
+ found: "🎯 Found {count} match(es) for '{pattern}' in {name}:"
42
+ position: " pos {start}-{end}"
43
+ not_found: "🎯 No matches for '{pattern}' in {name}"
44
+
45
+ examples:
46
+ GC Content: |
47
+ HAI GENZOME 1.0
48
+ DNA GO X ITZ "ATGCATGC"
49
+ GC BOMB X
50
+ KTHXBYE
51
+ Protein Translation: |
52
+ HAI GENZOME 1.0
53
+ DNA GO Y ITZ "ATGGAGGAGCC"
54
+ TRANSLATE Y
55
+ VISIBLE "Protein: " + Y
56
+ KTHXBYE
57
+ Alignment: |
58
+ HAI GENZOME 1.0
59
+ DNA GO A ITZ "ATGCGTAGG"
60
+ DNA GO B ITZ "ATGCGTACG"
61
+ ALIGN A WIT B
62
+ KTHXBYE
63
+ Sequence Analysis: |
64
+ HAI GENZOME 1.0
65
+ DNA GO X ITZ "AAATGCCCCCCTAAGG"
66
+ HOW LONG X
67
+ FIND ORF X
68
+ MOTIF HUNT X FOR "CCC"
69
+ COMPLEMENT X
70
+ VISIBLE "complement: " + X
71
+ KTHXBYE