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)