bioLOLPython 0.1.0__py3-none-any.whl
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.
- bioLOLPython/__init__.py +0 -0
- bioLOLPython/__main__.py +3 -0
- bioLOLPython/bio/__init__.py +0 -0
- bioLOLPython/bio/sequence.py +59 -0
- bioLOLPython/cli.py +88 -0
- bioLOLPython/dialects/__init__.py +67 -0
- bioLOLPython/dialects/base.py +105 -0
- bioLOLPython/dialects/brainrot.py +64 -0
- bioLOLPython/dialects/definitions/__init__.py +0 -0
- bioLOLPython/dialects/definitions/brainrot.yaml +71 -0
- bioLOLPython/dialects/definitions/gen_z.yaml +71 -0
- bioLOLPython/dialects/definitions/index.txt +3 -0
- bioLOLPython/dialects/definitions/lolcat.yaml +71 -0
- bioLOLPython/dialects/gen_z.py +64 -0
- bioLOLPython/dialects/lolcat.py +64 -0
- bioLOLPython/dialects/remote.py +91 -0
- bioLOLPython/interpreter.py +1049 -0
- biololpython-0.1.0.dist-info/METADATA +22 -0
- biololpython-0.1.0.dist-info/RECORD +23 -0
- biololpython-0.1.0.dist-info/WHEEL +5 -0
- biololpython-0.1.0.dist-info/entry_points.txt +2 -0
- biololpython-0.1.0.dist-info/licenses/LICENSE +21 -0
- biololpython-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
DIALECT = {
|
|
2
|
+
"name": "lolcat",
|
|
3
|
+
"era": "~2005-2012",
|
|
4
|
+
"description": "I CAN HAS BIOINFORMATICS? Classic lolspeak from the cheezburger era.",
|
|
5
|
+
"commands": {
|
|
6
|
+
"init": {
|
|
7
|
+
"pattern": "HAI GENZOME",
|
|
8
|
+
"greeting": "🐾 LOADING bioLOLCODE V1... LETZ GOOOO 💥",
|
|
9
|
+
},
|
|
10
|
+
"end": {
|
|
11
|
+
"pattern": "KTHXBYE",
|
|
12
|
+
},
|
|
13
|
+
"declare": {
|
|
14
|
+
"pattern": "DNA GO {name} ITZ {seq}",
|
|
15
|
+
},
|
|
16
|
+
"reverse": {
|
|
17
|
+
"pattern": "REVERSE THAT {name}",
|
|
18
|
+
},
|
|
19
|
+
"gc_content": {
|
|
20
|
+
"pattern": "GC BOMB {name}",
|
|
21
|
+
"response": "💥 GC content: {value:.2f}% 🧬",
|
|
22
|
+
},
|
|
23
|
+
"print": {
|
|
24
|
+
"pattern": "VISIBLE",
|
|
25
|
+
},
|
|
26
|
+
"transcribe": {
|
|
27
|
+
"pattern": "TRANSCRIBE {name}",
|
|
28
|
+
},
|
|
29
|
+
"translate": {
|
|
30
|
+
"pattern": "TRANSLATE {name}",
|
|
31
|
+
},
|
|
32
|
+
"align": {
|
|
33
|
+
"pattern": "ALIGN {a} WIT {b}",
|
|
34
|
+
"response": "🌈 ALINE SCOREZ: {score:.2f} 🔥 itz {rating}!!",
|
|
35
|
+
},
|
|
36
|
+
"mutate": {
|
|
37
|
+
"pattern": "I CRAVE VIOLENCE {name}",
|
|
38
|
+
"response": "💣 mutated {name} at pos {pos}: {old} ➜ {new}",
|
|
39
|
+
},
|
|
40
|
+
"length": {
|
|
41
|
+
"pattern": "HOW LONG {name}",
|
|
42
|
+
"response": "📏 {name} iz {value} bases long",
|
|
43
|
+
},
|
|
44
|
+
"complement": {
|
|
45
|
+
"pattern": "COMPLEMENT {name}",
|
|
46
|
+
},
|
|
47
|
+
"find_orf": {
|
|
48
|
+
"pattern": "FIND ORF {name}",
|
|
49
|
+
"orf_found": "🔍 ORF found: {orf} ({length} bp)",
|
|
50
|
+
"orf_missing": "🔍 No ORF found in {name} (no ATG start codon)",
|
|
51
|
+
},
|
|
52
|
+
"motif": {
|
|
53
|
+
"pattern": "MOTIF HUNT {name} FOR {pattern}",
|
|
54
|
+
"found": "🎯 Found {count} match(es) for '{pattern}' in {name}:",
|
|
55
|
+
"position": " pos {start}-{end}",
|
|
56
|
+
"not_found": "🎯 No matches for '{pattern}' in {name}",
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
"examples": {
|
|
60
|
+
"GC Content": 'HAI GENZOME 1.0\nDNA GO X ITZ "ATGCATGC"\nGC BOMB X\nKTHXBYE',
|
|
61
|
+
"Protein Translation": 'HAI GENZOME 1.0\nDNA GO Y ITZ "ATGGAGGAGCC"\nTRANSLATE Y\nVISIBLE "Protein: " + Y\nKTHXBYE',
|
|
62
|
+
"Alignment": 'HAI GENZOME 1.0\nDNA GO A ITZ "ATGCGTAGG"\nDNA GO B ITZ "ATGCGTACG"\nALIGN A WIT B\nKTHXBYE',
|
|
63
|
+
},
|
|
64
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Remote dialect fetching and caching.
|
|
3
|
+
|
|
4
|
+
Fetches dialect YAML files from a remote registry (GitHub raw URL by default),
|
|
5
|
+
caches them locally in ~/.bioLOL/dialects/, and reloads the dialect registry.
|
|
6
|
+
"""
|
|
7
|
+
import os
|
|
8
|
+
import time
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
from urllib.request import urlopen, Request
|
|
11
|
+
from urllib.error import URLError
|
|
12
|
+
|
|
13
|
+
from bioLOLPython.dialects.base import USER_DIR
|
|
14
|
+
|
|
15
|
+
# Default registry: raw GitHub URL pointing to the definitions/ directory
|
|
16
|
+
DEFAULT_REGISTRY_URL = (
|
|
17
|
+
"https://raw.githubusercontent.com/ChenHsieh/bioLOLPython/master/"
|
|
18
|
+
"bioLOLPython/dialects/definitions"
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
# Default index file listing available dialect filenames
|
|
22
|
+
INDEX_FILENAME = "index.txt"
|
|
23
|
+
|
|
24
|
+
# Cache TTL: 24 hours
|
|
25
|
+
CACHE_TTL_SECONDS = 86400
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def _ensure_user_dir():
|
|
29
|
+
USER_DIR.mkdir(parents=True, exist_ok=True)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def _is_cache_fresh(path, ttl=CACHE_TTL_SECONDS):
|
|
33
|
+
"""Check if a cached file is fresh enough."""
|
|
34
|
+
if not path.exists():
|
|
35
|
+
return False
|
|
36
|
+
age = time.time() - path.stat().st_mtime
|
|
37
|
+
return age < ttl
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def _fetch_url(url, timeout=10):
|
|
41
|
+
"""Fetch content from a URL."""
|
|
42
|
+
req = Request(url, headers={"User-Agent": "bioLOLPython"})
|
|
43
|
+
with urlopen(req, timeout=timeout) as resp:
|
|
44
|
+
return resp.read().decode("utf-8")
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def fetch_dialect(name, registry_url=DEFAULT_REGISTRY_URL):
|
|
48
|
+
"""Fetch a single dialect YAML from the remote registry and cache it."""
|
|
49
|
+
_ensure_user_dir()
|
|
50
|
+
url = f"{registry_url}/{name}.yaml"
|
|
51
|
+
content = _fetch_url(url)
|
|
52
|
+
cache_path = USER_DIR / f"{name}.yaml"
|
|
53
|
+
cache_path.write_text(content)
|
|
54
|
+
return cache_path
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def fetch_index(registry_url=DEFAULT_REGISTRY_URL):
|
|
58
|
+
"""Fetch the index of available remote dialects."""
|
|
59
|
+
url = f"{registry_url}/{INDEX_FILENAME}"
|
|
60
|
+
content = _fetch_url(url)
|
|
61
|
+
return [line.strip() for line in content.splitlines() if line.strip()]
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def update_dialects(registry_url=DEFAULT_REGISTRY_URL, force=False):
|
|
65
|
+
"""Fetch all remote dialects and update local cache.
|
|
66
|
+
|
|
67
|
+
Returns a list of (name, status) tuples where status is
|
|
68
|
+
'updated', 'cached', or 'error: ...'.
|
|
69
|
+
"""
|
|
70
|
+
_ensure_user_dir()
|
|
71
|
+
results = []
|
|
72
|
+
|
|
73
|
+
# Try to fetch index; if unavailable, fetch known dialect names
|
|
74
|
+
try:
|
|
75
|
+
dialect_names = fetch_index(registry_url)
|
|
76
|
+
except URLError:
|
|
77
|
+
# Fallback: try common names
|
|
78
|
+
dialect_names = ["lolcat", "gen_z", "brainrot"]
|
|
79
|
+
|
|
80
|
+
for name in dialect_names:
|
|
81
|
+
cache_path = USER_DIR / f"{name}.yaml"
|
|
82
|
+
if not force and _is_cache_fresh(cache_path):
|
|
83
|
+
results.append((name, "cached"))
|
|
84
|
+
continue
|
|
85
|
+
try:
|
|
86
|
+
fetch_dialect(name, registry_url)
|
|
87
|
+
results.append((name, "updated"))
|
|
88
|
+
except Exception as e:
|
|
89
|
+
results.append((name, f"error: {e}"))
|
|
90
|
+
|
|
91
|
+
return results
|