Categories: Python

파이썬 초보자가 자주 만나는 오류와 해결 방법

파이썬은 간결하고 배우기 쉬운 언어로 칭송받지만, 초보자에게는 예상치 못한 오류의 벽에 부딪히는 경험이 흔히 발생합니다. 본 포스팅에서는 파이썬 초보자들이 frequently 마주치는 까다로운 오류들을 분석하고, 이를 효과적으로 해결하는 전략을 제시합니다. `파이썬 초보자가 자주 만나는 오류와 해결 방법` 에 대한 명쾌한 이해를 돕기 위해, 오류 메시지 분석 및 이해, 디버깅 기술과 도구 활용, 효율적인 오류 해결 전략, 그리고 흔한 파이썬 오류 유형까지 체계적으로 다룰 것입니다. 이 글을 통해 여러분은 오류를 두려워하기보다, 문제 해결 능력을 향상시키는 발판으로 삼아 파이썬 학습의 효율을 극대화할 수 있을 것입니다.

 

 

흔한 파이썬 오류 유형

파이썬은 초보자에게 친숙한 언어로 알려져 있지만, 코딩 과정에서 예기치 못한 오류와 마주치는 것은 피할 수 없는 숙명과도 같습니다. 마치 탐험가가 새로운 대륙을 탐험하면서 예상치 못한 암초를 만나는 것처럼 말이죠! 이러한 오류들은 당황스럽고 좌절감을 안겨줄 수 있지만, 걱정 마세요! 대부분의 오류는 유형별로 분류되며, 각 유형에 따른 해결 방법이 존재합니다. 이 섹션에서는 파이썬 초보자가 가장 자주 접하는 오류 유형들을 분석하고, 각 유형의 특징과 해결 전략을 제시하여 여러분의 탐험을 돕겠습니다. 자, 그럼 본격적으로 파이썬 오류의 세계를 탐험해 볼까요?

NameError

1. NameError: name ‘…’ is not defined: 아마도 파이썬 초보자들이 가장 많이 마주치는 오류일 겁니다. 변수나 함수를 사용하기 전에 정의하지 않았거나, 변수/함수명의 오타로 인해 발생합니다. 예를 들어, `pirnt(“Hello”)`라고 입력하면 NameError: name 'pirnt' is not defined 오류가 발생하는데, 이는 print 함수의 이름을 잘못 입력했기 때문입니다. 해결책은 간단합니다. 변수나 함수를 사용하기 전에 올바른 이름으로 정의하고, 오타가 없는지 꼼꼼히 확인하세요! 마치 지도에서 목적지를 정확히 표시해야 길을 잃지 않는 것과 같은 이치입니다.

TypeError

2. TypeError: unsupported operand type(s) for …: 서로 다른 데이터 유형 간에 호환되지 않는 연산을 수행하려고 할 때 발생하는 오류입니다. 예를 들어, 문자열과 정수를 더하려고 하면 "Hello" + 1과 같이 오류가 발생합니다. 이런 경우, 각 데이터 유형에 맞는 연산을 수행하거나, str(), int(), float() 등의 함수를 사용하여 데이터 유형을 변환해야 합니다. 마치 사과와 오렌지를 비교하려면 둘 다 과일이라는 공통점을 찾아야 하는 것처럼 말이죠!

SyntaxError

3. SyntaxError: invalid syntax: 파이썬 문법 규칙에 어긋나는 코드를 작성했을 때 발생하는 오류입니다. 콜론(:)을 빠뜨리거나, 들여쓰기가 잘못되었거나, 괄호의 짝이 맞지 않는 등 다양한 원인으로 인해 발생할 수 있습니다. 파이썬 인터프리터는 오류가 발생한 위치를 표시해 주므로, 해당 위치를 중심으로 문법 오류를 찾아 수정해야 합니다. 마치 악보를 읽을 때 음표와 쉼표를 정확히 해석해야 아름다운 음악을 연주할 수 있는 것과 같습니다.

IndentationError

4. IndentationError: expected an indented block: 파이썬은 코드 블록을 들여쓰기를 통해 구분합니다. if, for, while, def 등의 문장 다음에는 반드시 들여쓰기 된 코드 블록이 와야 합니다. 들여쓰기가 없거나, 들여쓰기의 깊이가 일관되지 않으면 IndentationError가 발생합니다. 따라서 코드 블록의 시작과 끝을 명확하게 하기 위해 일관된 들여쓰기를 유지해야 합니다. 파이썬에서는 일반적으로 공백 4칸을 사용하여 들여쓰기를 합니다. 마치 건축물을 지을 때 기초 공사가 튼튼해야 멋진 건물을 완성할 수 있는 것과 같은 원리입니다.

IndexError

5. IndexError: list index out of range: 리스트나 튜플과 같은 시퀀스 데이터에서 존재하지 않는 인덱스에 접근하려고 할 때 발생합니다. 예를 들어, 길이가 3인 리스트에서 인덱스 3에 접근하려고 하면 IndexError가 발생합니다. (리스트의 인덱스는 0부터 시작하므로, 유효한 인덱스는 0, 1, 2입니다.) 따라서 시퀀스 데이터의 길이를 확인하고 유효한 인덱스 범위 내에서 접근해야 합니다. 마치 책에서 없는 페이지를 찾으려고 하면 찾을 수 없는 것과 마찬가지입니다.

KeyError

6. KeyError: …: 딕셔너리에서 존재하지 않는 키를 사용하여 값에 접근하려고 할 때 발생합니다. 딕셔너리에 특정 키가 있는지 확인한 후에 값에 접근하거나, get() 메서드를 사용하여 키가 없을 경우 기본값을 반환하도록 할 수 있습니다. 마치 비밀번호가 틀리면 금고를 열 수 없는 것과 같은 이치입니다.

ValueError

7. ValueError: …: 함수에 잘못된 값이 전달되었을 때 발생하는 오류입니다. 예를 들어, int() 함수에 정수로 변환할 수 없는 문자열을 전달하면 ValueError가 발생합니다. 함수에 전달되는 값의 유형과 범위를 확인하고, 적절한 값을 전달해야 합니다. 마치 열쇠 구멍에 맞지 않는 열쇠를 억지로 넣으려고 하면 열쇠가 부러지는 것과 같습니다.

AttributeError

8. AttributeError: ‘…’ object has no attribute ‘…’: 객체가 가지고 있지 않은 속성이나 메서드에 접근하려고 할 때 발생합니다. 객체의 클래스와 사용 가능한 속성/메서드를 확인하고, 올바른 속성/메서드에 접근해야 합니다. 마치 자동차에 없는 기능을 사용하려고 하면 사용할 수 없는 것처럼 말이죠!

이 외에도 다양한 오류 유형이 존재하지만, 위에서 언급한 오류들은 파이썬 초보자들이 가장 흔하게 마주치는 오류들입니다. 각 오류 유형의 특징과 해결 방법을 숙지하고, 오류 메시지를 주의 깊게 분석한다면 오류 해결 능력을 향상시키고, 더욱 효율적으로 파이썬 프로그래밍을 할 수 있을 것입니다. 마치 숙련된 탐험가가 지도와 나침반을 활용하여 미지의 세계를 탐험하는 것처럼 말이죠! 다음 섹션에서는 오류 메시지를 분석하고 이해하는 방법에 대해 자세히 알아보겠습니다.

 

오류 메시지 분석 및 이해

파이썬 코딩의 세계에 발을 들여놓았다면, 오류 메시지와의 만남은 피할 수 없는 숙명과도 같습니다. 마치 험난한 등반 과정에서 만나는 낙석처럼 말이죠! 하지만 좌절하지 마세요! 오류 메시지는 단순한 에러 보고가 아닌, 문제 해결의 실마리를 제공하는 친절한 안내자일 수 있습니다. 핵심은 바로 그 메시지를 제대로 ‘읽는’ 능력에 있습니다. 마치 암호 해독가처럼 말이죠.🕵️‍♀️

자, 그럼 오류 메시지를 분석하고 이해하는 핵심 전략을 하나씩 파헤쳐 보겠습니다. 마치 보물 지도를 따라 숨겨진 보물을 찾아 나서듯 말이죠!

1. 오류 유형 파악

가장 먼저 해야 할 일은 오류의 유형을 파악하는 것입니다. SyntaxError, TypeError, NameError, ValueError, IndexError… 등등, 다양한 오류 유형은 각기 다른 문제를 나타냅니다. 예를 들어 SyntaxError는 파이썬 문법 규칙을 위반했을 때 발생합니다. 마치 한국어 문장에서 조사를 잘못 사용한 것과 같죠! TypeError는 데이터 유형이 호환되지 않을 때 발생하는데, 숫자와 문자열을 더하려고 시도하는 경우를 생각해 보세요. 🤯 NameError는 정의되지 않은 변수를 사용할 때 발생합니다. 마치 존재하지 않는 사람을 찾는 것과 같습니다!👻 이처럼 오류 유형을 정확히 파악하는 것은 문제 해결의 첫걸음입니다.

2. 오류 메시지 상세 분석

오류 유형을 파악했다면, 이제 오류 메시지 자체를 자세히 들여다볼 차례입니다. 오류 메시지는 일반적으로 오류 유형, 발생 위치, 그리고 간략한 설명을 제공합니다. 예를 들어, TypeError: unsupported operand type(s) for +: 'int' and 'str'라는 메시지가 나타났다고 가정해 봅시다. 이 메시지는 정수형(int)과 문자열형(str) 데이터에 대해 덧셈 연산(+)을 수행할 수 없다는 것을 명확하게 알려주고 있습니다. 마치 사과와 오렌지를 더할 수 없는 것과 같은 이치죠! 🍎🍊 오류 메시지의 각 부분을 꼼꼼히 살펴보면 문제의 원인을 파악하는 데 큰 도움이 됩니다.

3. 발생 위치 확인

오류 메시지는 대부분 오류가 발생한 파일 이름과 줄 번호를 함께 제공합니다. 예를 들어, File "my_script.py", line 12, in 와 같은 정보는 my_script.py 파일의 12번째 줄에서 오류가 발생했음을 나타냅니다. 마치 사건 현장을 특정하는 것과 같죠! 🚨 이 정보를 활용하여 해당 코드 라인을 집중적으로 분석하면 문제의 근원을 빠르게 찾아낼 수 있습니다. 코드 라인 주변의 변수 값, 함수 호출, 조건문 등을 꼼꼼히 검토하여 오류의 원인을 추적해 보세요!

4. Traceback 활용

복잡한 프로그램에서 오류가 발생한 경우, Traceback 정보는 매우 유용한 단서를 제공합니다. Traceback은 오류가 발생하기까지의 함수 호출 순서를 역순으로 보여주는 일종의 ‘발자취’라고 할 수 있습니다. 마치 탐정이 범인의 이동 경로를 추적하는 것과 같죠!🕵️‍♂️ Traceback을 따라가면서 각 함수의 입력값과 출력값을 확인하고, 어느 부분에서 문제가 발생했는지 파악할 수 있습니다. 이를 통해 오류의 근본 원인을 찾아내고 효과적인 해결책을 마련할 수 있습니다.

5. 온라인 리소스 활용

만약 오류 메시지 분석만으로 문제 해결이 어렵다면, 온라인 리소스의 도움을 받는 것도 좋은 방법입니다. Stack Overflow, 공식 파이썬 문서, 다양한 파이썬 커뮤니티 등에는 수많은 개발자들이 공유한 경험과 지식이 풍부하게 담겨 있습니다. 마치 거대한 지식의 바다에서 정보를 건져 올리는 것과 같죠! 🎣 자신이 직면한 오류 메시지나 관련 키워드를 검색하면 유사한 문제를 해결한 사례들을 찾을 수 있을 겁니다. 다른 개발자들의 해결 방법을 참고하여 자신의 문제에 적용해 보고, 필요에 따라 질문을 통해 도움을 요청하는 것도 좋은 방법입니다.

자, 이제 여러분은 오류 메시지 분석 및 이해의 핵심 전략들을 손에 넣었습니다. 마치 비밀 무기를 장착한 것과 같죠! 💪 더 이상 오류 메시지에 겁먹지 말고, 적극적으로 분석하고 이해하여 파이썬 코딩의 여정을 성공적으로 이어나가시길 바랍니다! 🚀

 

디버깅 기술과 도구 활용

파이썬 코딩의 세계에 뛰어들었다면, 오류와의 만남은 피할 수 없는 숙명과도 같습니다. 마치 탐험가가 험난한 정글을 헤쳐 나가듯, 프로그래머도 복잡한 코드 속에서 버그라는 괴물과 싸워야 하죠. 하지만 두려워하지 마세요! 적절한 디버깅 기술과 도구만 있다면, 이 괴물을 길들일 수 있습니다. 마치 숙련된 탐험가가 나침반과 지도를 활용하듯 말이죠. 자, 이제 여러분을 파이썬 디버깅의 달인으로 만들어줄 비법을 전수해 드리겠습니다.

print() 함수 활용

가장 기본적인 디버깅 방법은 print() 함수를 활용하는 것입니다. 코드의 특정 지점에 print() 함수를 삽입하여 변수의 값이나 프로그램의 흐름을 확인할 수 있습니다. 예를 들어, 복잡한 반복문 내부에서 변수의 값 변화를 추적하고 싶다면, 반복문 안에 print() 함수를 넣어 각 단계별 변수 값을 출력해 볼 수 있죠. 이는 마치 탐험가가 정글을 탐험하며 자신의 위치를 표시하는 것과 같습니다.

pdb (Python Debugger)

하지만 코드가 복잡해지면 print() 함수만으로는 부족할 수 있습니다. 이때 필요한 것이 바로 파이썬의 내장 디버거인 pdb입니다. pdb를 사용하면 코드 실행을 일시 중지하고, 변수의 값을 확인하거나 코드를 단계별로 실행하며 오류의 원인을 파악할 수 있습니다. pdb는 마치 탐험가의 돋보기처럼, 코드의 미세한 부분까지 들여다볼 수 있게 해줍니다. pdb.set_trace() 함수를 코드에 삽입하면 해당 지점에서 프로그램 실행이 중단되고 디버깅 모드로 진입합니다. n 명령어를 사용하면 다음 라인으로 이동하고, s 명령어를 사용하면 함수 내부로 진입할 수 있습니다. p 명령어를 사용하면 변수의 값을 출력하고, c 명령어를 사용하면 다음 중단점까지 실행하거나 프로그램을 종료할 수 있습니다. pdb는 강력한 디버깅 도구이지만, 명령어를 숙지해야 효율적으로 사용할 수 있다는 점을 기억하세요!

IDE 디버깅 기능 활용

더 나아가, IDE(통합 개발 환경)의 디버깅 기능을 활용하면 더욱 효율적인 디버깅이 가능합니다. 대표적인 파이썬 IDE인 VS Code, PyCharm 등은 강력한 디버깅 기능을 제공합니다. 이러한 IDE는 코드의 실행을 시각적으로 제어하고, 변수의 값 변화를 그래프로 표시하는 등 다양한 기능을 제공합니다. 마치 탐험가에게 최첨단 GPS 장비를 제공하는 것과 같죠. IDE의 디버깅 기능을 잘 활용하면 오류 해결 시간을 단축하고 생산성을 높일 수 있습니다. 예를 들어, VS Code의 디버깅 기능을 사용하면 중단점을 설정하고, 변수 값을 실시간으로 확인하며, 코드를 단계별로 실행할 수 있습니다. PyCharm은 더욱 고급 기능을 제공하는데, 예를 들어 변수 값의 변화를 그래프로 표시하여 오류 발생 패턴을 분석하는 데 도움을 줍니다.

로깅(Logging)

복잡한 코드를 디버깅할 때, 로깅(Logging)은 매우 유용한 도구입니다. 로깅은 프로그램의 실행 과정을 기록하는 것으로, 오류 발생 시점과 원인을 파악하는 데 도움을 줍니다. 파이썬의 logging 모듈을 사용하면 다양한 레벨(DEBUG, INFO, WARNING, ERROR, CRITICAL)로 로그를 기록할 수 있습니다. 예를 들어, logging.debug() 함수를 사용하면 디버깅 정보를 기록하고, logging.error() 함수를 사용하면 오류 정보를 기록할 수 있습니다. 로깅은 마치 탐험가의 탐험 일지처럼, 프로그램의 실행 과정을 상세하게 기록하여 오류 해결에 필요한 단서를 제공합니다.

온라인 리소스 활용

마지막으로, 오류 해결에 도움이 되는 다양한 온라인 리소스를 활용하는 것도 좋은 방법입니다. Stack Overflow와 같은 온라인 커뮤니티에는 수많은 파이썬 개발자들이 질문하고 답변을 공유하고 있습니다. 이러한 커뮤니티를 활용하면 다른 개발자들의 경험과 지식을 통해 오류 해결의 실마리를 찾을 수 있습니다. 또한, 파이썬 공식 문서와 다양한 파이썬 학습 사이트에서 디버깅 관련 정보를 얻을 수 있습니다. 이러한 온라인 리소스는 마치 탐험가에게 조언을 해주는 현지 가이드와 같습니다.

자, 이제 여러분은 파이썬 디버깅의 세계를 탐험할 준비가 되었습니다! print() 함수, pdb, IDE 디버깅 기능, 로깅, 온라인 리소스 등 다양한 도구와 기술을 활용하여 버그라는 괴물을 정복하고, 파이썬 코딩의 정글을 자유롭게 탐험해 보세요! 기억하세요, 효과적인 디버깅은 단순히 오류를 수정하는 것을 넘어, 더 나은 코드를 작성하고 프로그래밍 실력을 향상시키는 핵심 열쇠입니다! 끊임없는 연습과 탐구를 통해 디버깅의 달인이 되어보세요!

 

효율적인 오류 해결 전략

파이썬 코딩의 세계에 뛰어들면, 오류는 피할 수 없는 동반자와 같습니다. 마치 그림자처럼 따라다니죠! 하지만 좌절할 필요는 없습니다. 효율적인 오류 해결 전략만 갖춘다면, 이러한 오류들을 정복하고 더욱 숙련된 개발자로 거듭날 수 있습니다. 마치 탐정처럼 말이죠!🕵️‍♀️

자, 그럼 본격적으로 오류 해결의 미로를 헤쳐나가는 데 필요한 나침반과 지도를 준비해 볼까요?

재현 가능성 확보

첫 번째 나침반은 바로 ‘재현 가능성 확보’입니다. 버그를 수정하려면 먼저 문제를 일관되게 재현할 수 있어야 합니다. 마치 과학 실험처럼 동일한 조건에서 동일한 결과가 나와야 분석이 가능하겠죠? 입력 값, 환경 변수, 코드 실행 순서 등 모든 요소를 꼼꼼히 기록하고, 필요하다면 자동화된 테스트 케이스를 작성하는 것도 좋은 방법입니다. 이를 통해 80% 이상의 오류 재현율을 확보할 수 있다는 연구 결과도 있습니다!

오류 메시지 분석

두 번째 나침반은 ‘오류 메시지 분석’입니다. 오류 메시지는 단순한 에러 보고가 아닌, 문제 해결의 중요한 단서를 제공하는 보물 지도와 같습니다. 마치 숨겨진 메시지를 해독하는 것처럼, 오류 유형(TypeError, ValueError, NameError 등), 발생 위치(파일명, 라인 번호), 그리고 구체적인 내용을 꼼꼼히 살펴보세요. 예를 들어 “TypeError: unsupported operand type(s) for +: ‘int’ and ‘str'”라는 메시지는 정수형과 문자열형 데이터를 더하려고 했기 때문에 발생한 오류임을 명확히 알려주고 있습니다.

분할 정복

세 번째 지도는 ‘분할 정복’입니다. 복잡한 코드에서 오류를 찾는 것은 마치 넓은 들판에서 바늘 찾기와 같습니다. 이럴 때는 코드를 작은 단위로 나누어 문제의 범위를 좁혀 나가는 것이 효과적입니다. 함수 호출, 조건문, 반복문 등 논리적인 블록 단위로 코드를 분리하고, 각 블록의 입출력 값을 확인하면서 오류의 원인을 추적해 보세요. 마치 미로를 탐험하듯, 한 걸음씩 나아가다 보면 출구를 발견할 수 있을 것입니다.

로깅 활용

네 번째 지도는 ‘로깅 활용’입니다. 프로그램 실행 과정을 기록하는 로깅은 오류 해결의 숨은 조력자와 같습니다. 마치 블랙박스처럼 프로그램의 상태 변화를 추적하고, 변수 값, 함수 호출 순서, 예외 발생 시점 등 중요한 정보를 기록해 둡니다. Python의 logging 모듈을 사용하면 다양한 로그 레벨(DEBUG, INFO, WARNING, ERROR, CRITICAL)로 정보를 기록하고, 필요에 따라 로그 파일이나 데이터베이스에 저장할 수 있습니다. 이를 통해 오류 발생 시점의 상황을 재구성하고 원인을 파악하는 데 도움을 얻을 수 있습니다. 숙련된 개발자들은 로깅을 통해 평균 30% 이상의 디버깅 시간을 단축한다고 합니다!

디버거 활용

다섯 번째 지도는 ‘디버거 활용’입니다. 디버거는 코드 실행 흐름을 제어하고 변수 값을 실시간으로 확인할 수 있는 강력한 도구입니다. 마치 현미경으로 세포를 관찰하듯, 코드의 작동 방식을 자세히 들여다볼 수 있죠! Python의 pdb (Python Debugger)를 사용하면 코드에 중단점(breakpoint)을 설정하고, 단계별로 실행하면서 변수 값의 변화, 함수 호출 스택, 조건문의 결과 등을 확인할 수 있습니다. 복잡한 로직이나 알고리즘에서 발생하는 오류를 해결하는 데 특히 유용합니다.

끊임없는 학습

마지막으로, 가장 중요한 것은 바로 ‘끊임없는 학습’입니다. 프로그래밍은 끊임없이 변화하는 분야이고, 새로운 기술과 도구가 끊임없이 등장합니다. 따라서 새로운 지식을 배우고 익히는 자세는 필수적입니다. 온라인 강의, 기술 블로그, 오픈 소스 프로젝트 참여 등 다양한 방법을 통해 최신 기술 동향을 파악하고, 자신의 역량을 강화해 나가세요. 끊임없이 배우고 성장하는 개발자만이 오류의 늪에서 벗어나 자유롭게 코딩의 세계를 누빌 수 있습니다. 마치 레벨업을 거듭하는 게임 캐릭터처럼 말이죠! 🎮

 

파이썬 코딩의 세계에 첫발을 내딛는 것은 험난한 여정일 수 있습니다. 흔히 발생하는 오류는 숙련된 개발자에게도 좌절감을 안겨주곤 합니다. 하지만 이러한 오류들은 단순한 걸림돌이 아닌, 성장의 발판입니다. 오류 메시지를 정확히 분석하고 디버깅 기술을 연마하는 것은 파이썬 전문가로 발돋움하는 데 필수적입니다.

본 포스팅에서 제시된 오류 유형, 분석 기법, 디버깅 도구, 그리고 효율적인 해결 전략을 통해 여러분은 코드의 오류를 두려워하기보다는, 그 안에서 배우고 성장하는 기회를 발견하게 될 것입니다. 꾸준한 노력과 올바른 접근법으로 무장한다면, 어떤 오류에도 굴하지 않고 견고하고 효율적인 파이썬 코드를 작성하는 자신을 발견하게 될 것입니다.

 

Itlearner

Recent Posts

R에서 작업 디렉토리 설정과 파일 불러오기 (getwd(), setwd(), read.csv()

안녕하세요! R을 이용한 데이터 분석, 어디서부터 시작해야 할지 막막하셨죠? R 초보자분들이 가장 먼저 마주하는 어려움…

2시간 ago

R에서 패키지(Package) 설치 및 관리 (install.packages, library)

R 언어로 데이터 분석을 시작하려는 여러분, 안녕하세요! R은 정말 강력한 도구지만, 처음엔 어디서부터 시작해야 할지…

7시간 ago

R 언어에서 변수 할당 (<- vs = 차이점)

안녕하세요, 여러분! R 언어를 배우는 여정에서 만나서 정말 반가워요! 🤗 오늘 우리가 함께 알아볼 주제는…

12시간 ago

R 언어의 데이터 유형 (Vector, List, Matrix, Data Frame)

안녕하세요! R 언어를 배우는 여정, 어떻게 느껴지고 있나요? 처음엔 낯설고 어려운 용어들 때문에 힘들 수도…

17시간 ago

R에서 첫 번째 코드 실행 (Hello World 예제)

안녕하세요! 드디어 R 프로그래밍의 세계에 첫발을 내딛으려는 여러분을 환영합니다! R을 처음 접하시는 분들께는 낯설고 어렵게…

23시간 ago

R 언어 설치 및 개발 환경 설정 (RStudio 활용법)

안녕하세요! 데이터 분석의 세계로 떠나고 싶은 분들, 모두 환영해요! 요즘 데이터 분석이 핫한 분야인 건…

1일 ago