86 lines
2.5 KiB
Python
86 lines
2.5 KiB
Python
from math import sin, cos, pi
|
|
from colorama import Fore,Back,Style
|
|
from time import sleep
|
|
from random import randint
|
|
import argparse
|
|
|
|
#command line arg stuff
|
|
desc="Displays an ASCII art strand of DNA, because why not?"
|
|
epi="""Protip: to watch an animated strand of ASCII DNA scroll across the screen,
|
|
set length to a really large number and pause to a reasonable number like 50
|
|
or 100 milliseconds. Enjoy!"""
|
|
parser=argparse.ArgumentParser(description=desc, epilog=epi)
|
|
parser.add_argument("-l", "--length", type=int, help="Changes the length of the ASCII DNA. Default = 40")
|
|
parser.add_argument("-p", "--pause", type=int, help="Number of milliseconds to pause after plotting each line. Default=0")
|
|
parser.add_argument("-b", "--block", action="store_true", help="Display using block characters instead of letters. Default=False")
|
|
args=parser.parse_args()
|
|
|
|
if args.length: length=args.length
|
|
else: length=40
|
|
|
|
if args.pause: pause=args.pause
|
|
else: pause=0
|
|
|
|
if args.block:
|
|
chars={"x":"█","a":"█","t":"█","g":"█","c":"█"}
|
|
else:
|
|
chars={"x":"X","a":"A","t":"T","g":"G","c":"C"}
|
|
|
|
#define and initialize stuff
|
|
class DnaStrand:
|
|
def __init__(self, char, func):
|
|
self.char=char
|
|
self.func=func
|
|
def pos(self,x):
|
|
return int(self.func(x))
|
|
def getchar(self): return self.char
|
|
|
|
width = 20
|
|
blank=[]
|
|
lin=[]
|
|
theta=0
|
|
basecount=2
|
|
step=pi/12
|
|
|
|
bluchar=Fore.BLUE+chars["x"]+Fore.WHITE
|
|
blustrand=DnaStrand(bluchar, lambda x: (width/2-1)*(sin(x)+1))
|
|
redchar=Fore.RED+chars["x"]+Fore.WHITE
|
|
redstrand=DnaStrand(redchar, lambda x: (width/2-1)*(cos(x)+1))
|
|
|
|
a=Fore.YELLOW+chars["a"]+Fore.WHITE
|
|
t=Fore.WHITE+chars["t"]+Fore.WHITE
|
|
g=Fore.GREEN+chars["g"]+Fore.WHITE
|
|
c=Fore.CYAN+chars["c"]+Fore.WHITE
|
|
msg="tilde.club"
|
|
for i in range (width):
|
|
blank.append(" ")
|
|
|
|
|
|
#Draw
|
|
for i in range(length):
|
|
lin=blank.copy()
|
|
blupos=blustrand.pos(theta)
|
|
redpos=redstrand.pos(theta)
|
|
lin[blupos]=blustrand.getchar()
|
|
lin[redpos]=redstrand.getchar()
|
|
|
|
if basecount%3==0 and abs(blupos-redpos) > 3:
|
|
bp=randint(1,4)
|
|
if bp==1:bp1,bp2=a,t
|
|
elif bp==2:bp1,bp2=t,a
|
|
elif bp==3:bp1,bp2=g,c
|
|
else:bp1,bp2=c,g
|
|
halfway=int(abs(blupos+redpos)/2)
|
|
start=min(redpos,blupos)+1
|
|
end=max(redpos,blupos)
|
|
lin[start:halfway]=[bp1]*abs(halfway-start)
|
|
lin[halfway:end]=[bp2]*abs(end-halfway)
|
|
tc=randint(1,5)
|
|
if tc==5 and end-start > len (msg):
|
|
lin[start:start+len(msg)]=list(msg)
|
|
|
|
print("".join(lin))
|
|
theta += step
|
|
basecount+=1
|
|
sleep(pause/1000)
|