barcode

RE with FLASK-Searcher 이식하기

Coding/Python

들어가기 전에 중요한 게 하나 있다. 

Cutter와 Finder도 내일 이식하긴 할건데, 내일 이식하는 부분에서 FASTA/Genbank 파일 올리는거랑 결과 저장 기능은 빠진다. 그래서 원본 코드에 있던 with 어쩌고를 일단 작성 없이 서버로 보내서 텍스트 에리어에서 출력하는 걸 일차적으로 진행하고 저장-업로드 순으로 할 예정. FASTA/Genbank는 JS로 파일 받아서 파이썬으로 넘겨서 열 생각인데 그거 관련해서 로직 처리가 좀 필요하고(뼈대를 보면 라디오 버튼이다) 반대로 텍스트 파일은 파이썬에서 만들어서 JS로 넘길 생각이다. 텍스트 파일은 만들어준 거 받아서 버튼 누르면 다운로드 되게 하면 끝임. 


대공사 전에... 

일단 공사 전인 Searcher의 뼈대를 보자. 

원래 코드에서 입력으로 받던 걸 죄다 라디오버튼으로 박아버렸다. JS파일의 임무는 일차적으로 

1) 사용자가 입력한 검색어와 
2) 라디오버튼의 값을 app.py(파이썬)으로 전달해주는 

것이다. 로직은 뒤에서 돌 거니까 JS는 

1) 로직을 돌리기 위해 필요한 변수들을 주고
2) 결과물을 받아서 출력한다 

그리고 인자와 결과물의 전달을 Ajax가 한다. (얘때문에 jQuery 들어간거지 저거 빼고 어지간한 기능은 다 바닐라JS다)

 

function searchFilter() {
    const search_method = document.getElementsByName('search_val');
    console.log(search_method)
}

일단 이렇게 하면 값은 나오는데 문제는 뭐냐... 라디오버튼 중 선택된 값만 넘겨야 한다. 

 

function searchFilter() {
    const search_method = document.getElementsByName('search_val');
    for (let i = 0;i < search_method.length;i++) {
        if (search_method[i].checked == true) {
            console.log(search_method[i].value)
        }
    }
}

그러니까 이 if를 세 개 줘야 한다. 

 

function searchFilter() {
    const search_method = document.getElementsByName('search_val');
    const NEB_filter = document.getElementsByName('option_NEB');
    const cut_filter = document.getElementsByName('option_cut');

    for (let i = 0;i < search_method.length;i++) {
        if (search_method[i].checked == true) {
            console.log(search_method[i].value);
        }
    }
    for (let i = 0;i < NEB_filter.length;i++){
        if (NEB_filter[i].checked == true) {
            console.log(NEB_filter[i].value);
        }
    }
    for (let i = 0;i < cut_filter.length;i++){
        if (cut_filter[i].checked == true) {
            console.log(cut_filter[i].value)
        }
    }
}

왜 for+if가 3개인지 궁금하신 분들은 뼈대를 다시 보고 옵시다. 아무튼 그럼 Ajax를 불러보자. 

 

let search_method_val = '';
let NEB_filter_val = '';
let cut_filter_val = '';
function searchFilter() {
    const search_method = document.getElementsByName('search_val');
    const NEB_filter = document.getElementsByName('option_NEB');
    const cut_filter = document.getElementsByName('option_cut');

    for (let i = 0; i < search_method.length; i++) {
        if (search_method[i].checked == true) {
            search_method_val = search_method[i].value;
        }
    }
    for (let i = 0; i < NEB_filter.length; i++) {
        if (NEB_filter[i].checked == true) {
            NEB_filter_val = NEB_filter[i].value;
        }
    }
    for (let i = 0; i < cut_filter.length; i++) {
        if (cut_filter[i].checked == true) {
            cut_filter_val = cut_filter[i].value
        }
    }
    $.ajax({
    type: "POST",
    url: "/searcher",
    data: {NEB_give: NEB_filter_val, cut_give: cut_filter_val, search_give: search_method_val},
    success: function (response) {
        alert(response['msg'])
    }
})
}

여기다가 변수 하나만 추가하면 텍스트도 같이 넘길 수 있다. 

 

@app.route('/searcher', methods=['POST'])
def searcher():
    NEB_receive = request.form['NEB_give']
    cut_receive = request.form['cut_give']
    search_receive = request.form['search_give']
    message = '{},{},{}'.format(NEB_receive,cut_receive,search_receive)
    return jsonify({'msg': message})

그리고 받아오면 된다. 

 

로직의 변경점

위에서 기존 코드로 입력받던 것들을 라디오버튼으로 바꿨다고 했는데, 그거 말고도 변경점이 하나 더 있다. 원래 코드에서는 print문으로 출력해줬지만, 쟤는 app.py에서 다 만들고 나면 결과를 다시 JS에게 넘겨줘야 한다. 그러니까 단순히 print문으로 되어있던 걸 처리하는 과정이 필요하다.

 

@app.route('/searcher', methods=['POST'])
def searcher():
    enzyme_table = pd.read_csv('/home/koreanraichu/restriction_merge.csv')
    NEB_receive = request.form['NEB_give']
    cut_receive = request.form['cut_give']
    search_receive = request.form['search_give']
    keywd_receive = request.form['keywd_give']

    def SeqtoString(a):
        a = enzyme_table.sequence[(enzyme_table['Enzyme'] == keywd_receive)]
        a = a.to_string(index=False)
        a = str(a).strip()
        return a

    def SitetoString(a):
        a = enzyme_table.restriction_site[(enzyme_table['Enzyme'] == keywd_receive)]
        a = a.to_string(index=False)
        a = str(a).strip()
        return a

    def NEB_selling(a):
        a = enzyme_table.NEB_sell[(enzyme_table['Enzyme'] == keywd_receive)]
        a = a.to_string(index=False)
        a = str(a).strip()
        return a

    # 함수 가즈아!!!

    if cut_receive == 'sticky':
        enzyme_table = enzyme_table[enzyme_table['cut_feature'] == 'Sticky']
        enzyme_table.reset_index(inplace=True)
        cut_feature = 'Sticky end'
    elif cut_receive == 'blunt':
        enzyme_table = enzyme_table[enzyme_table['cut_feature'] == 'Blunt']
        enzyme_table.reset_index(inplace=True)
        cut_feature = 'Blunt end'
    elif cut_receive == 'nicked':
        enzyme_table = enzyme_table[enzyme_table['cut_feature'] == 'Nicked']
        enzyme_table.reset_index(inplace=True)
        cut_feature = "Nicked"
    else:
        cut_feature = "W/O filter"
        pass
    if NEB_receive == 'NEB':
        enzyme_table = enzyme_table[enzyme_table['NEB_sell'] == 'Yes']
        enzyme_table.reset_index(inplace=True)
        NEB_filter = 'NEB only'
    else:
        NEB_filter = 'All'
        pass
    if search_receive == 'name':
        pass
    elif search_receive == 'sequence':
        pass
    else:
        pass
    return jsonify({'msg': '입력되었습니다!'})

근데 함수 그냥 이렇게 써도 됨? 

아무튼 그래서... print문을 전부 텍스트로 할당했다. 

@app.route('/searcher', methods=['POST'])
def searcher():
    enzyme_table = pd.read_csv('/home/koreanraichu/restriction_merge.csv')
    NEB_receive = request.form['NEB_give']
    cut_receive = request.form['cut_give']
    search_receive = request.form['search_give']
    keyword_receive = request.form['keyword_give']

    def SeqtoString(a):
        a = enzyme_table.sequence[(enzyme_table['Enzyme'] == keyword_receive)]
        a = a.to_string(index=False)
        a = str(a).strip()
        return a

    def SitetoString(a):
        a = enzyme_table.restriction_site[(enzyme_table['Enzyme'] == keyword_receive)]
        a = a.to_string(index=False)
        a = str(a).strip()
        return a

    def NEB_selling(a):
        a = enzyme_table.NEB_sell[(enzyme_table['Enzyme'] == keyword_receive)]
        a = a.to_string(index=False)
        a = str(a).strip()
        return a

    # 함수 가즈아!!!

    if cut_receive == 'sticky':
        enzyme_table = enzyme_table[enzyme_table['cut_feature'] == 'Sticky']
        enzyme_table.reset_index(inplace=True)
        cut_feature = 'Sticky end'
    elif cut_receive == 'blunt':
        enzyme_table = enzyme_table[enzyme_table['cut_feature'] == 'Blunt']
        enzyme_table.reset_index(inplace=True)
        cut_feature = 'Blunt end'
    elif cut_receive == 'nicked':
        enzyme_table = enzyme_table[enzyme_table['cut_feature'] == 'Nicked']
        enzyme_table.reset_index(inplace=True)
        cut_feature = "Nicked"
    else:
        cut_feature = "W/O filter"
        pass
    if NEB_receive == 'NEB':
        enzyme_table = enzyme_table[enzyme_table['NEB_sell'] == 'Yes']
        enzyme_table.reset_index(inplace=True)
        NEB_filter = 'NEB only'
    else:
        NEB_filter = 'All'
        pass

    if search_receive == 'name':
        find_seq = SeqtoString(keyword_receive)
        Site_seq = SitetoString(keyword_receive)
        NEB_sell = NEB_selling(keyword_receive)
        result_iso = ''
        result_neo = ''
        result_iso_list = []
        result_neo_list = []
        Iso = []
        Neo = []
        message_give =  "{0} | {1} | {2} | {3} | Input enzyme".format(keyword_receive, find_seq, Site_seq, NEB_sell)
        for i in range(len(enzyme_table)):
            DB_enzyme = str(enzyme_table['Enzyme'][i]).strip()
            DB_seq = str(enzyme_table['sequence'][i]).strip().upper()
            DB_site = str(enzyme_table['restriction_site'][i]).strip().upper()
            if find_seq == str(DB_seq) and DB_enzyme != keyword_receive:
                if Site_seq == DB_site:
                    Iso.append(DB_enzyme)
                    result_iso = "{0} | {1} | {2} | {3} | Isoschizomer".format(DB_enzyme, DB_seq, DB_site,
                                                                                   NEB_sell)
                    result_iso_list.append(result_iso)

                    # 인식하는 시퀀스와 자르는 방식이 같은 제한효소
                elif Site_seq != DB_site:
                    Neo.append(DB_enzyme)
                    result_neo = "{0} | {1} | {2} | {3} | Neoschizomer".format(DB_enzyme, DB_seq, DB_site,
                                                                                   NEB_sell)
                    result_neo_list.append(result_neo)
                    # 인식하는 시퀀스는 같으나 자르는 방식이 다른 제한효소
            elif find_seq == str(DB_seq) and DB_enzyme == keyword_receive:
                pass
            else:
                pass
    elif search_receive == 'sequence':
        find_seq = keyword_receive
        message_give = ("Searched by: {0}".format(keyword_receive))
        for i in range(len(enzyme_table)):
            DB_enzyme = str(enzyme_table['Enzyme'][i]).strip()
            DB_seq = str(enzyme_table['sequence'][i]).strip().upper()
            DB_site = str(enzyme_table['restriction_site'][i]).strip().upper()
            DB_NEB = str(str(enzyme_table['NEB_sell'][i]).strip())
            if find_seq == DB_seq:
                print("{0} | {1} | {2} | {3}".format(DB_enzyme, DB_seq, DB_site, DB_NEB))
        else:
            enzyme_RE = keyword_receive
            enzyme_RE = enzyme_RE.upper()
            enzyme_RE_2 = '^' + enzyme_RE
            message_give = ("Enzyme with start with {0}".format(enzyme_RE))
            for i in range(len(enzyme_table)):
                DB_enzyme = str(enzyme_table['Enzyme'][i]).strip()
                DB_seq = str(enzyme_table['sequence'][i]).strip().upper()
                DB_site = str(enzyme_table['restriction_site'][i]).strip().upper()
                DB_NEB = str(str(enzyme_table['NEB_sell'][i]).strip())
                if re.search(enzyme_RE_2, DB_enzyme):
                    print("{0} | {1} | {2} | {3}".format(DB_enzyme, DB_seq, DB_site, DB_NEB))
    return jsonify({'Message_give': message_give,'Result_iso':result_iso_list,'Result_neo':result_neo_list})

이건데(일단 이름 검색만 됨) 여기서 

if search_receive == 'name':
    find_seq = SeqtoString(keyword_receive)
    Site_seq = SitetoString(keyword_receive)
    NEB_sell = NEB_selling(keyword_receive)
    result_iso = ''
    result_neo = ''
    result_iso_list = []
    result_neo_list = []
    Iso = []
    Neo = []
    message_give =  "{0} | {1} | {2} | {3} | Input enzyme".format(keyword_receive, find_seq, Site_seq, NEB_sell)
    for i in range(len(enzyme_table)):
        DB_enzyme = str(enzyme_table['Enzyme'][i]).strip()
        DB_seq = str(enzyme_table['sequence'][i]).strip().upper()
        DB_site = str(enzyme_table['restriction_site'][i]).strip().upper()
        if find_seq == str(DB_seq) and DB_enzyme != keyword_receive:
            if Site_seq == DB_site:
                Iso.append(DB_enzyme)
                result_iso = "{0} | {1} | {2} | {3} | Isoschizomer".format(DB_enzyme, DB_seq, DB_site,
                                                                               NEB_sell)
                result_iso_list.append(result_iso)

                # 인식하는 시퀀스와 자르는 방식이 같은 제한효소
            elif Site_seq != DB_site:
                Neo.append(DB_enzyme)
                result_neo = "{0} | {1} | {2} | {3} | Neoschizomer".format(DB_enzyme, DB_seq, DB_site,
                                                                               NEB_sell)
                result_neo_list.append(result_neo)
                # 인식하는 시퀀스는 같으나 자르는 방식이 다른 제한효소

이 부분을 다시 보다. print문이 있어야 할 곳에 메세지, 리절트 이런 변수들이 있다. 왜 이렇게 했나고? 

return jsonify({'Message_give': message_give,'Result_iso':result_iso_list,'Result_neo':result_neo_list})

얘때문임. Ajax로 다시 JS로 보내려면 JSON파일로 만들어야 하거든… 그래서 결과를 딕셔너리로 만든 다름 JSON으로 넘길거다. 

 

success : function (response) {
    var message = response['Message_give']
    var iso = response['Result_iso']
    var neo = response['Result_neo']
    let result = document.getElementById('search_result');
    result.innerText = message;
    for (let i = 0; i < iso.length; i++) {
        console.log(iso[i])
        result.innerText = iso[i]
    }
    for (let i = 0; i < neo.length; i++) {
        console.log(neo[i])
        result.innerText = neo[i]
    }
}

근데 여기서 줄바꿈 안돼서 진짜 온갖가지 것들을 다 해봤음... 근데 이스케이프 문자 안먹지 백틱 안먹지 뭐 어쩌라는건지...ㅡㅡ 

 

success : function (response) {
    if (search_method_val == 'name') {
        let message = response['doc_result']['Message_give'];
        let iso = response['doc_result']['Result_iso'];
        let neo = response['doc_result']['Result_neo'];
        let result = document.getElementById('search_result');
        result.innerHTML = message;
        for (let i = 0; i < iso.length; i++) {
            result.innerHTML = result.innerHTML.concat("\n", iso[i])
        }
        for (let i = 0; i < neo.length; i++) {
            result.innerHTML = result.innerHTML.concat("\n", neo[i])
        }
    } else if (search_method_val == 'sequence') {
        let message = response['doc_result']['Message_give'];
        let same_seq = response['doc_result']['Result_seq'];
        let result = document.getElementById('search_result');
        result.innerHTML = message;
        for (let i = 0; i < same_seq.length; i++) {
            result.innerHTML = result.innerHTML.concat("\n", same_seq[i])
        }
    } else {
        let message = response['doc_result']['Message_give'];
        let spell = response['doc_result']['Result_spell'];
        let result = document.getElementById('search_result');
        result.innerHTML = message;
        for (let i = 0; i < spell.length; i++) {
            result.innerHTML = result.innerHTML.concat("\n", spell[i])
        }
    }
}

는 지나가던 분의 .concat()신공과 가만 이거 innerText말고 inner HTML도 있잖아?로 해⭐결! 

 

그래서 완성품

이름으로 검색
시퀀스로 검색
그 뭐더라 X로 시작하는 효소

 

이후 추가할 기능

검색어 없을 때 멘트랑 검색 방법별 도움말정도? 

'Coding > Python' 카테고리의 다른 글

RE with FLASK-시퀀스 정보  (0) 2022.08.23
RE with FLASK-Cutter/Finder  (0) 2022.08.22
RE with FLASK-뼈대 대공사  (0) 2022.08.22
Wordcloud with FLASK-뼈대 대공사 (3)  (0) 2022.08.22
경로때문에 개노가다 한 썰 푼다  (0) 2022.08.22