(83)

판다스 없이 표 만들기

공부 예… 기출문제 37개 풀어서 7개틀림……근데 아직 R은 시작도 안했어... 심지어 통계학도 있어... 수업시간에 자지 말걸... 죄송합니다 교수님... 오전수업이라 졸렸어요......일단 저 제목이 뭔 개소린가 싶어서 들어오셨다고요? 말 그대로 파이썬에서 판다스 없이 표를 만드는 게 가능한지 지피티한테 물어봤음. 아니 그럼 왜 이런 걸 해보시는거예요? 그 예전에 내가 Biopython 없이 전사번역 올렸던거 기억하시죠? 그때 내가 Biplython을 설치해야 하기도 하고, 이게 깔아도 VScode에서 안된다고 했잖아요. 근데 판다스도 쓸라면 깔아야됩니다. 리눅스는 터미널에 치면 깔리는데 윈도우는 pip 찾아가서 pip install 쳐야 깔리더라 심지어… 그래서 물어본겁니다. 방법 1: 리스트 안..

전사/번역을 Biopython 없이 해보자

이걸 왜 하냐... Biopython 깔면 장땡 아니냐... 변환해주는 툴 있지 않냐... 하시는데 변환해주는 툴은 인터넷이 안되면 못 쓰고, Biopython은 VScode에서 안된다. 일단 리눅스에서는 spyder랑 pycharm에서만 정상적으로 인식했다.전사DNA를 인트론 자르고 mRNA로 만드는 과정이다. 그리고 RNA가 DNA와 다른 점은 티민 대신 우라실(U)이 들어간다는 점. 그래서 ATGC->AUGC로 바꾸기만 하면 된다. def transcription(text) : pass우리는 찍어낸다 함수. 원래는 파일을 따로 하려고 했는데 아니 이게… 씁… 전사가 너무 간단함. def transcription(text) : text = text.replace('T','U') ret..

Matplotlib으로 정규분포를 그려보자

R에서 그래프 그릴 때 가끔 예제로 나오는게 정규분포다. 그 종같이 생긴 그거 말하는 거 맞습니다. 그래서 이걸 Matplotlib으로 그려봅시다. Referencehttps://bigdata-doctrine.tistory.com/14 [Python] 정규분포 그래프 시각화오늘은 정규분포 그래프를 matplotlib을 사용하여 시각화해보겠습니다. 정규분포의 사전적 정의는 다음과 같습니다. 도수(度數) 분포 곡선이 평균값을 중앙으로 하여 좌우 대칭으로 종 모양을 이bigdata-doctrine.tistory.com그 전에 Matplotlib으로 그래프 그리는 걸 하셨으면 Matplotlib랑 Numpy, Pandas는 설치하셨을텐데 오늘은 Scipy도 같이 설치해야 한다. 네, 깔고 오십시오. pip in..

Matplotlib으로 그래프를 그려보자 (2)

https://koreanraichu.tistory.com/431 Matplotlib으로 그래프를 그려보자일단 이번에는 VScode가 아닌 다른 걸 켜볼건데… 바로 Jupyter이다. 얘가 칸단위로 처리할 수 있어서 개편합니다. 그래서 Jupyter, Numpy, Pandas, Matplotlib까지 설치하고 오시면 됩니다.impkoreanraichu.tistory.com자 우리 저번시간에는 matplotlib으로 꺾은선 그래프를 그렸는데… 아니 사인함수 그렸잖아요… 아무튼, 이번에는 csv파일을 불러온 다음 그걸로 막대그래프를 그려보자. 왜 csv냐면 이거 리눅스로 쓰고 있음.  일단 이 CSV파일을 받아주시면 된다. 참고로 저거 동물의숲 무트코인임... raddish=pd.read_csv("./rad..

Matplotlib으로 그래프를 그려보자

일단 이번에는 VScode가 아닌 다른 걸 켜볼건데… 바로 Jupyter이다. 얘가 칸단위로 처리할 수 있어서 개편합니다. 그래서 Jupyter, Numpy, Pandas, Matplotlib까지 설치하고 오시면 됩니다.import numpy as npimport pandas as pdimport matplotlib.pyplot as plot다 불러오면 된다. Jupyter는 이렇게 하고 Ctrl+Enter만 누르면 만사 오케이다. x = np.linspace(0,10,1000)fig, ax = plot.subplots()ax.plot(x, np.sin(x))plot.show()linspace는 넘파이에 있는건데, 저게 무슨 뜻이냐면 1) 0부터 2) 10까지 3) 간격 1000으로 나눠달라 는 얘기다...

배수 판별을 해보자

왜 우리 초딩때 배웠던 배수 판별법 있죠? 짝수면 2의 배수, 끝자리가 5나 0이면 5의 배수, 자릿수 다 더해서 3의 배수이면 3의 배수 뭐 이런거. 그걸 해 볼거다. 솔직히 배수 판별이라고 해서 엥 그거 걍 나눠서 나머지 없으면 배수 아니냐 했던 분들 반성하십쇼. 그런 심플한거나 하겠답시고 내가 여기다 올리겠수? https://ko.wikipedia.org/wiki/%EB%B0%B0%EC%88%98_%ED%8C%90%EC%A0%95%EB%B2%95 배수 판정법 - 위키백과, 우리 모두의 백과사전 위키백과, 우리 모두의 백과사전. 배수 판정법은 배수인지 확인하려는 수의 배수가 맞는지 간단히 확인하는 절차이다. 일반적으로 정수 m , n {\displaystyle m,n} 에 대해 m {\displays..

구구단을 이차원 배열로 출력해보자

아오 티스토리에 왜이렇게 뻘댓글이 많은지… ㅡㅡ 심지어 내가 달지 말고 걍 가라했는데도 계속 달아서 티스토리도 스팸필터 달고 있음… 네이버는 한줄+답글이지만 티스토리는 한명이 서너개 두두두두 달고 갑니다. 하지 말라면 좀 하지 말라고… 생각해봅시다. 반복문 하면서 제일 만만한게 구구단인데, 이거 보통 for i in range(2,10): for j in range(2,10): print('{} * {} = {}'.format(i, j, i * j)) 이렇게 하잖아요? 그래서 저거 실행하면 2 * 2 = 4 이런 식으로 줄줄이 뜨잖음. 그러니까, 한 줄로요. 이걸 이차원 배열... 그러니까 표로 출력할거다. 상당히 간단한 절차이니 걍 보고 따라해보자. gugudan_array = [['*' for i i..

현재 시각을 십이지시로 바꿔보자

요즘은 뭐 열두시 한시 이런 식으로 얘기해서 십이지시 잘 모르는 사람도 많다. 사실 이거 쓰는거 사주 볼 때 말고는 없는데, 뭐 개인이 보는 경우도 있지만 가끔 남녀가 결혼하기 전에 궁합이 어떤지 볼 때도 태어난 년월일'시'가 필요할 때가 있다. 근데 딱히 그래서 코딩해본 건 아님. 참고로 일본 괴담 번역 즐겨보시는 분들 한번 접해봤을 키워드인 축시의 참배 할 때 축시도 십이지시다. 그래서 이게 대충 몇시인가요? 여기서 시간만 보면 된다. 참고로 1시 정각이 그래서 자시인지 축시인지는 안 나오는 관계로 편의상 n시 정각~n시 59분으로 코딩하도록 하겠음. 와 이래 보니 축시가 꼭두새벽이었네... 그럼 꼭두새벽에 누구 저주한답시고 나무에 못박고 그러는거임? 후덜덜하구만. 여담이지만 자시와 오시는 자정, 정..

파이썬으로 만나이를 계산해보자

아니 이게요... 일하는데 어떤 분이 엑셀로 생년월일 입력하면 만나이 계산 알아서 되는 방법이 있다던데 함수좀 짜달라길래... 속으로 오 씨 콘텐츠 각 이러면서 짰습니다... 이걸 각을 재네 나중에 JS랑 엑셀로도 할거고 하게 되면 또 올리겠음. 참고로 엑셀은 미디움에는 안 올라갑니다. 원래 미디움에는 잔머리엑셀 연재 안했음. 일단 만 나이가 뭐냐... 한국인은 나이가 두 개인데 첫번째가 해가 지나가면(1월 1일 되면) +1씩 더해지는 세는 나이고 두번째가 본인 생일이 지나야 올라가는 만나이이다. 보통 사람들하고 교류할때는 세는 나이를 말하고 행정 처리(예를 들자면 교통카드 요금이 청소년->성인으로 올라가는 것) 할 때는 만 나이로 들어가는데, 본인은 91년생이기때문에 세는 나이로는 34살이지만 아직 생..

나눗셈 결과 몫 ... 나머지로 표시하기

이거 참고로 노션에는 기록을 못한다... 차마 기록할 페이지를 어디다 만들어야 할 지 모르겠음... ㅋㅋㅋㅋㅋ 문방구 오락기에서 게임하다가 엄마한테 등짝맞던 시절... 아니 그니까 초딩때를 이야기하는거다. 아무튼, 우리가 나눗셈을 처음 배웠을 때 6 나누기 4는 몫이 1이고 나머지가 2라 1 ... 2 이런 식으로 표현했다. 근데 콤퓨타는 기본적으로 몫과 나머지따원 모르겠고 난 소수점으로 쫑낼것이다! 모드란 말이죠. 그니까 응애 애기피츄 책사죠 하던 시절의 그 나눗셈을 해보자 이겁니다. 뭘로? 파이썬으로. 왜 피츄인지는 내 닉네임을 보면 납득할 수 있을것이다. 본인이 라이츄기 때문에 유년기가 피츄인거다. 일단 나눗셈의 용어에 대해 알고 가도록 하자. 나눗셈 하면 피제수와 제수라는 두 개의 용어가 있는데(..

Python으로 연결 리스트 구현하기

https://koreanraichu.tistory.com/311 연결 리스트 JS는 토이프로젝트 해야 하는데 뭐 또 생각나면 만들겠음... 솔직히 프론트엔드가 쓸 일은 없겠지만 알아서 나쁠거 없잖아요? 아무튼. 배열은 만들 때 메모리 공간의 연속된 공간을 할당받는다. koreanraichu.tistory.com 여기서는 대충 이론적인 설명(...)을 했다면 이제 만들어보자. 이게 왜 분리가 됐냐면 티스토리와 워드프레스는 이론 카테고리와 코딩 카테고리가 나뉘어져 있다. 오늘의 참고문헌은 https://velog.io/@yeseolee/python-%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-%EC%97%B0%EA%B2%B0%EB%A6%AC%EC%8A%A4%ED%8A%B8Linked-..

enumerate에 대해 알아보자

enumerate는 해시 테이블을 만들어보는 과정에서 나왔던건데, 반복문 뺑뺑이 도는 역할을 한다. 근데 이제 for문 하면 빠질 수 없는 for i in 아무개 없이 할 수 있다. import sys text = sys.stdin.readline().rstrip() for i in text: print(i) 텍스트를 입력받아서 한글자씩 출력하는 코드. for문은 이렇게 쓴다. 이건 직접 글자에 접근해서 print(i)로 출력했지만 보통은 for i in range(len(text))로 주고 print문을 작성하게 된다. 그거 말고도 가끔 그럴때 있잖음. 인덱스랑 같이 뽑고 싶잖아요? 그러면 어떻게 하냐... import sys text = sys.stdin.readline().rstrip() j = 0..

zip이란 무엇인가

요전에 해시 테이블 할 때 나왔던건데, zip이 뭔지 한번 알아보는 시간을 가져보자. enu뭐시기도 나중에 알아볼거니까 안심하시고. molecule_name = ["Ethanol", "Glucose", "Methanol"] molecule_formula = ["C2H5OH", "C6H12O6", "CH3OH"] 여기 길이 3인 1차원 배열 두 개가 있다. 이 배열 두 개를 하나로 묶고 싶은데 그럼 어떻게 하나요? molecular_list = zip(molecule_name,molecule_formula) for i in molecular_list: print(i) zip()으로 묶어주면 알아서 튜플로 변환해준다. molecule_name = ["Ethanol", "Glucose", "Methanol",..

Python으로 해시 테이블 만들어보기

https://koreanraichu.tistory.com/289 해시 테이블 처음 설명을 본 본인 표정: 그럴만 했다. 뭔 소린지 1도 모르겠거든... 일단 얘는 자료구조다. 이름이 테이블인데 왜 자료구조인지는 주변에 계신 개발자에게 물어보도록. 아무튼 이 테이블은 데 koreanraichu.tistory.com 여기서 이어진다. 솔직히 이론적인거 백날 설명해봐야 뭔 소린지 모르잖음? 그니까 같이 만들어봅시다. 참고로 이번에 참고한 곳은 https://wikidocs.net/193049 06. 파이썬으로 해시 테이블 구현하기 해시 테이블은 언어에 따라 해시 맵, 사전 등으로 부른다. 해시 테이블은 키(key)와 값(value)으로 구성된 자료 구조다. 여기서 중요한 것은 해시함수다. 키를 해시함수에 …..

Python의 예외처리

예외처리... 쉽게 설명하자면 에러가 떴을 때 어떻게 할 지 코딩하는거라고 보면 된다. 예를 들어서 웹서핑을 하다 보면 보이는 이런게 있는데 대충 이런거. 404 뜨면 404 페이지를 띄우시오 이런 느낌이라고 보면 된다. 당연한 얘기지만 자바스크립트에도 예외처리가 있다. 나중에 함 다뤄보겠음. 나무위키의 정의에 따르면 예외처리는 '예외 처리(Exception Handling) 혹은 오류 처리(Trouble Shooting)란 실행 흐름상 오류가 발생했을 때 오류를 그대로 실행시키지 않고 오류에 대응하는 방법을 제시하는 개념이나 하드웨어 구조를 의미한다. 일반적으로 프로그래밍에서 프로그램이 실행 중 특정 문제가 발생했을 때 다른 처리 방식으로 흐름을 옮기는 개념으로 사용한다.'라고 한다. 예를 들어서 계산..

판다스 없이 표 만들기

Coding/Python 2025. 9. 27. 02:36

공부 예… 


기출문제 37개 풀어서 7개틀림……

근데 아직 R은 시작도 안했어... 심지어 통계학도 있어... 

 

수업시간에 자지 말걸... 죄송합니다 교수님... 오전수업이라 졸렸어요......


일단 저 제목이 뭔 개소린가 싶어서 들어오셨다고요? 말 그대로 파이썬에서 판다스 없이 표를 만드는 게 가능한지 지피티한테 물어봤음. 아니 그럼 왜 이런 걸 해보시는거예요? 그 예전에 내가 Biopython 없이 전사번역 올렸던거 기억하시죠? 그때 내가 Biplython을 설치해야 하기도 하고, 이게 깔아도 VScode에서 안된다고 했잖아요. 근데 판다스도 쓸라면 깔아야됩니다. 리눅스는 터미널에 치면 깔리는데 윈도우는 pip 찾아가서 pip install 쳐야 깔리더라 심지어…

 

그래서 물어본겁니다.

 

방법 1: 리스트 안의 리스트

table = [
    ['피카츄', '에몽가', '빠르모트'], 
    ['이상해씨', '소미안', '냄새꼬'], 
    ['꾸왁스', '발챙이', '물짱이'], 
    ['파이리', '에이스번', '폭거북스']
]

그니까 이거 말하는거다. 근데 이건 걍 이차원 배열 아님?

 

for i in table: 
    print(i)

걍 이렇게 뽑으면 저 리스트가 그대로 나오니까

 

for i in table: 
    print(*i)

대괄호 빼고 깔끔하게 뽑고 싶으면 이런식으로 언패킹하던가 텍스트 조인하던가 해야됨.

 

언패킹하면서 구분자도 같이 줬다.

 

방법 2: 딕셔너리로 뽑기

table = [
    {'이름':'미라이돈', '도감번호':'1008', '분류':'패러독스 포켓몬'},
    {'이름':'코라이돈', '도감번호':'1007', '분류':'패러독스 포켓몬'},
    {'이름':'복숭악동', '도감번호':'1025', '분류':'환상의 포켓몬'},
    {'이름':'테라파고스', '도감번호':'1024', '분류':'전설의 포켓몬'}
]

이건 근데... 겉에만 대괄호지 JSON 아니냐... 아무튼 얘도 걍 for문 쓰면 딕셔너리가 그대로 나온다. 그럼 어떻게 해요?

 

for i in table: 
    print(i['이름'], i['도감번호'], i['분류'])

키값 픽하셔야죠. 저게 근데 웃긴게 코라이돈이랑 미라이돈이랑 분류 밸류가 겹치잖아요? 그래서 분류까지 같이 뽑았더니 어떻게 됐냐면

 

미쳤습니까 휴먼이 날 반김.

 

방법 3: 딕셔너리 안에 리스트

이게 뭔 소리인가 궁금하시죠? 

table = {
    '타입':['전기/격투', '고스트/페어리', '에스퍼/페어리', '격투/페어리'],
    '이름':['무쇠손','날개치는머리','사나운꼬리','무쇠무인'],
    '출현하는 버전':['바이올렛','스칼렛','스칼렛','바이올렛']
    }

괄호를 잘 보면 방법 1, 2는 바깥이 대괄호(네모난거)였는데 얘는 바깥이 중괄호고 딕셔너리 키값이랑 묶인 밸류가 1차원 배열이다. 그럼 얘는 어떻게 뽑냐고?

 

print(*table['이름'], *table['타입'], *table['출현하는 버전'])

이렇게 뽑으면 되긴 한데, 방법 1이랑 방법 2에 비해 뽑았을때 안이쁘다. 4*3으로 뜨는 게 아니라 걍 길쭉하게 뜸.

 

방법 4: 선까지 뽑고 싶다면

def drawing_table(data): 
    col_width = [max(len(str(row[i])) for row in data) for i in range(len(data[0]))]

    def draw_line(sep="+",fill="-"):
        return sep + sep.join(fill * (w + 2) for w in col_width) + sep
    
    print(draw_line) # 맨 위 줄

    for i, row in enumerate(data):
        row_str = "| " + " | ".join(str(row[j]).ljust(col_width[j]) for j in range(len(row))) + " |"
        print(row_str)

        if i == 0:
            print(draw_line())

    print(draw_line())

table = [
    ['열1','열2','열3','열4'],
    ['피카츄','라이츄','파이리','꼬부기'],
    ['버터플','야도란','피죤투','또가스'],
    ['잠만보','망나뇽','질퍽이','탕구리'],
    ['고오스','왕구리','메탕구','오거폰']
]

drawing_table(table)

근데 얘는 왜 잘하다가 막줄에 줄 긋는걸 전역으로 빼버렸냐… 내가 뭔가 이상해서 함수 안으로 다시 넣긴 했음.

 

저 표가 지금 제목 말고 다른건 다 일정해서 그런데, ljust가 적용되어 있으면 왼쪽정렬 하고 남는 글자만큼을 뭘로 채운다. 저기 몇 개3글자가 아닌 걸로 바꿔보면

 

3번째 열이랑 4번째 열에 ljust가 적용돼서 왼쪽정렬이 된 것을 볼 수 있다. 

 

저 줄에 긋는 하이픈 개수는 col_width로 정하는건데 그 열에서 제일 긴 글자수가 기준이 된다. 그래서 3열은 하이픈이 7개 그어져 있는데… 저게 한글하고 하이픈하고 바이트가 달라서 선 수축됐음…

 

결론: 예쁘게 뽑고 싶으면 걍 판다스 까십쇼 그게 아니지 

Lv. 35 라이츄

Lv. 35 라이츄

광고 매크로 없는 청정한 블로그를 위해 노력중입니다. 근데 나만 노력하는 것 같음… ㅡㅡ

전사/번역을 Biopython 없이 해보자

Coding/Python 2025. 9. 10. 23:31

이걸 왜 하냐... Biopython 깔면 장땡 아니냐... 변환해주는 툴 있지 않냐... 하시는데 변환해주는 툴은 인터넷이 안되면 못 쓰고, Biopython은 VScode에서 안된다. 일단 리눅스에서는 spyder랑 pycharm에서만 정상적으로 인식했다.


전사

DNA를 인트론 자르고 mRNA로 만드는 과정이다. 그리고 RNA가 DNA와 다른 점은 티민 대신 우라실(U)이 들어간다는 점. 그래서 ATGC->AUGC로 바꾸기만 하면 된다.

 

def transcription(text) :
    pass

우리는 찍어낸다 함수. 원래는 파일을 따로 하려고 했는데 아니 이게… 씁… 전사가 너무 간단함.

 

def transcription(text) :
    text = text.replace('T','U')
    return text

sequence = input('DNA 시퀀스를 입력해주세요: ')
sequence = sequence.upper()

print(transcription(sequence))

위에도 썼지만 전사는 T(티민)를 U(우라실)로 바꾸기만 하면 된다. 진짜로 그게 다다. 문제는 번역이지…

 

번역

번역이 왜 문제임? 을 설명하려면 이 표가 필요하다.

 

이건 코돈 테이블이라는 거다. 당신이 이 글을 읽는 시간에도 리보솜에서 mRNA를 해독하고 아미노산 호출해서 단백질 만들 때 이 테이블대로 만들어서 지지고 볶고 PTM까지 조지는 과정을 거치는데... 으악 이게 뭐예요? 왼쪽에 있는 세 글자가 mRNA의 염기 세 개다. 그러니까 구아닌 시토신 시토신은 알라닌이라는 아미노산을 지정한다 이 얘기. 이건 생물종별로 코돈이 다르긴 한데 보통은 사람 코돈으로 하니까 그것까진 걱정 안 하셔도 됨.

 

여기서 뭐가 문제인지 깨달은 분도 계실 것이다. 그렇다. 여기서 문제는 전사와 달리 번역을 할 때는 알파벳 세 개를 찝어다가 저 표에서 맞는 아미노산을 골라야 한다는 거다. 한 아미노산에 대해서 여러가지 코돈이 대응하는 경우는 있지만, 번역하는 데 있어서 그건 문제가 안된다. 우리는 염기를 3개씩 묶어서 할 거지 아미노산으로 염기 찾는 걸 하는 게 아니거든…

 

그 외에도 고려할 게 몇 개 있는데, 그건 차차 설명하도록 하자. 기능 구현하는데도 피똥 쌀 예정이다.

 

def translation(text) :
    pass

우리는 또 찍어낸다 함수를.

 

codon_table = {
    # U
    "UUU":"F", "UUC":"F", "UUA":"L", "UUG":"L", 
    "UCU":"S", "UCC":"S", "UCA":"S", "UCG":"S",
    "UAU":"Y", "UAC":"Y", "UAA":"*", "UAG":"*",
    "UGU":"C", "UGC":"C", "UGA":"*", "UGG":"W",

    # C
    "CUU":"L", "CUC":"L", "CUA":"L", "CUG":"L", 
    "CCU":"P", "CCC":"P", "CCA":"P", "CCG":"P", 
    "CAU":"H", "CAC":"H", "CAA":"Q", "CAG":"Q", 
    "CGU":"R", "CGC":"R", "CGA":"R", "CGG":"R", 

    # A
    "AUU":"I", "AUC":"I", "AUA":"I", "AUG":"M", 
    "ACU":"T", "ACC":"T", "ACA":"T", "ACG":"T", 
    "AAU":"N", "AAC":"N", "AAA":"K", "AAG":"K", 
    "AGU":"S", "AGC":"S", "AGA":"R", "AGG":"R", 

    # G
    "GUU":"V", "GUC":"V", "GUA":"V", "GUG":"V", 
    "GCU":"A", "GCC":"A", "GCA":"A", "GCG":"A", 
    "GAU":"D", "GAC":"D", "GAA":"E", "GAG":"E", 
    "GGU":"G", "GGC":"G", "GGA":"G", "GGG":"G"
}

gpt한테 물어봤더니 코돈 테이블을 딕셔너리로 만든 다음 거기서 뒤져서 대체하게 하란다. 일회성으로 돌릴거면 함수 안에 넣어도 되는데 저거 한번 돌리고 땡 아니면 걍 전역 하라고 함… 전역변수 하라는 얘기는 함수 밖으로 빼라는 얘기다. 왜 그렇게 하냐고? 전역변수면 한 번만 부르면 되는데, 함수 안에 때려박으면 함수 돌릴때마다 쟤를 불러야 한다 이거지.

 

def translation(text) :
    text = text.upper()
    protein = []
    for i in range(0, len(text) - 2, 3):
        codon = text[i:i+3]
        amino_acid = codon_table.get(codon, '???')
        protein.append(amino_acid)
    return "".join(protein)

그러니까 착한 코더분들은 툴 찾아서 쓰십쇼… 일단 저 ???가 굳이 필요한지는 모르겠는게, 연구자들이 저런거 돌리는 시퀀스는 이미 DB에 있는거다. 그러니까 없는 코돈이 없다. for문 안에 0, len(text) - 2, 3으로 되어있는 이유는 0부터 시퀀스 길이-2까지 3개만인데…보통 시퀀스 3배수로 하지 않나? 라고 할 수 있지만 PCR 산물은 3배수 아닐수도 있다.

 

된 거 맞다. DNA를 입력해서 RNA로 전사하고 그걸로 번역까지 해야 한다.

 

아직 안 끝났다! 

중요한건 우리는 이제 막 번역 로직을 구현했을 뿐이고, 실제로 생물학 연구자들이 활용하는 두 가지에 대해서는 구현이 안 됐다. 그 두 가지가 뭐냐...

 

첫번째, 모든 번역의 시작점은 AUG(메티오닌)이다. 그러니까 DNA 시퀀스에서는 몇 번째에 존재하던 상관없이 AUG가 시작점이다. GAATTGCTAUG 뭐 이런 시퀀스가 있으면 GAATTGCT[AUG] <<여기 대괄호 친 AUG가 시작점이다.

 

두번째, 종결코돈이 나오면 더 이상 번역 안 하고 끝낸다. 위에 돌린 거 보면 번역 결과가 GSSRVPRVLSK*NELPYIEEGSCEG*WDCASSLTSVEIPDRPNACPRSIQDITSIHLL*RRGWNVFFFHDAPRGWGSIFGTTVGRGIFNDGLSFIAMMAFVGATFLFHYLHNKVTDSWAMESEEVSGYYPLLKSLNCPLVF*DCIFDIFGVDKCVVLHHVD
로 나오는데, 원래 번역대로라면 GSSRVPRVLSK에서 끝났어야 맞다.

 

def translation(text) :
    text = text.upper()
    protein = []
    for i in range(0, len(text) - 2, 3):
        codon = text[i:i+3]
        amino_acid = codon_table.get(codon, '???')
        protein.append(amino_acid)
        if amino_acid == "*":
            break
    return "".join(protein)

두번째 부분에 대해서는 if문 하나 추가하면 땡이다. 내가 위에 전역변수 선언한 표에 보면 종결코돈이 *로 되어있다. 그러니까 테이블 돌다가 * 나오면 끝내셈 하면 된다. 종결코돈은 툴 바이 툴인데 마침표로 표시하는데도 있음. 

 

def translation(text) :
    text = text.upper()
    start = text.find("AUG")

    if start == -1:
        return "No start point(AUG)"

    protein = []
    for i in range(start, len(text) - 2, 3):
        codon = text[i:i+3]
        amino_acid = codon_table.get(codon, '???')
        protein.append(amino_acid)
        if amino_acid == "*":
            break
    return "".join(protein)

find함수로 AUG를 찾은 다음 거기서부터 번역을 시작하면 장땡이다. 이게 또 피쌸돌렸거나 하면 없을 수도 있기때문에 if문 하나 때려박아줌... 그런데! 여기서 또 중요한 게 하나 있다. 저 기능이 보통 옵션으로 제공된다. 그러니까 AUG를 안 찾고 번역하는 함수도 필요하긴 하다는 것.

 

그래서 AUG로 시작하는 거, 아닌거 둘 다 했다. (함수 따로 빼버림)

 

결론: 착한 연구자 여러분들은 이런거 구현할 시간에 그냥 툴 쓰십시오

Lv. 35 라이츄

Lv. 35 라이츄

광고 매크로 없는 청정한 블로그를 위해 노력중입니다. 근데 나만 노력하는 것 같음… ㅡㅡ

Matplotlib으로 정규분포를 그려보자

Coding/Python 2024. 7. 16. 22:00

R에서 그래프 그릴 때 가끔 예제로 나오는게 정규분포다. 그 종같이 생긴 그거 말하는 거 맞습니다. 그래서 이걸 Matplotlib으로 그려봅시다.

 

Reference

https://bigdata-doctrine.tistory.com/14

 

[Python] 정규분포 그래프 시각화

오늘은 정규분포 그래프를 matplotlib을 사용하여 시각화해보겠습니다. 정규분포의 사전적 정의는 다음과 같습니다. 도수(度數) 분포 곡선이 평균값을 중앙으로 하여 좌우 대칭으로 종 모양을 이

bigdata-doctrine.tistory.com


그 전에 Matplotlib으로 그래프 그리는 걸 하셨으면 Matplotlib랑 Numpy, Pandas는 설치하셨을텐데 오늘은 Scipy도 같이 설치해야 한다. 네, 깔고 오십시오. pip install ~ 쓰면 깔릴거임.

 

import numpy as np
import matplotlib.pyplot as plot
from scipy.stats import norm

가져왔으면 이제 시작해보자. 세번째줄은 scipy의 모듈인데 아마 여기에 정규분포가 있는 듯 하다.

 

x = np.arange(0,20,0.001)
plot.figure(figsize=(10,7.5))
plot.title('Normal distribution')
plot.xlabel('x')
plot.ylabel('f(x)')
plot.plot(x, norm.pdf(x, loc=10, scale=2))
plot.show()

이렇게 하면 어떻게 나오냐면

 

이렇게 나온다. 이게 흔히 말하는 정규분포. 어? 이상하다? 정규분포 해갖고 가운데에 0 있는건 뭐예요? 그건 표준정규분포다. 얘는 평균이 10, 표준편차가 2인 정규분포.

 

위 코드만 입력하면 이렇게 정규분포가 나오는데... plot.어쩌고 된 건 다 matplotlob 관련인 거 알겠는데 첫 줄은 뭔가요? 그건 numpy를 이용해서 0부터 20까지 0.001간격으로 배열 형식으로 저장하라는 코드다. 그 다음으로 중요한 건 norm.pdf(x, loc=10, scale=2) 이 부분인데 이게 바로 '평균이 10, 표준편차가 2인 정규분포를 그려라'라는 얘기다. loc가 평균, scale이 표준편차. 그럼 표준정규분포를 그리려면 어디를 수정해야 하는 지 감이 좀 오시쥬?

 

x = np.arange(-4,4,0.001)
plot.figure(figsize=(10,7.5))
plot.title('Normal distribution')
plot.xlabel('x')
plot.ylabel('f(x)')
plot.plot(x, norm.pdf(x, loc=0, scale=1))
plot.show()

일단 위 코드랑 다른 점이 두 개 있다. 첫번째는 평균이랑 표준편차가 각각 0, 1이고 두번째는 x로 만드는 배열의 숫자 범위가 다르다. 처음에는 0부터 20까지였는데(평균이 10이라…) 표준정규분포는 -4부터 4까지 있다. 범위가 중요한가요? 예, 중요합니다. 범위를 그대로 0부터 20까지로 하면 어떻게 되냐면

 

타노스가 왔다갔나 반만 나온다.

 

착한 코더 여러분들은 얘는 '표준'정규분포니까 plot.title()에 Standard Normal distribution이라고 적어주는 센스를 잊지 말자.

Lv. 35 라이츄

Lv. 35 라이츄

광고 매크로 없는 청정한 블로그를 위해 노력중입니다. 근데 나만 노력하는 것 같음… ㅡㅡ

Matplotlib으로 그래프를 그려보자 (2)

Coding/Python 2024. 6. 5. 00:11

https://koreanraichu.tistory.com/431

 

Matplotlib으로 그래프를 그려보자

일단 이번에는 VScode가 아닌 다른 걸 켜볼건데… 바로 Jupyter이다. 얘가 칸단위로 처리할 수 있어서 개편합니다. 그래서 Jupyter, Numpy, Pandas, Matplotlib까지 설치하고 오시면 됩니다.imp

koreanraichu.tistory.com

자 우리 저번시간에는 matplotlib으로 꺾은선 그래프를 그렸는데… 아니 사인함수 그렸잖아요… 아무튼, 이번에는 csv파일을 불러온 다음 그걸로 막대그래프를 그려보자. 왜 csv냐면 이거 리눅스로 쓰고 있음.

 


raddish.csv
0.00MB

 

일단 이 CSV파일을 받아주시면 된다. 참고로 저거 동물의숲 무트코인임...

 

raddish=pd.read_csv("./raddish.csv",sep=";")

csv파일은 이렇게 불러오면 된다. 혹시 본인이 따로 파일을 준비했는데 그 파일이 엑셀파일이라면? pd.read_excel로 열면 된다. 혹시 본인이 따로 준비한 csv파일이 있다면 주의할 점이 하나 있는데, csv파일은 comma seperated 어쩌고라 보통 콤마(,)로 나뉘어져 있다. 근데 저 코드를 잘 보면 sep에 세미콜론이 들어가 있다. 아까도 설명했듯 csv파일은 보통 콤마로 나누기때문에 구분자가 ;라고 얘기를 안 해주면 판다스가 모르기때문에 오류...는 안뜨지만 표를 괴랄하게 읽는다. 그래서 sep=";"은 이거 csv파일이고 세미콜론으로 나뉘여있다고 말해주는거다. 공백이면 \s, 탭이면 \t 쓰면 된다.

 

그래프가 뭔 무트코인 옹졸에디션 됐어…

 

엥? loc에 숫자 들어갔어요? 예, 그 범례 위치 숫자로도 지정 가능합니다.
1. best, 0 (알아서 니가 적당한데 놔줘)
2. upper left/right 2,1 (위쪽 꼭지점)
3. lower left/right 3,4 (아래쪽 꼭지점)
4. right 5 (오른쪽)
5. center left/right 6,7 (가운데, 즉 꼭지점이 아니고 그래프의 양쪽 축(변)에 위치하게 된다)
6. upper/lower center 9,8 (위쪽/아래쪽 중앙. 그래프의 상/하변에 위치하게 된다)
7. center 10 (가운데)
대충 이렇게 지정하면 된다.

 

쓰읍 이거 오전오후 나란히 둘 수 없나요?

 

보시다시피 정말 개고생했다… 여러분은 걍 엑셀 쓰세요.

 

bar_width = 0.2
N = raddish.shape[0]
index = np.arange(N)
fig, ax=plot.subplots(figsize = (14,7))
ax.bar(index - bar_width, raddish['AM'], color="#000000", label='AM', width = bar_width)
ax.bar(index + bar_width, raddish['PM'], color='#999999', label='PM', width = bar_width)
ax.legend(loc=2)
plot.xticks(index, raddish['Date'])

일단 matplotlib에는 막대그래프가 여러개라고 겹쳐주는 기능이 없다. 그래서 가로 너비를 정하고 넘파이까지 동원해서 니들끼리 옆으로 빠져주세요 해야 한다… 보통은 저렇게 겹친다.

 

figsize는 그래프의 크기를 정하는거다. 그래서 위 캡처보다 아래 그래프가 좀 더 커진 걸 볼 수 있다. 그리고 xticks는 x축 간격 정하는건데 yticks라고 해서 y축 간격 정해주는 것도 있다. 일단 이정도...인데... 솔직히 저 그래프 딸랑 주면 님들 뭔지 모르잖아요?

 

제목이 너무 작아서 크기를 키우고싶은가? 

 

bar_width = 0.2
N = raddish.shape[0]
index = np.arange(N)
fig, ax=plot.subplots(figsize = (14,7))

plot.rc("font", family='NanumGothic', size = 14)

ax.bar(index - bar_width, raddish['AM'], color="#000000", label='AM', width = bar_width)
ax.bar(index + bar_width, raddish['PM'], color='#999999', label='PM', width = bar_width)
ax.legend(loc=2)
plot.xticks(index, raddish['Date'], size = 12)
plot.yticks(size = 12)
plot.title("무트코인 가격",size = 20)
ax.set_xlabel('날짜', size = 16)
ax.set_ylabel('벨', size = 16)
plot.show()

size = 원하는 크기 주면 된다. 보통은 일일이 하기 귀찮으니까 사이즈 변수에 담아놓고 변수 던져준다. plot.rc에 있는 family는 뭐냐면 이 그래프 글꼴 나눔고딕으로 해달라는 얘기인데, 이건 적용하려면 PC에 설치된 글꼴이어야 한다. PC에 설치만 되어있으면 프리텐다드 이런거 써도 된다.

 

착한 어린이 여러분들은 그냥 엑셀 쓰세요.

 

이거 심지어 다른 폰트는 적용하려고 설치된 이름이랑 파일명이랑 다 해봤는데 적용 안돼서 나눔고딕으로 롤백함…

Lv. 35 라이츄

Lv. 35 라이츄

광고 매크로 없는 청정한 블로그를 위해 노력중입니다. 근데 나만 노력하는 것 같음… ㅡㅡ

Matplotlib으로 그래프를 그려보자

Coding/Python 2024. 6. 3. 23:45

일단 이번에는 VScode가 아닌 다른 걸 켜볼건데… 바로 Jupyter이다. 얘가 칸단위로 처리할 수 있어서 개편합니다. 그래서 Jupyter, Numpy, Pandas, Matplotlib까지 설치하고 오시면 됩니다.


import numpy as np
import pandas as pd
import matplotlib.pyplot as plot

다 불러오면 된다.

 

Jupyter는 이렇게 하고 Ctrl+Enter만 누르면 만사 오케이다.

 

x = np.linspace(0,10,1000)
fig, ax = plot.subplots()
ax.plot(x, np.sin(x))
plot.show()

linspace는 넘파이에 있는건데, 저게 무슨 뜻이냐면 1) 0부터 2) 10까지 3) 간격 1000으로 나눠달라 는 얘기다. 두번째줄 저거는 뭔진 모르겠는데 있어야 그려주데… 그리고 세번째줄은 y=sin(x)의 그래프를 그려달라는 얘기. 마지막줄은 그렸으면 보여달라는 얘기다.

 

그니까 이렇게 했으면 여러분은 y-sin(x)의 그래프를 그린 게 맞는'데'… 솔직히 그렸다 땡 하면 여러분들 욕할거 다 알아요… 그러니까 저 그래프 모양을 살짝 손질해보자.

 

ax.set_xlim(0, 10)
ax.set_ylim(-1.5, 1.5)

이렇게 하면 x축(위), y축(아래)의 값을 제한할 수 있다. 이렇게 하면 뭐가 좋냐고?

 

그래프가 꽉 차보입니다.

 

x = np.linspace(0,10,1000)
fig, ax = plot.subplots()
ax.plot(x, np.sin(x), color="#000000", label="y=sin(x)")
ax.legend(loc='upper right')
ax.set_xlim(0, 10)
ax.set_ylim(-1.5, 1.5)
ax.set_xlabel('X')
ax.set_ylabel('y')
plot.show()

뭐가 좀 많이 늘었는데 하나씩 차근차근 설명해주겠다. ax.set_xlabel, ax.set_ylabel은 각각 x축/y축 라벨이다. 그리고 ax.legend는 레전드인데... 이게 뭐냐면... 이 그래프는 사인함수 하나만 있지만 가끔 그런거 할 때 있잖아요? 뭐 예를 들자면 시정 점유율같은 거. 그런거 할 때 무슨색이 뭐고 무슨색이 뭐고 달려있는 그거다. ...그거 뭐라하지? 아무튼... ax.plot에 color="#000000"은 이 그래프 선을 검정색으로 바꿔라 이 얘기. color 옵션은 막대그래프에서도 통한다.

 

그래서 아까 그렸던 사인함수 그래프가 이렇게 됐다. 여기까지 잘 따라왔다면 여러분은 파이썬으로 사인함수 그래프 그려 본 사람이 되는거다.

 

솔직히 코사인 탄젠트 빠지면 섭하쥬?

 

plot.savefig('example.png')

요고 한 줄 쳐주면 당신이 그린 그래프를 저장할 수 있다.

 

놋북이 오래돼서 로딩이 느린거지 저장된거 맞다.

 

다음부턴 배경땜시 jpg로 해야쓰것군...

 

그래서 이게 다냐고? 아니, 이제 꺾은선 그래프 그려봤으니까 막대그래프도 그려볼거다. 그리고 엑셀파일도 불러와서 그려봐야 하고. 윈도우에는 안 깔려있어서 리눅스로 해야 하는게 단점이지만 아무튼… 다음편에서는 막대그래프도 그려보고, 판다스의 힘으로 엑셀파일도 불러와서 해보자.

Lv. 35 라이츄

Lv. 35 라이츄

광고 매크로 없는 청정한 블로그를 위해 노력중입니다. 근데 나만 노력하는 것 같음… ㅡㅡ

배수 판별을 해보자

Coding/Python 2024. 4. 10. 01:30

왜 우리 초딩때 배웠던 배수 판별법 있죠? 짝수면 2의 배수, 끝자리가 5나 0이면 5의 배수, 자릿수 다 더해서 3의 배수이면 3의 배수 뭐 이런거. 그걸 해 볼거다. 솔직히 배수 판별이라고 해서 엥 그거 걍 나눠서 나머지 없으면 배수 아니냐 했던 분들 반성하십쇼. 그런 심플한거나 하겠답시고 내가 여기다 올리겠수?


https://ko.wikipedia.org/wiki/%EB%B0%B0%EC%88%98_%ED%8C%90%EC%A0%95%EB%B2%95

 

배수 판정법 - 위키백과, 우리 모두의 백과사전

위키백과, 우리 모두의 백과사전. 배수 판정법은 배수인지 확인하려는 수의 배수가 맞는지 간단히 확인하는 절차이다. 일반적으로 정수 m , n {\displaystyle m,n} 에 대해 m {\displaystyle m} 이 n {\displaysty

ko.wikipedia.org

여기 들어가보면 뭐가 많은데 우리는 1부터 9까지만 할거다. 두자리수부터는 솔직히 있는줄도 몰랐음.

 

2의 배수

2의 배수: 일의 자리 수가 0,2,4,6,8인 수이다.
import sys

K = sys.stdin.readline().rstrip()

if K[-1] == '2' or K[-1] == '4' or K[-1] == '6' or K[-1] == '8' or K[-1] == '0':
    print('2의 배수입니다. ')
else: 
    print('2의 배수가 아닙니다. ')

2의 배수는 말 그대로 끝자리가 2, 4, 6, 8, 0이면 2의 배수이다. 즉 짝수면 2의 배수다. 쉽죠? 5의 배수도 이따가 다시 설명하겠지만 로직은 비슷하고 끝자리가 5 혹은 0이기때문에 or 하나 들어가고 땡이다.

 

3의 배수

3의 배수: 각 자리 수의 합이 3의 배수인 수이다.

이거 사람은 둘째치고 컴퓨터 시켜먹을라면 빡세겠는데?

 

sum = 0
for i in K:
    sum += int(i)
print(sum)

근데 우리는 내일 쉬니까 해봅시다. 아무튼 숫자 자릿수를 다 더하는 방법은 이거다. 이거는 근데 그냥 다 더하는 방법이고... 우리는 이걸 다 더해서 3의 배수인지 아닌지 판단하는 절차를 거쳐야 한다.

 

import sys

K = sys.stdin.readline().rstrip()

sum = 0
for i in K:
    sum += int(i)

if sum % 3 == 0:
    print('3의 배수입니다')
else: 
    print('3의 배수가 아닙니다')

물론 가장 심플한 방법은 이거긴 함... 다 더한 값이 3으로 나누어 떨어지면 그건 3의 배수다. 예를 들어서 54는 5+4가 9이고 9가 3의 배수니까 3의 배수인 것. 쉽죠?

 

사실 하고싶었던 건 자릿수의 합을 구한 다음 그걸 또 더하고 더해서 최종 자릿수를 10 미만(한자리)으로 남긴 다음 판정하는건데 이거는 while 안에 for문 때려박으니까 로직 에러가 터진다. for+continue 해봤는데 처음으로 가기만 하고 실행 안함 잉잉…

 

4의 배수

4의 배수는 가장 끝에 두 자리수가 00이거나 4의 배수인 수이다. (십의 자리가 짝수인 경우에는 일의 자리수가 0, 4, 8이면 되고, 십의 자리수가 홀수인 경우에는 일의 자리수가 2, 6이면 된다.)

와씨 3 다음이 더 저세상이었어...

 

일단 첫번째 조건은 숫자가 세자리 미만(0~99)일 때는 판단 불가이므로 숫자 길이를 먼저 봐야 한다. 나머지는 뭐 두자리에서도 가능은 한데… or 붙이기 귀찮으니 걍 % 쓰겠음둥.

 

import sys

K = sys.stdin.readline().rstrip()

if len(K) > 2 and K[-2] == '00': # 해당 조건은 세자리 숫자부터 가능하다
    print('4의 배수입니다.')
elif int(K[-2]) % 2 == 0:
    if K[-1] == '0':
        print('4의 배수입니다.')
    if K[-1] == '4':
        print('4의 배수입니다.')
    if K[-1] == '8':
        print('4의 배수입니다.')
elif int(K[-2]) % 2 != 0:
    if K[-1] == '2':
        print('4의 배수입니다.')
    if K[-1] == '6':
        print('4의 배수입니다.')
else: 
    print('4의 배수가 아닙니다')

이때 아차 싶었던게 4의 배수가 아니면 출력이 안됨... 저기 else 보이죠? 지금 장식됐음 ㅋㅋㅋㅋㅋㅋ

 

import sys

K = sys.stdin.readline().rstrip()

if len(K) > 2 and K[-2] == '00': # 해당 조건은 세자리 숫자부터 가능하다
    print('4의 배수입니다.')
elif int(K[-2]) % 2 == 0 and K[-1] == '0':
    print('4의 배수입니다.')
elif int(K[-2]) % 2 == 0 and K[-1] == '4':
    print('4의 배수입니다.')
elif int(K[-2]) % 2 == 0 and K[-1] == '8':
    print('4의 배수입니다.')
elif int(K[-2]) % 2 != 0 and K[-1] == '2':
    print('4의 배수입니다.')
elif int(K[-2]) % 2 != 0 and K[-1] == '6':
    print('4의 배수입니다.')
else: 
    print('4의 배수가 아닙니다')

와 8의 배수 어카냐...

 

5의 배수

5의 배수는 일의 자리수가 5, 0인 수이다.

이거는 걍 위에 2의 배수 한 거 갖다 쓰면 된다.

 

import sys

K = sys.stdin.readline().rstrip()

if K[-1] == '5' or K[-1] == '0':
    print('5의 배수입니다. ')
else: 
    print('5의 배수가 아닙니다. ')

3, 4배수 거치고 나니 얘는 선녀가 따로 없다.

 

6의 배수

6의 배수는 2와 3의 공배수, 즉, 짝수이면서 각 자리의 합이 3의 배수인 수이다.
import sys

K = sys.stdin.readline().rstrip()

sum = 0
for i in K:
    sum += int(i)

if sum % 3 == 0 and int(K) % 2 == 0:
    print('6의 배수입니다')
else: 
    print('6의 배수가 아닙니다')

여기서 조심할건 3배수 갖다쓴답시고 sum % 2가 0일때로 걸면 안된다는 것. 우리가 입력하는 숫자가 짝수이면서 합계가 3의 배수인게 6의 배수지 합계는 홀수건 짝수건 상관 없다. 당장 36도 6의 배수인데 자릿수 다 더하면 9다.

 

7의 배수

7의 배수는 일의 자리를 두 배 한 것을 나머지 수에서 빼면 결과가 0 또는 7의 배수가 나오는 수이다. 다른 방법으로는 일의 자리부터 세 자리씩 끊어서 교대로 빼고 더한 것이 7의 배수일 경우 본래의 수도 7의 배수이다. 이 방법은 7이 1001의 약수임을 이용한 것으로 다른 1001의 약수 11, 13, 77, 91, 143, 1001에도 적용시키는 게 가능하다. 또 다른 방법으로는 본래의 수를 10으로 나눈 뒤에 소수점 아래는 버림한 값에 본래의 수의 일의 자리를 다섯 배한 수를 더한 결과가 7의 배수이면 본래의 수도 7의 배수이다.

이건 발견한 놈도 연구대상 아니냐... 이래서 초딩때 7의 배수만 판별법 안가르쳐주고 넘어갔구나...

 

자 일단 뭔 소리냐… 14를 예로 들어보면 일의 자리가 4니까 4*2를 1에서 빼면 음수긴 하지만 절대값이 어쨌든 7이니까 7의 배수 뭐 이런 식인 듯 한데… 솔직히 음수 어떻게 처리하는지는 저 방법 고안한 사람한테 물어봐야될 듯 하고요…

 

import sys

K = sys.stdin.readline().rstrip()

sum = 0
for i in range(len(K)-1):
    sum += int(K[i])

if abs(sum - int(K[-1]) * 2) % 7 == 0:
    print('7의 배수입니다.')
else: 
    print('7의 배수가 아닙니다.')

귀찮아서 절대값 때려박았음. 스펜터인지 스펜스인지 아무튼 이거 고안한 양반은 음수 처리를 어떻게 했는지 모르겠고… 이거는 걍 % 7 == 0으로 조건 거십쇼 그게 머리 안 터지고 좋은 방법입니다. 두번째 방법은 나도 이해를 못해서 못짜겠고 마지막 방법은… 35를 예시로 들자면 35/10은 3(소수점 버림)이고, 거기에 5*5 25를 더하면 28이 7의 배수이니까 35도 7의 배수! 이런 느낌인 듯 하다.

 

import sys

K = sys.stdin.readline().rstrip()

X = int(K) // 10
Y = int(K[-1]) * 5

if (X + Y) % 7 == 0:
    print('7의 배수입니다.')
else: 
    print('7의 배수가 아닙니다.')

근데 농담 아니고 막상 해놓고 보니 얘가 더 쉬운데?

 

8의 배수

8의 배수는 가장 끝에 세 자리수가 000이거나 8의 배수인 수이다. (좀 더 쉽게 설명하자면 백의 자리가 0이거나 짝수인 경우에는 끝에 두 자리수가 00, 08, 16, 24, 32, 40, 48, 56, 64, 72, 80, 88, 96 다시 말해 8의 배수인 수이고, 백의 자리가 홀수인 경우에는 끝의 두 자리수가 4의 배수면서 8의 배수가 아닌 두 자리수 4, 12, 20, 28, 36, 44, 52, 60, 68, 76, 84, 92이어야 한다.)

야 이거 두자리 수는 그냥 8로 나누어 떨어지나 봐야긋다…

 

import sys

K = sys.stdin.readline().rstrip()

if len(K) <= 3 and int(K) % 8 == 0: # 이거 안 해주면 인덱싱 에러떠유
    print('8의 배수입니다.')
elif len(K) > 3 and K[-2] == '000': # 해당 조건은 네자리 숫자부터 가능하다
    print('8의 배수입니다.')
    # 여러분은 그냥 %를 쓰십시오... 아무튼 아래 조건은 1. 백의 자리가 짝수이면서 2. 십의 자리, 일의 자리가 8의 배수인 것들 
elif int(K[-3]) % 2 == 0 and K[-2:] == '00':
    print('8의 배수입니다.')
elif int(K[-3]) % 2 == 0 and K[-2:] == '08':
    print('8의 배수입니다.')
elif int(K[-3]) % 2 == 0 and K[-2:] == '16':
    print('8의 배수입니다.')
elif int(K[-3]) % 2 == 0 and K[-2:] == '24':
    print('8의 배수입니다.')
elif int(K[-3]) % 2 == 0 and K[-2:] == '32':
    print('8의 배수입니다.')
elif int(K[-3]) % 2 == 0 and K[-2:] == '40':
    print('8의 배수입니다.')
elif int(K[-3]) % 2 == 0 and K[-2:] == '48':
    print('8의 배수입니다.')
elif int(K[-3]) % 2 == 0 and K[-2:] == '56':
    print('8의 배수입니다.')
elif int(K[-3]) % 2 == 0 and K[-2:] == '64':
    print('8의 배수입니다.')
elif int(K[-3]) % 2 == 0 and K[-2:] == '72':
    print('8의 배수입니다.')
elif int(K[-3]) % 2 == 0 and K[-2:] == '80':
    print('8의 배수입니다.')
elif int(K[-3]) % 2 == 0 and K[-2:] == '88':
    print('8의 배수입니다.')
elif int(K[-3]) % 2 == 0 and K[-2:] == '96':
    print('8의 배수입니다.')
    # 아래 조건은 1. 백의 자리가 홀수이면서 2. 십의 자리, 일의 자리가 4의 배수이면서 8의 배수가 아닌 것들(대충 초항이 4 공차가 8인 등차수열인데 범위가 < 100)
elif int(K[-3]) % 2 != 0 and K[-2:] == '04':
    print('8의 배수입니다.')
elif int(K[-3]) % 2 != 0 and K[-2:] == '12':
    print('8의 배수입니다.')
elif int(K[-3]) % 2 != 0 and K[-2:] == '20':
    print('8의 배수입니다.')
elif int(K[-3]) % 2 != 0 and K[-2:] == '28':
    print('8의 배수입니다.')
elif int(K[-3]) % 2 != 0 and K[-2:] == '36':
    print('8의 배수입니다.')
elif int(K[-3]) % 2 != 0 and K[-2:] == '44':
    print('8의 배수입니다.')
elif int(K[-3]) % 2 != 0 and K[-2:] == '52':
    print('8의 배수입니다.')
elif int(K[-3]) % 2 != 0 and K[-2:] == '60':
    print('8의 배수입니다.')
elif int(K[-3]) % 2 != 0 and K[-2:] == '68':
    print('8의 배수입니다.')
elif int(K[-3]) % 2 != 0 and K[-2:] == '76':
    print('8의 배수입니다.')
elif int(K[-3]) % 2 != 0 and K[-2:] == '84':
    print('8의 배수입니다.')
elif int(K[-3]) % 2 != 0 and K[-2:] == '92':
    print('8의 배수입니다.')
else: 
    print('8의 배수가 아닙니다')

누누이 말하는거지만 착한 코더 여러분들은 이런 노가다 하지 마시고 그냥 % 쓰십시오. 진지하니까 궁서체.

 

아, 참고로 4배수랑 달리 if문에 뭔가 이상한 게 들어갔는데, 저거 안 들어가면 두자리수 판별할 때 인덱싱 에러 뜬다. 십의자리, 일의자리랑 반복문땜시 입력을 텍스트로 받고 있는데 두자리수가 들어오면 인덱싱 범위 벗어난다고 안돼서 맨 위에 K(입력받은 수)가 두자리이고 8로 나누어 떨어지면 8의 배수 하셈 한 것. 4배수는 안해도 잘 돌아갔거나 내가 깜빡했거나 둘 중 하나다.

 

9의 배수

9의 배수는 각 자리 숫자의 합이 9의 배수인 수이다.
import sys

K = sys.stdin.readline().rstrip()

sum = 0
for i in K:
    sum += int(i)

if sum % 9 == 0:
    print('9의 배수입니다')
else: 
    print('9의 배수가 아닙니다')

걍 이걸로 퉁칩시다... 8배수 코딩하느라 기력 다빠졌어... ㅠㅠ

 

10의 배수

10의 배수는 일의 자리가 0인 수이다.
import sys

K = sys.stdin.readline().rstrip()

if K[-1] == '0' :
    print('10의 배수입니다')
else: 
    print('10의 배수가 아닙니다')

얘가 제일 쉬웠어요…

 

번외편: 11의 배수

11의 배수는 홀수 자리의 합과 짝수 자리의 합의 차가 0이거나 11의 배수인 수이다. 다른 방법은 일의 자리 숫자를 제외한 후 남은 숫자에 제외시킨 일의 자리 숫자를 뺀 결과가 0이거나 11의 배수이면 본래의 수도 11의 배수이다.

첫번째 방법은 숫자 길이가 정해져있으면 몰라도 숫자 길이가 가변형이면 난이도 급상승하니까 두번째 방법으로 해 보자. 솔직히 안하려고 했는데 재밌어보여서 하는거다.

 

import sys

K = sys.stdin.readline().rstrip()

X = int(K[-1])
Y = int(K[0:len(K)-1])

if (Y - X) % 11 == 0:
    print('11의 배수입니다.')
else: 
    print('11의 배수가 아닙니다.')

이거 n 이상 m 미만 아니었나 생각해봤는데 뒤에꺼 자르려면 길이에서 1 빼는게 맞더라...

 

결론: 그러니까 여러분은 이런 노가다 하지 마시고 걍 %를 쓰세요.

Lv. 35 라이츄

Lv. 35 라이츄

광고 매크로 없는 청정한 블로그를 위해 노력중입니다. 근데 나만 노력하는 것 같음… ㅡㅡ

구구단을 이차원 배열로 출력해보자

Coding/Python 2024. 3. 12. 23:28

아오 티스토리에 왜이렇게 뻘댓글이 많은지… ㅡㅡ 심지어 내가 달지 말고 걍 가라했는데도 계속 달아서 티스토리도 스팸필터 달고 있음… 네이버는 한줄+답글이지만 티스토리는 한명이 서너개 두두두두 달고 갑니다. 하지 말라면 좀 하지 말라고…

 

생각해봅시다. 반복문 하면서 제일 만만한게 구구단인데, 이거 보통

for i in range(2,10):
    for j in range(2,10):
        print('{} * {} = {}'.format(i, j, i * j))

이렇게 하잖아요? 그래서 저거 실행하면 2 * 2 = 4 이런 식으로 줄줄이 뜨잖음. 그러니까, 한 줄로요. 이걸 이차원 배열... 그러니까 표로 출력할거다. 상당히 간단한 절차이니 걍 보고 따라해보자.


gugudan_array = [['*' for i in range(2,10)] for j in range(2,10)]

print(gugudan_array)

일단 이렇게 하면 이차원 배열을 만들 수 있다. 그런데 이대로 출력하면 안에 애스터리스크만 들어있는 이차원 배열이 나온다. 그러면 안에 값은 어떻게 채우냐고?

 

gugudan_array = [[i * j for i in range(2,10)] for j in range(2,10)]

print(gugudan_array)

그냥 이렇게 하면 된다. 근데 저대로 출력하면 1차원 배열들이 그냥 줄줄이 성의없이 나오는데… 스읍… 이거 어떻게 안될까요?

 

gugudan_array = [[i * j for i in range(2,10)] for j in range(2,10)]

for k in gugudan_array:
    print(k)

해드렸습니다^^

 

import sys
gugu_range = int(sys.stdin.readline())

gugudan_array = [[i * j for i in range(1,gugu_range+1)] for j in range(1,gugu_range+1)]

for k in gugudan_array:
    print(k)

이렇게 하면 9까지 안 하고 11단 12단 이렇게도 할 수 있다. 근데... 생각해보니 저 괄호 있잖아... 아예 걍 떼버리고 싶지 않음?

 

import sys
gugu_range = int(sys.stdin.readline())

gugudan_array = [[i * j for i in range(1,gugu_range+1)] for j in range(1,gugu_range+1)]

for x in range(gugu_range):
    for y in range(gugu_range):
        print(gugudan_array[x][y], end=" ")
    print()

여기서 더 이쁘게 뽑고 싶다면 그건 판다스를 섭외하거나 엑셀로 가셔야 함...

Lv. 35 라이츄

Lv. 35 라이츄

광고 매크로 없는 청정한 블로그를 위해 노력중입니다. 근데 나만 노력하는 것 같음… ㅡㅡ

현재 시각을 십이지시로 바꿔보자

Coding/Python 2024. 1. 10. 23:04

요즘은 뭐 열두시 한시 이런 식으로 얘기해서 십이지시 잘 모르는 사람도 많다. 사실 이거 쓰는거 사주 볼 때 말고는 없는데, 뭐 개인이 보는 경우도 있지만 가끔 남녀가 결혼하기 전에 궁합이 어떤지 볼 때도 태어난 년월일'시'가 필요할 때가 있다. 근데 딱히 그래서 코딩해본 건 아님.

 

참고로 일본 괴담 번역 즐겨보시는 분들 한번 접해봤을 키워드인 축시의 참배 할 때 축시도 십이지시다. 그래서 이게 대충 몇시인가요?

 

출처: 위키피디아(지지_역법)

여기서 시간만 보면 된다. 참고로 1시 정각이 그래서 자시인지 축시인지는 안 나오는 관계로 편의상 n시 정각~n시 59분으로 코딩하도록 하겠음. 와 이래 보니 축시가 꼭두새벽이었네... 그럼 꼭두새벽에 누구 저주한답시고 나무에 못박고 그러는거임? 후덜덜하구만.

 

여담이지만 자시와 오시는 자정, 정오의 어원이다. 자정은 익일 0시(오전 12시)인데 자시의 딱 중간이고, 정오는 12시(오후 12시)인데 오시의 딱 중간이그덩.

 

from datetime import datetime

now_hour = datetime.today().hour
now_minute = datetime.today().minute

우리에게 필요한 것은 시와 분이긴 한데... 사실 분 필요엄슴... 시만 있으면 됨...

 

if (now_hour >= 1 and now_hour < 3):
    print("축시")
elif (now_hour >= 3 and now_hour < 5):
    print("인시")
elif (now_hour >= 5 and now_hour < 7):
    print("묘시")
elif (now_hour >= 7 and now_hour < 9):
    print("진시")
elif (now_hour >= 9 and now_hour < 11):
    print("사시")
elif (now_hour >= 11 and now_hour < 13):
    print("오시")
elif (now_hour >= 13 and now_hour < 15):
    print("미시")
elif (now_hour >= 15 and now_hour < 17):
    print("신시")
elif (now_hour >= 17 and now_hour < 19):
    print("유시")
elif (now_hour >= 19 and now_hour < 21):
    print("술시")
elif (now_hour >= 21 and now_hour < 23):
    print("해시")
else:
    print("자시")

select case좌... 그립습니다... 아무튼. 편의상 n시 정각~n시 59분까지로 한다고 했는데 이게 어쨌든 두시간이잖아요? 그러면 걍 현재 시가 1보다 같거나 크고 3부다 작으면 축시, 3보다 같거나 크고 5보다 작으면 인시 이런 식으로 하면 된다. if문이 개같이 많을 뿐 그렇게 어려운 문제는 아니다. 근데 왜 자시를 밑으로 뺐냐면 자시는 23시부터 익일 1시 사이라서 저걸 범위 잡기가 개같이 애매했음...

 

아, 이거 자바스크립트로요? 아니 해서 나쁠 건 없는데 이걸 굳이?

Lv. 35 라이츄

Lv. 35 라이츄

광고 매크로 없는 청정한 블로그를 위해 노력중입니다. 근데 나만 노력하는 것 같음… ㅡㅡ

파이썬으로 만나이를 계산해보자

Coding/Python 2024. 1. 9. 23:28

아니 이게요... 일하는데 어떤 분이 엑셀로 생년월일 입력하면 만나이 계산 알아서 되는 방법이 있다던데 함수좀 짜달라길래... 속으로 오 씨 콘텐츠 각 이러면서 짰습니다... 이걸 각을 재네 나중에 JS랑 엑셀로도 할거고 하게 되면 또 올리겠음. 참고로 엑셀은 미디움에는 안 올라갑니다. 원래 미디움에는 잔머리엑셀 연재 안했음. 


일단 만 나이가 뭐냐... 한국인은 나이가 두 개인데 첫번째가 해가 지나가면(1월 1일 되면) +1씩 더해지는 세는 나이고 두번째가 본인 생일이 지나야 올라가는 만나이이다. 보통 사람들하고 교류할때는 세는 나이를 말하고 행정 처리(예를 들자면 교통카드 요금이 청소년->성인으로 올라가는 것) 할 때는 만 나이로 들어가는데, 본인은 91년생이기때문에 세는 나이로는 34살이지만 아직 생일이 안 지나서 만 나이는 32살이다. 근데 두달후면 올라서 의미는 엄숴... 아무튼 만 나이는 생일이 지났다면 세는 나이에서 -1이고 안 지났으면 세는 나이에서 -2 하면 된다.

 

from datetime import datetime

birth = input('생일을 yyyy-mm-dd형식으로 입력해주세요: ')

datetime이 있으면 파이썬에서도 날짜와 시간을 주물주물 할 수 있다. 아무튼 그래서 일단 불러오고... 생일 입력 받고... 아니 생일을 입력받아야 나이 계산을 할 거 아뉴.

 

birthday = datetime.strptime(birth,"%Y-%m-%d")

now_year = datetime.today().year
now_month = datetime.today().month
now_day = datetime.today().day
# 오늘 년월일

birth_year = birthday.year
birth_month = birthday.month
birth_day = birthday.day
# 생일 년월일

일단 생일은 문자열 형태라 저거 자체로는 계산을 못 하기 때문에 strptime을 이용해서 날짜로 바꿔줄거다. 보통 태어난 시까지는 잘 모르기도 하고 사주 볼 때나 쓰기때문에 의미는 없고 걍 연월일 하면 되는데 4자리 할거면 y는 반드시 대문자로 해야 한다. 내 경험담임. 소문자 하니께 에러떴음...... 위는 현재 연월일, 아래는 생일에서 추출한 연월일이다.

 

isbirthdaypass = False
# 음 대충 생일 플래그인걸로 합시다 

if birth_month < now_month : # 생일 월보다 현재 날짜의 월이 더 크면 생일이 지난것이므로 
    isbirthdaypass = True # 만나이 +1
elif birth_month == now_month: # 생일 월과 현재 월이 같다면
    if birth_day <= now_day : # 현재 일이 생일보다 크거나 같나요? 
        isbirthdaypass = True # 응 만나이 먹었어
    else: # 아니야? 
        isbirthdaypass = False # 응 아직 아니야
else: 
    isbirthdaypass = False # 생일 월이 현재 날짜보다 크다면 아직 안 지난 것

위에 있는 불린은 대충 플래그니까 패스하시고... 여기가 제일 골대리는 파트니까 집중하십쇼.

 

자 일단 만 나이가 올라가는 기준이 생일이라고 했잖아요? 그럼 생일이 지났는지를 어떻게 판별하느냐...

 

1. 생일 월 < 현재 월: 생일 지났다.

2. 생일 월 > 현재 월: 아직 아니다.

3. (여기가 분기점) 생일 월이랑 현재 월이 같은가? -> 현재 일이 생일보다 크거나 같나요? 예: 지났음/아니오: 응 아직

 

3번이 제일 이해가 안 갈텐데 생각해보자. 오늘이 1월 9일이니까 91년 1월 8일생인 사람이 있다면 월은 1로 둘 다 같으니까 일을 비교할것이다. 그럼 birth_day는 8이고 now_day는 9니까 오른쪽이 더 크잖음? 그래서 만으로 33세가 되는거다. 반면 91년 1월 10일생인 사람은 오늘이 1월 9일이라 birth_day가 now_day보다 크기때문에(현재 일이 생일보다 작기때문에) 아직 만 나이가 오르지 않았는데... 아... 곧 오르네...

 

if isbirthdaypass == False:
    print(now_year - birth_year - 1)
else: 
    print(now_year - birth_year)

플래그가 섰다면 플래그대로 출력하면 된다. 일단 생일이 아직 안 지났으면 만나이가 아직 안 오른건 다들 아실테니 패스하고 계산이 왜 저런지를 설명하자면, 원래 만나이가 현재 년도에서 태어난 년도 뺀 게 만나이다. 년도'만' 빼면 그런데 아직 만나이가 안 올랐으면 거기서 1을 더 빼면 된다.

 

참고로 외국에서는 만 나이만 사용하니 이 점 유의합시다. 당장 옆나라 일본도 만나이로 센다.

Lv. 35 라이츄

Lv. 35 라이츄

광고 매크로 없는 청정한 블로그를 위해 노력중입니다. 근데 나만 노력하는 것 같음… ㅡㅡ

나눗셈 결과 몫 ... 나머지로 표시하기

Coding/Python 2023. 10. 22. 00:00

이거 참고로 노션에는 기록을 못한다... 차마 기록할 페이지를 어디다 만들어야 할 지 모르겠음... ㅋㅋㅋㅋㅋ

 

문방구 오락기에서 게임하다가 엄마한테 등짝맞던 시절... 아니 그니까 초딩때를 이야기하는거다. 아무튼, 우리가 나눗셈을 처음 배웠을 때 6 나누기 4는 몫이 1이고 나머지가 2라 1 ... 2 이런 식으로 표현했다. 근데 콤퓨타는 기본적으로 몫과 나머지따원 모르겠고 난 소수점으로 쫑낼것이다! 모드란 말이죠.

 

그니까 응애 애기피츄 책사죠 하던 시절의 그 나눗셈을 해보자 이겁니다. 뭘로? 파이썬으로. 왜 피츄인지는 내 닉네임을 보면 납득할 수 있을것이다. 본인이 라이츄기 때문에 유년기가 피츄인거다.


일단 나눗셈의 용어에 대해 알고 가도록 하자. 나눗셈 하면 피제수와 제수라는 두 개의 용어가 있는데(몫과 나머지도 있지만), 피제수는 나눠지는 수, 제수는 나누는 수이다. 6 나누기 3에서 6은 피제수, 3은 제수다.

 

전에 백준 풀이에서 부정과 불능에 대해 얘기하면서 0 나누기 0을 하게 되면 0을 빼고빼고빼고빼고빼고빼고...빼고 해야돼서 안 끝난다고 했는데, 그렇다. 피제수에서 제수를 겁나 빼는게 나눗셈이다. 30 나누기 5 하면 30에서 5를 여섯 번 빼면 된다. 언제까지? 0 될때까지. 나머지가 있다면 언제까지? 0보다 크고 제수보다 작을때까지.

 

import sys

X = int(sys.stdin.readline()) # 피제수
Y = int(sys.stdin.readline()) # 제수
cnt = 0

while X >= Y:
    X -= Y
    cnt += 1

print(cnt, X)

여기서 cnt는 몫이고, X는 피제수(였던것)가 된다. 왜 였던것이냐면 피제수가 제수보다 클때까지 빼고빼고빼고빼고...빼서 제수보다 작아지면 while문을 빠져나오기 때문.

 

import sys

X = int(sys.stdin.readline()) # 피제수
Y = int(sys.stdin.readline()) # 제수
cnt = 0

while X >= Y:
    X -= Y
    cnt += 1

print('{} ... {}'.format(cnt,X))

이렇게 하면 몫 ... 나머지로 출력되는데 아직 한가지 더 남았다. 나머지가 0이면?

 

import sys

X = int(sys.stdin.readline()) # 피제수
Y = int(sys.stdin.readline()) # 제수
cnt = 0

while X >= Y:
    X -= Y
    cnt += 1

if X == 0:
    print('{}'.format(cnt))
else: 
    print('{} ... {}'.format(cnt,X))

아니 이게 클때로 조건을 걸어두니까 피제수에서 제수 뺄 수 있는데 걍 나머지로 짬때리더라고... 그래서 등호 추가했다. 이러면 피제수와 제수가 같아질때 한번 더 빼고 나머지가 0이 된다. 아무튼... 이렇게 if문을 추가하면 나머지가 없을때는 몫만, 나머지가 있을때는 몫 ... 나머지로 출력해준다.

 

import sys

X = int(sys.stdin.readline()) # 피제수
Y = int(sys.stdin.readline()) # 제수
cnt = 0

while True:
    if X < Y:
        break
    X -= Y
    cnt += 1

if X == 0:
    print('{}'.format(cnt))
else: 
    print('{} ... {}'.format(cnt,X))

이건 While True 버전. While True는 위의 while문에 있던 조건문이 if+break 2+1 패키지로 들어간다.

 

일단 for문은 여기서부터 여기까지 해라지 조건부 반복문이 아니기때문에 while만 해봤는데, 이거 굳이 반복문 써야 하나요? 아뇨, 더 간소화 할 수 있는 방법이 있습니다.

import sys

X = int(sys.stdin.readline()) # 피제수
Y = int(sys.stdin.readline()) # 제수

if X % Y != 0:
    print('{} ... {}'.format(X // Y, X % Y))
else: 
    print(X // Y)

X // Y는 몫(int(X/Y)와 같음), X % Y는 나머지다. 그러니까 X를 Y로 나눈 나머지가 0이 아니면 몫 ... 나머지로, X를 Y로 나눈 나머지가 0이면 몫만 출력하면 된다. ㅇㅋ?

Lv. 35 라이츄

Lv. 35 라이츄

광고 매크로 없는 청정한 블로그를 위해 노력중입니다. 근데 나만 노력하는 것 같음… ㅡㅡ

Python으로 연결 리스트 구현하기

Coding/Python 2023. 9. 5. 23:29

https://koreanraichu.tistory.com/311

 

연결 리스트

JS는 토이프로젝트 해야 하는데 뭐 또 생각나면 만들겠음... 솔직히 프론트엔드가 쓸 일은 없겠지만 알아서 나쁠거 없잖아요? 아무튼. 배열은 만들 때 메모리 공간의 연속된 공간을 할당받는다.

koreanraichu.tistory.com

여기서는 대충 이론적인 설명(...)을 했다면 이제 만들어보자. 이게 왜 분리가 됐냐면 티스토리와 워드프레스는 이론 카테고리와 코딩 카테고리가 나뉘어져 있다.


오늘의 참고문헌은 

https://velog.io/@yeseolee/python-%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-%EC%97%B0%EA%B2%B0%EB%A6%AC%EC%8A%A4%ED%8A%B8Linked-List-feat.LeetCode

 

[Python 자료구조] 연결리스트(Linked List) feat.LeetCode

연결리스트는 다른 추상 자료형(Abstract Data Type)을 구현할 때 기반이 되는 기초 선형 자료구조이다.각 노드가 데이터와 포인터를 가지고 한 줄로 연결되어 있는 방식으로 데이터를 저장한다.

velog.io

https://wikidocs.net/191324

 

03. 파이썬으로 연결 리스트 구현하기

## 연결 리스트의 구조와 특징 연결 리스트는 여러 곳의 자료를 연결한 것이다. 연결 리스트는 배열처럼 선형 자료 구조이지만, 연속한 메모리 위치에 값이 저장되는 것은 아니다.…

wikidocs.net

여기다. 여기 좋은거 많데? 근데 구슬이 서 말이라도 꿰어야 보배라는데... 뭐함? IDE 켜야죠.

 

class node:
    def __init__(self, data):
        self.data = data # 노드에 들어갈 데이터 
        self.next = None # 다음 노드를 가리킬 포인터

연결 리스트는 노드로 이루어져 있고, 그 노드는 데이터와 포인터로 구성되어있다. 그니까 모든 노드들이 다 이래요. 헤드(시작) 테일(끝) 뭐 다를거 없이 걍 다 노드는 똑같다. 단지 테일 노드는 포인터가 다음을 가리키지 않을 뿐. 그러면 이거 찍어내야 할 거 아뉴? 그죠 노드 찍어낼라면 틀 짜야지.

 

head = node(1) # 헤드(첫 노드)
head.next = node(2) # 다음 노드
head.next.next = node(3) # 다음다음 노드

다른거 없고 이렇게만 해도 노드가 세 개인 연결 리스트가 생긴다. 노드는 데이터와 포인터로 이루어져 있다고 했는데, 여기서 데이터는 각각 1, 2, 3이다. 그리고 next로 노드 1의 포인터가 2를, 2의 포인터가 3을 가리키게 했다. 

 

node = head
while node:
    print(node.data)
    node = node.next

요 네 줄 추가하면 출력도 된다. while문은 대충 뭘 가리키는 애가 없는 노드(테일)까지 갈 때까지 데이터를 출력하고 다음 노드로 가시오 뭐 이런 얘기.

 

근데 생각해보자. 저 넥스트를 꼭 연결 리스트 만들때마다 줄줄이 소시지마냥 추가해야됨? 저거 백준 문제에서 본 적 있다고요? 네, 그 롱롱롱ㄹ오롱ㄹ오롱롱롱롱 그 문제임... 아무튼 일할때도 잔머리를 굴리는 본인 성미상 이런건 씁 에반데 소리가 절로 나온다. 다들 그렇잖음?

head = node("Pikachu")

여기 연결 리스트가 있다. 그래서 이 뒤에 피카츄의 진화체인 라이츄를 추가해볼건데... 사실 간단하게 head.next = node("raichu") 해도 되긴 된다. 근데 저게 막 25번째 노드고 그러면 넥스트 24번 정직하게 치실거임? 아니잖음...

 

node = head
while node:
    print(node.data)
    if node.next == None:
        node.next = Node("Raichu")
        break
    node = node.next

출력이 피카츄만 나와서 글치 추가된 거 맞다. 위에 있는 while문을 조금 응용한건데, 테일 노드(하나밖에 없음...)에 도달하면 뒤에 라이츄 노드를 붙이게 된다. 그럼 헤드에 뭐 추가할때는 어떻게 하나요?

 

node = Node("Pichu")
node.next = head
head = node

이건 세 단계로 헤드를 바꾼(...)건데, 먼저 피츄 노드를 추가하고 피츄 노드의 포인터를 피카츄(지금 헤드)를 가리키게 한 다음 피츄 노드를 헤드로 임명했다. 라이츄는 밑에 따로 추가한거라 출력 안되는데 추가된거 맞음. 근데 왜 출력이 안될까...

 

빌형! VScode 이상해!

 

아, 사실 참고문헌에는 추가만 있어서 삭제도 따로 찾아봤다.

head = Node("Pidgey")
head.next = Node("Cyndaquil")
head.next.next = Node("Totodile")

2세대 스타팅들이 있는 노드인데 자세히 보니까... 구구가 아니라 치코리타가 와야 하는 거 아녀? 반대 아닌가 

 

node = head
while node:
    if node.data == "Pidgey":
        head = head.next
        node = node.next
        break
    node = node.next

데이터가 구구면 다음 노드가 머리가 된다 뭐 이런 얘기인데, 이거는 구구 노드가 헤드라 가능한 코드다. 원래는

node = head
while node:
    if node.next.data == 5:
        node.next = node.next.next
        break
    node = node.next

다음 노드가 내가 찾는 값이면 그거 빼고 다음다음노드로 연결해서 지운다.

Lv. 35 라이츄

Lv. 35 라이츄

광고 매크로 없는 청정한 블로그를 위해 노력중입니다. 근데 나만 노력하는 것 같음… ㅡㅡ

enumerate에 대해 알아보자

Coding/Python 2023. 8. 5. 22:00

enumerate는 해시 테이블을 만들어보는 과정에서 나왔던건데, 반복문 뺑뺑이 도는 역할을 한다. 근데 이제 for문 하면 빠질 수 없는 for i in 아무개 없이 할 수 있다.

 

import sys

text = sys.stdin.readline().rstrip()

for i in text:
    print(i)

텍스트를 입력받아서 한글자씩 출력하는 코드. for문은 이렇게 쓴다. 이건 직접 글자에 접근해서 print(i)로 출력했지만 보통은 for i in range(len(text))로 주고 print문을 작성하게 된다. 그거 말고도 가끔 그럴때 있잖음. 인덱스랑 같이 뽑고 싶잖아요? 그러면 어떻게 하냐...

import sys

text = sys.stdin.readline().rstrip()

j = 0
for i in text:
    print(j, i)
    j += 1

뭐 이렇게 하든가 range를 len(text)로 하고 뽑든가 함.

 

import sys

text = sys.stdin.readline().rstrip()

for i in enumerate(text):
    print(i)

enumerate는 이렇게 쓰면 된다. 그냥 이렇게만 하면 인덱스와 요소를 튜플로 반환한다. 위 예시에서는 글자를 입력받아서 출력하는거니까 인덱스-알파벳이 쌍으로 출력되는 것이다.

이렇게 튜플로 묶어서 출력되는데... 아 이거 안이뻐... 그러면

import sys

text = sys.stdin.readline().rstrip()

for i, j in enumerate(text):
    print(i,j)

for문에 변수 두 개 주면 된다. 그러면 튜플이 깔끔하게 언패킹 돼서 출력된다.

 

import sys

text = sys.stdin.readline().rstrip()

for i, j in enumerate(text, start=1):
    print(i,j)

start= 옵션으로 시작 번호를 지정할 수도 있다. 위 코드의 경우 언패킹과 시작 번호 지정이 둘 다 된 상태.

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

나눗셈 결과 몫 ... 나머지로 표시하기  (0) 2023.10.22
Python으로 연결 리스트 구현하기  (0) 2023.09.05
zip이란 무엇인가  (0) 2023.08.04
Python으로 해시 테이블 만들어보기  (0) 2023.08.02
Python의 예외처리  (0) 2023.06.24
Lv. 35 라이츄

Lv. 35 라이츄

광고 매크로 없는 청정한 블로그를 위해 노력중입니다. 근데 나만 노력하는 것 같음… ㅡㅡ

zip이란 무엇인가

Coding/Python 2023. 8. 4. 00:15

요전에 해시 테이블 할 때 나왔던건데, zip이 뭔지 한번 알아보는 시간을 가져보자. enu뭐시기도 나중에 알아볼거니까 안심하시고.


molecule_name = ["Ethanol", "Glucose", "Methanol"]
molecule_formula = ["C2H5OH", "C6H12O6", "CH3OH"]

여기 길이 3인 1차원 배열 두 개가 있다. 이 배열 두 개를 하나로 묶고 싶은데 그럼 어떻게 하나요?

 

molecular_list = zip(molecule_name,molecule_formula)

for i in molecular_list:
    print(i)

zip()으로 묶어주면 알아서 튜플로 변환해준다.

 

molecule_name = ["Ethanol", "Glucose", "Methanol", "Formaldehyde"]
molecule_formula = ["C2H5OH", "C6H12O6", "CH3OH"]

솔직히 여기서 궁금했던 사람 있을텐데, 그럼 배열 두 개가 길이가 다르면 어떻게 될까? 앞에서부터 짝이 맞는 애들끼리 묶기때문에 뒤에 있는 포름알데히드가 빠져있는 것을 알 수 있다. zip()으로 리스트를 묶을 때는 두 리스트의 0번-0번, 1번-1번 이런 식으로 순차적으로 묶기 때문에 중간에 데이터가 빠져버리면 아 망했어요가 된다.

 

molecule_name = ["Ethanol", "Glucose", "Methanol", "Formaldehyde"]
molecule_formula = ["C2H5OH", "C6H12O6", "CH3OH", "HCHO"]

molecular_list = dict(zip(molecule_name,molecule_formula))

이런 식으로 딕셔너리로 묶을 수도 있다. 그럼 이거 키랑 밸류 같이 뽑고 싶으면 어떻게 하냐고?

 

print(molecular_list)

딕셔너리는 위처럼 반복문 주면 키만 나오고, 전체 다 뽑을거면 이렇게 해야 한다. 

for i, j in molecular_list.items():
    print(i, j)

키-밸류 쌍을 반복문 줘서 뽑을거면 이렇게 주면 된다.

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

Python으로 연결 리스트 구현하기  (0) 2023.09.05
enumerate에 대해 알아보자  (0) 2023.08.05
Python으로 해시 테이블 만들어보기  (0) 2023.08.02
Python의 예외처리  (0) 2023.06.24
n진수->10진수 코딩하기  (0) 2023.06.16
Lv. 35 라이츄

Lv. 35 라이츄

광고 매크로 없는 청정한 블로그를 위해 노력중입니다. 근데 나만 노력하는 것 같음… ㅡㅡ

Python으로 해시 테이블 만들어보기

Coding/Python 2023. 8. 2. 23:44

https://koreanraichu.tistory.com/289

 

해시 테이블

처음 설명을 본 본인 표정: 그럴만 했다. 뭔 소린지 1도 모르겠거든... 일단 얘는 자료구조다. 이름이 테이블인데 왜 자료구조인지는 주변에 계신 개발자에게 물어보도록. 아무튼 이 테이블은 데

koreanraichu.tistory.com

여기서 이어진다.

 

솔직히 이론적인거 백날 설명해봐야 뭔 소린지 모르잖음? 그니까 같이 만들어봅시다. 참고로 이번에 참고한 곳은 https://wikidocs.net/193049

 

06. 파이썬으로 해시 테이블 구현하기

해시 테이블은 언어에 따라 해시 맵, 사전 등으로 부른다. 해시 테이블은 키(key)와 값(value)으로 구성된 자료 구조다. 여기서 중요한 것은 해시함수다. 키를 해시함수에 …

wikidocs.net

여기다. 


쿠키 틀 짜기

뭔 코딩하다말고 쿠키 타령이여? 아, 먹는 쿠키 말고... 클래스를 만들건데, 이 클래스를 보통 쿠키 틀에 비유한다. 쿠키 틀로 쿠키 찍는거랑 클래스가 비슷한가봄. 그거랑 별개로 치즈쿠키 먹고싶다...

 

class Hash_table:
    def __init__(self, length = 5):
        self.max_len = length
        self.table = [[] for _ in range(self.max_len)]
    
    def hash(self, key): # 해시 테이블에 key와 value를 넣는다. 
        res = sum([ord(s) for s in key])
        return res % self.max_len

    def set(self, key, value):
        index = self.hash(key)
        self.table[index].append((key, value))

    def get(self, key): # 해시 테이블에서 key의 value를 찾는다.
        index = self.hash(key)
        value = self.table[index]
        if not value:         # 찾는 키가 없으면 None을 반환
            return None
        for v in value:       # 리스트에서 값을 찾아 반환 
            if v[0] == key:
                return v[1]
        return None

이게 해시 테이블을 찍어내기 위한 쿠키 틀이다. 위쪽은 해시 테이블의 길이를 정하는 것 같고... hash는 키랑 밸류를 넣는 거고, 밑에 있는 게 해시 함수다. 여기서는 아스키 코드의 총 합을 테이블의 길이로 나눠서 해시를 만드는데(해시 함수가 만드는 게 해시), 이거 입력이 한글이면 다른 방법을 써야 한다. 밑에 있는 set은 아마 키값을 넣고 변환된 해시가 나오면 그 해시에 인덱싱하는 것 같고... 그 밑에 있는 건 해시 테이블에서 키를 이용해 값을 찾는 거다.

 

아, 밑에 if문이요? 해시 테이블에서 값 찾았는데 없을 때 None이라고 뜨게 하라는 얘기.

 

if __name__ == "__main__":
    capital = Hash_table()
    country = ["Korea", "America", "China", "England", "Türkiye"]
    city = ["Seoul", "Washington", "Beijing", "London", "Ankara"]
    for co, ci in zip(country, city):
        capital.set(co, ci)

    print("해시 테이블의 상태")
    print("===============")
    for i, v in enumerate(capital.table):
        print(i, v)
    print()
    print("해시 테이블의 검색 결과")
    print("====================")
    print(f"Captial of America = {capital.get('America')}")
    print(f"Captial of Korea = {capital.get('Korea')}")
    print(f"Captial of England = {capital.get('England')}")
    print(f"Captial of China = {capital.get('China')}")
    print(f"Captial of Japan = {capital.get('Japan')}")
    print(f"Captial of Türkiye = {capital.get('Türkiye')}")

그래서 이 과정을 거치면 해시 테이블이 완겅된다. 검색 결과에 있는 건 말 그대로 .get을 이용해 해시 테이블에서 검색한 결과.

 

if __name__ == "__main__":
    pokemon = Hash_table()
    name = ["Metagross", "Gengar", "Raichu", "Yveltal", "Glimmora"]
    nickname = ["김메탕", "최팬텀", "왕뚠뚠돈까스", "냉동차돌박이", "라피스라줄리"]
    for name, nickname in zip(name, nickname):
        pokemon.set(name, nickname)

    print("해시 테이블의 상태")
    print("===============")
    for i, v in enumerate(pokemon.table):
        print(i, v)
    print()
    print("해시 테이블의 검색 결과")
    print("====================")
    print(f"Metagross = {pokemon.get('Metagross')}")
    print(f"Gengar = {pokemon.get('Gengar')}")
    print(f"Raichu = {pokemon.get('Raichu')}")
    print(f"Yveltal = {pokemon.get('Yveltal')}")
    print(f"Glimmora = {pokemon.get('Glimmora')}")
    print(f"Beldum = {pokemon.get('Beldum')}")

해시 메소드 건들기 싫어서 포켓몬은 영칭으로 넣었음... 아무튼. 리스트가 클래스 안에 있는 게 아니기때문에 리스트 안에 있는 건 얼마든지 바꿀 수 있다. 키값은 포켓몬의 영어 이름(그니까 이름), 밸류는 내가 실제로 지어준 닉네임이다. 

 

아니 아스키코드 합을 5로 나눈건데 충돌만 세개 실화냐...

 

pokemon = Hash_table()
name = ["Swadloon", "Ferroseed", "Tinkaton", "Yveltal", "Raichu", "Nihilego", "Metagross", "Gengar", "Goodra", "Primarina", "Glimmora", "Brute Bonnet", "Iron bundle", "Heatran", "Zygarde", "Goomy", "Flutter Mane"]
nickname = ["망개떡", "김철시드", "웨폰브레이커", "냉동차돌박이", "왕뚠뚠돈까스", "김부추곱창씨", "김메탕", "김팬텀", "타로블루베리", "세탁기고장남", "라피스라줄리", "고혈압버섯", "메탈딸배몬", "모쏠드런선생", "우로보로스", "딸기바닐라", "퀘찰코아틀"]
for name, nickname in zip(name, nickname):
    pokemon.set(name, nickname)

for i, v in enumerate(pokemon.table):
    print(i, v)

해시 테이블을 만들 리스트 자체의 길이는 상관 없다. 길이 넘는다고 오류뜨는 거 아님.

 

아, 그래서 zip이랑 enu머시기는 뭐냐고? zip은 저기 리스트 두 개를 튜플로 묶어서 반환하는건데 리스트의 0번 0번끼리 묶는다. enu머시기는 반복문 도는거라는데 나중에 자세히 다뤄보겠음.

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

enumerate에 대해 알아보자  (0) 2023.08.05
zip이란 무엇인가  (0) 2023.08.04
Python의 예외처리  (0) 2023.06.24
n진수->10진수 코딩하기  (0) 2023.06.16
강해져서 돌아온 ChatGPT에게 코딩을 시켜보자 (번외편)  (0) 2023.04.29
Lv. 35 라이츄

Lv. 35 라이츄

광고 매크로 없는 청정한 블로그를 위해 노력중입니다. 근데 나만 노력하는 것 같음… ㅡㅡ

Python의 예외처리

Coding/Python 2023. 6. 24. 01:09

예외처리... 쉽게 설명하자면 에러가 떴을 때 어떻게 할 지 코딩하는거라고 보면 된다. 예를 들어서 웹서핑을 하다 보면 보이는 이런게 있는데

대충 이런거. 404 뜨면 404 페이지를 띄우시오 이런 느낌이라고 보면 된다. 당연한 얘기지만 자바스크립트에도 예외처리가 있다. 나중에 함 다뤄보겠음.

 

나무위키의 정의에 따르면 예외처리는 '예외 처리(Exception Handling) 혹은 오류 처리(Trouble Shooting)란 실행 흐름상 오류가 발생했을 때 오류를 그대로 실행시키지 않고 오류에 대응하는 방법을 제시하는 개념이나 하드웨어 구조를 의미한다. 일반적으로 프로그래밍에서 프로그램이 실행 중 특정 문제가 발생했을 때 다른 처리 방식으로 흐름을 옮기는 개념으로 사용한다.'라고 한다. 예를 들어서 계산기를 코딩했는데 사용자가 0으로 나눈다, 그러면 제로디비전이 나온다. 그럴 때 메시지를 띄우거나 걍 0으로 내보내는 등의 방법을 컴퓨터한테 제시하는 것이다. 가끔 본인 백준 풀이에도 나온다.


try except

트라이 캐치 파이널리 레이즈 뭐 많은데 일단 이 두개만 외워둡시다. try에는 실행할 코드가, except에는 에러가 떴을 때 어떻게 처리할지가 들어간다. 예를 들어보자.

 

import sys

A, B = map(int,sys.stdin.readline().split())

print(A/B)

이 코드 실행하고 0 0쓰면

컴퓨터가 미쳤습니까 휴먼? 한다. 그 왜 그런지는 이 블로그 어딘가에 있는 백준 풀이를 찾아보시면 압니다... 부정과 불능에 대해 설명했는데 몇번문제인지 까먹음. 아무튼... 근데 이거 처리 안하고 내보내면 사용자 입장에서도 그렇게 좋진 않을거란 말이지? 사용법에 0 0 쓰지 마세요라고 하면 꼭 쓰는 사람 나옵니다.

 

import sys

A, B = map(int,sys.stdin.readline().split())

try:
    print(A/B)
except:
    print('0으로 나눌 수 없습니다!')

이게 파이썬이라 그렇지 자바스크립트였으면 alert 띄웠음... (alert: 알림창 띄우는거) 위 코드 구조도 간단하다. 두 수를 입력받고 A/B를 계산하되, ZeroDivisionError가 뜨는 상황에는 except에 있는 메시지를 띄워라, 이걸로 이해하면 쉽다.

 

출처: 코딩도장, ▼ 그림 38-1 예외 발생과 except

여기 잘가르칩니다. 함 해보십쇼. 아무튼... 이 그림이 매우 설명이 적절하다. 실행하려고 했더니 에러뜸? 그럼 익셉트로 고고싱! 오케이?

 

import sys

A, B = map(int,sys.stdin.readline().split())

try:
    print(A/B)
except ZeroDivisionError:
    print('0으로 나눌 수 없습니다!')

에러 종류가 한두개가 아닌데 except 하나로 처리하기가 거시기하면 이런 식으로 오류 종류에 따라 다르게 처리하도록 지정할 수도 있다. 위 코드도 동일한 역할이지만 ZeroDivisionError일 때는 이렇게 하라고 세부적으로 지시한 것. 저 경우 ZeroDivisionError, IndexError 등 여러가지 에러일때 메시지를 다르게 표기할 수 있다.

 

import sys

A, B = map(int,sys.stdin.readline().split())

try:
    print(A/B)
except ZeroDivisionError as e:
    print('0으로 나눌 수 없습니다!')
    print(e)

except A as e 형식으로 해당 예외에 대한 에러 메시지를 받아올 수도 있다. 그리고 print(e)를 추가하면 여기에 대한 에러 메시지도 출력해준다. 그리고 except Exception as e 형식을 쓰면 모든 예외에 대한 에러 메시지를 출력할 수 있다. 근데 저 코드로 발생시킬 수 있는 에러가 제로디비전 말고 없음...

 

else&finally

else는 if 친구 아니냐고? 얘네랑도 노나보죠 뭐.

 

import sys

A, B = map(int,sys.stdin.readline().split())

try:
    x = A/B
except:
    print('0으로 나눌 수 없습니다!')
else: 
    print(x)

이게 되게 웃긴게 else가 위로 가면 

미쳤습니까 휴먼? 한다. 순서가 바꼈을 뿐인데 말이지.

 

else는 예외가 발생하지 '않았을 때' 실행할 코드가 들어간다. 즉 저 세개는 각각 1) A/B를 계산하는데 2) 제로디비전 뜨면 0으로 못 나눈다 하고 3) 아님 출력하슈 인 셈.

 

import sys

A, B = map(int,sys.stdin.readline().split())

try:
    x = A/B
except:
    print('0으로 나눌 수 없습니다!', e)
else: 
    print(x)
finally:
    print('퐈이널리!')

finally는 예외 발생 여부와 상관없이 항상 실행하는 코드다. 저거는 예외 발생됐을 때 결과잖음?

정상적으로 실행됐을때도 저게 나온다.

 

raise

코딩하다 보면 가끔 예외를 발생시켜야 할 때가 있다. 아무튼 그럴 때 쓰는게 raise다.

 

import sys

A = int(sys.stdin.readline())

try:
    if A % 2 == 1:
        raise Exception('Odd number!')
except Exception as e:
    print('Error: ', e)
finally:
    print(A)

위 코드는 입력받은 수가 '홀수이면' 예외가 발생하는 코드다. 그럼 저걸 실행해보실까?

 

홀수, 즉 2로 나누어서 나머지가 1인 수가 들어오면 예외가 발생하게 되어서 예외처리를 하게 된다. 밑에 있는 5는 finally때문에 출력된 것.

 

예전에 만들었던 프로젝트 제한효소의 경우 지원하는 파일이 FASTA(*.fasta)와 Genbank(*.gb)인데, 이 경우 두 파일이 '아닌' 다른 파일을 업로드했을 때 예외를 발생시킨 다음 예외처리를 할 수도 있다.

import sys

file = sys.stdin.readline().rstrip()

try:
    if file.find('fasta') == -1 and file.find('gb') == -1:
        raise Exception('지원하는 파일이 아닙니다.')
except Exception as e:
    print('Error: ', e)
else: 
    print('파일 업로드가 완료되었습니다. ')

이놈들 대체 뭘로 묶어야 정상작동 하는건지...

 

아무튼 이런 식으로 FASTA나 Genbank파일이 아닌 다른 파일을 올리면 예외를 발생시킬 수도 있다. 아마 지금 코딩된거는 FASTA, Genbank 파일에 하나 있을 때 or 여러개 있을 때로 예외처리해서 처리가 되고 있지만, 사실 구체적으로 들어가자면 FASTA, Genbank파일이 아닌 다른 파일이 올라왔을때도 이런 식으로 해야 한다. 근데 어차피 저거 브라우저 띄울때 FASTA랑 Genbank파일만 찾아서 상관 없음.

 

import sys

def even_number():
    X = int(sys.stdin.readline())
    if X % 2 == 1:
        raise Exception('홀수입니다!')
    print(X)

try:
    even_number()
except Exception as e:
    print(e)

raise는 함수 안에 넣고 예외처리는 밖에서 할 수도 있다. 단, 저게 없이 그냥 함수를 실행하고 홀수를 입력하면 코드가 중단되고 에러가 뜨게 된다.

 

import sys

def even_number():
    try:
        X = int(sys.stdin.readline())
        if X % 2 == 1:
            raise Exception('홀수입니닷!')
        print(X)
    except Exception as e:
        print('아 사실 그거 홀수였음! ', e)
        raise

try:
    even_number()
except Exception as e:
    print('스크립트에서 문제가 발생하였습니다.', e)

그... 발생시켰던 예외를 다시 발생시킬 수도 있다. 응? 이거 완전 죽은자의 소생 아니냐? 아무튼 저 코드를 실행하면 어떻게 되느냐...

안에서 한번 예외가 발생해서 처리했는데 이걸 밖에서 또 처리한다. 진정한 예토전생이여.

 

import sys

def even_number():
    try:
        X = int(sys.stdin.readline())
        if X % 2 == 1:
            raise Exception('홀수입니닷!')
        print(X)
    except Exception as e:
        print('아 사실 그거 홀수였음! ', e)
        raise RuntimeError('실행하다가 문제가 발생했습니다. ')

try:
    even_number()
except Exception as e:
    print('스크립트에서 문제가 발생하였습니다.', e)

함수 안에 있는 raise에 다른 예외처리를 지정하고 re-raise 한 결과.

어째 더 정신사나워졌어...

 

한번에 다 이해하기 당연히 힘들다. 그게 가능한 개쌉고수들은 여기 올 일이 없어요 벌써 버그터진거 해결하고 담탐 하러 갔지... 아니면 카페인 공급중이거나. 일단 try except까지만 알고 있어도 한결 편해질것이다.

Lv. 35 라이츄

Lv. 35 라이츄

광고 매크로 없는 청정한 블로그를 위해 노력중입니다. 근데 나만 노력하는 것 같음… ㅡㅡ

방명록