250x250
Notice
Recent Posts
«   2024/07   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
관리 메뉴

일상 코딩

파이썬 압축 알고리즘 DNA 시퀀스를 이용한 압축 알고리즘 본문

Python/고전 컴퓨터 알고리즘

파이썬 압축 알고리즘 DNA 시퀀스를 이용한 압축 알고리즘

polarcompass 2021. 1. 30. 18:53
728x90
class CompressedGene:
    
    def __init__(self, gene: str) -> None:
        self._compress(gene) # "_"은 클래스 외부에서 사용되지 않게 하기 위한 비공개 처리 문구이다.
        
    def _compress(self, gene: str) -> None:
        self.bit_string: int = 1 # 1로 시작/ 유전코드를  2진수로 변환 후 저장할 변수.
        
        for nucleotide in gene.upper():
            self.bit_string <<= 2 # 왼쪽으로 2비트 시프트
            
            if nucleotide == "A":  # 마지막 2비트를 00 변경
                self.bit_string |= 0b00
                
            elif nucleotide == "C":
                self.bit_string |= 0b01
            
            elif nucleotide == "G":
                self.bit_string |= 0b10
            
            elif nucleotide == "T":
                self.bit_string |= 0b11
            
            else:
                raise ValueError("유효하지 않은 뉴클레오타이드 입니다 : {}".format(nucleotide))
    
    def decompress(self) -> str:
        gene: str = ""                
        
        for i in range( 0, self.bit_string.bit_length()-1, 2): # 1로 시작하므로 1을 빼준다.
            bits: int = self.bit_string >> i & 0b11 # 마지막 2비트를 추출한다.
            
            if bits == 0b00: # A
                gene += "A"
            
            elif bits == 0b01: # C
                gene += "C"
            
            elif bits == 0b10: # G
                gene += "G"
            
            elif bits == 0b11: # T
                gene += "T"
                
            else:
                raise ValueError("Invalid bits: {}".format(bits))
        return gene[::-1] # [::-1]은 문자열을 뒤집는다.
    
    def __str__(self) -> str: # 출력을 위한 문자열 표현
        return self.decompress()

if __name__ == '__main__':
    
    from sys import getsizeof
    
    original: str = "TAGGGATTAACCGTTATATATATATAGCCATGGATCGATTATATATAGGGATTAACCGTTATATATATATAGCCATGGAATCGATTATA"*100
    
    print("원본: {} 바이트".format(getsizeof(original))) # 원본: 8949 바이트
    
    compressed: CompressedGene = CompressedGene(original) # 압축
    
    print("압축: {} 바이트".format(getsizeof(compressed.bit_string))) # 압축: 2400 바이트
    
    print(compressed)
    
    print("원본 문자열과 압축 해제한 문자열은 같습니까? {}".format(original == compressed.decompress()))
    # 원본 문자열과 압축 해제한 문자열은 같습니까? True
    

UTF-8 형식으로 되어있는 문자열 DNA 시퀀스를 2진수 비트 형식으로 바꿔 압축하는 클래스이다.

뭔가 길어서 있어보이지만 자세히 살펴보면

if - elif - else 를 이용한 분기를 이용하여

A가 아노면 0b00 2진수로 바꿔주는 그런 경우이고 이를 4번씩 반복한 것이다.

기본적인 프로그램 문법이나 문제를 몇번 풀어봤다면

다 이해할 수 있는 부분이니 천천히 보면서 이해하면 쉬울 것이다.

사용한 라이브러리도 문자열의 크기를 구하는 getsizeof() 정도로 밖에 없어서 이해하기 쉽다.

728x90