본문 바로가기
개발적인/대외활동

[대외활동] 코뮤니티 파이썬 과정

by klm hyeon woo 2021. 8. 10.

썸네일은 감성있게 엣지있게 열정있게!

요즘 일상 블로그 올리는 것도 재밌는데, 개발 블로그 쓰는 것도 너무 재밌다!

 

코로나때문에 대외활동을 미룰 수는 없어서, 일단 뭐라도 하자 싶어 대외활동을 찾다가 온라인 대외활동 모각코(?)를 찾았다.

모각코는 비공식으로 각자 모여서 하는 코딩이라고 들었는데, 수료증도 주고 공식적으로 인정을 해주는 대외활동이라서 호다닥 달려갔다.

지원서도 열심히 작성하고, 코뮤에서 원하는 학생이 무엇인가 곰곰히 생각하며 지원을 했다. (백수는 아니지만 나만의 백수는,, 우울하니까 🥺,,)

 

운이 좋게 대외활동 합격에 성공했다 ✌🏻


1일차

아유,, 거,, 맥북 유저라서 처음에 중앙에서 Visual Studio Code를 설치를 권장했다.

이런 유명한 컴파일러들을 쓰는데는 편리성이라는 이유가 있겠지만, 나는 평소에 쓰는 Xcode 컴파일러에 익숙해졌던터라 Xcode에 파이썬 언어를 구축해서 넣고 싶었다. 그런데, 구글링을 해보니까 외국자료에 설명이 잘 되어있었다!

 

경로도 잘 설정해주고, Python 최신버젼을 끌어다와서 Xcode에 잘 이식을 해주었는데,,

 

Terminal에서는 sudo 명령어로 파이썬이 인식이 되는데 Xcode에서 허용제한 에러가 발생한다,,
3시간 동안 나는 무엇을 하고 있는건가,, 멘붕이 왔다
수 차례 애플 SIP 정책도 확인해보고, 그러다 BIN 파일 경로도 다시 확인해주고 Terminal을 통해 Python3를 데스크탑 바탕화면에 링커 명령어를 통해 지정해주니까 되었다,, 경로 문제였나 하여튼 반가운 "Hello World",, 개발자들이 왜 "Hello World"를 반가워하는지 알 것 같기도 하고,,

 

2일차 

온라인 모각코 과정 2일차, 저학년때 파이썬을 배우기도 했고 오랜만에 기억을 떠올려 다시 한번 배워가고있다!

오늘은 문자열 출력에 대한 부분을 배웠다.

C언어에서는 문자를 printf("")로 출력을 하고, 자바에서는 print.out("")로 출력을 하는데 파이썬은 print("")으로 출력을 한다.

(파이썬은 세미콜론도 안 찍는 이상한 녀석이다,,)

 

파이썬에서 print 뒤에는 다른 언어도 마찬가지겠지만, \n (다음 줄로 이동)이 생략되어있는데 이 부분은 전혀 몰랐다.

print("Hello World", end="") 처럼 end 값에 빈 문자열을 지정하면, 다음 print 문이 입력 되었을 때 다음 줄로 이동없이 한 문장으로 같이 출력이 된다.

 

end="," 를 적으면 문자열 뒤에 , 가 출력되고,

end=":"를 적으면 문자열 뒤에 :가 출력되고,

end="!"를 적으면 문자열 뒤에 !가 출력됩니다.

 

그렇다고 한다, 무지무지 신기하다.

 

C언어에서는 여러 줄을 출력할 때 printf(" ... ")로 "..." 안에 여러 문장들을 입력하면 되었지만, 파이썬은 들여쓰기에 오류가 생기면 컴파일도 안되고 printf("...")에 "..."에 여러 문장을 입력해도 오류를 나타낸다. 파이썬에서 한 print문으로 여러 문장을 입력할 때는 print(""" ... """)처럼 """ 세개의 쌍따옴표를 써줘야한다고 한다. 

 

정리를 하자면 print문과 함께 한 문장을 쓸때는 따옴표(") 1개, 여러 문장을 쓸 때는 따옴표(""") 3개를 사용해주면 된다.

 

주석은 우리가 흔히 아는 (#) 주석이 있지만, (""") 세개의 따옴표를 그냥 앞 뒤로 붙여주면 주석처리가 된다고 한다. (ㅇ,, 오,, 정말 신기,,)

 

나는 파이썬 초보지만,, 곧 고수가 될거라고 믿는다,,

3일차 

모각코 3일차, 자료형과 변수라는 제목으로 파이썬을 오늘도 힘차게 시작했다!

다른 언어와 마찬가지로, 변수에 값을 넣어주고 타입명으로 출력을 했을 때 변수에 대한 타입명을 알 수 있었는데

변수에 다양한 값을 넣어주고, 타입 명을 다양하게 받아봤다.

개발자라면 흔히 볼 수 있는 값으로 테스트를 해보았다.

C언어에서는 Boolean이라고 많이들 사용하는데, 파이썬에서는 요약어로 Bool 타입이라고 사용을 했다.

(출력도 Boolean이 아닌, Bool로 출력이 된다-!)

 

인덱싱 : 가리키다

당연한 코드이지만, 문자열 인덱싱이라는 말이 생소해서 이렇게 포스팅을 해보았다.

예전 정보관련 전공 과목을 들었을 때 보조기억장치 뭐라뭐라 해서 인덱싱을 배웠던 것 같은데, 여기서 또 볼 수 있어서 반갑기도 하고,, 예,,

변수에 문자열을 넣어주었고, 이를 print문으로 바로 인덱싱하여 출력을 할 수 있다. (이때, 숫자도 포함이 된다.)

 

C언어에서 처음 접할 때 어려운 부분 중 하나가 문자배열이었다.

[0]부터 배우면서 메모리 이야기도 나오고, 반복문으로 꺼내와야하고 조건문도 붙으면 더 어려워지고,,

그런데 파이썬은 반복문을 사용 할 필요가 없이 다음 명령어로 꺼내올 수 있었다.

(무척이나 신기했다,, 이래서 이래서 파이썬 하는ㄱ,, 것인가,,?)

파이썬에서는 문자열 잘라오는 방법이 신기하다.
C언어에서는 분명 반복문을 사용했던 것 같은데,, 역시 더 친숙한 언어 파이썬!

hi = "파이썬 공부는 즐거워!"
print(hi[4:7])  # 4번부터 7-1번 문자열까지 출력
print(hi[-4:])  # -4부터 문자열의 마지막까지 슬라이싱
print(hi[:4])   # 문자열의 첫 글자부터 4-1번 문자열까지 슬라이싱
print(hi[4:-1]) # 4번부터 -2번 문자열까지 출력

요약하자면, print(문자배열이름[시작문자열 : 끝 문자열]) 와 같이 출력을 하면 원하는 문자배열을 끌어올 수 있게된다.

여기서 술술 이해를 하다가 음수배열 부분에서 조금 시간이 걸렸는데 자세히 보았더니 그냥 순서도만 다른거였다.

 

음수로 표현을 했을 때, 문자열 배열
양수로 표현했을 때, 문자열 배열

헷갈리는 부분은 다음과 같았다 : hi[4:-1]

공[4] 부[5] 는[6] ' '[7] 즐[8] 거[9] 워[10]

→ 공[-8] 부[-7] 는[-6] ' '[-5] 즐[-4] 거[-3] 워[-2]

처음에는 4부터 양수 문자열의 끝까지 끌어오고, 또 음수 문자열의 처음부터 끝까지 끌어와 이중으로 출력을 해주는 줄 알았는데,

양수 문자열에서 '공'을 찾았으면 음수 문자열에 '공'에서부터 시작을 해서 끝을 내는 방식이었다.

 

블로그 정리하지 않았으면 그냥 넘어갔을거라고 생각하는 나는 아주 뿌듯하다 😇

 

 

4일차

거,, 이 정도면 작심삼일 넘긴거쥬,,? 

오늘은 산술연산자 파트에 대해 공부를 해보았습니다!

C언어에서 산술연산자를 배워놓았기 때문에 이번 파이썬에서 산술연산자도 수월하게 숙제를 제출했습니다만,,

파이썬하고 C언어의 다른 점을 찾았다면, 파이썬은 정말 사람들하고 친숙하다는 것을 인증하는 언어인지는 잘 모르겠지만,

C언어에서 5/2의 값은 몫 2라는 값을 출력하지만, 파이썬은 2.5라는 값을 출력한다,,

 

/ 연산자 : 나눗셈 (division)

// 연산자 : 버림 나눗셈 (floor division)

% 연산자 : 모듈로 연산자 (modulo)

 

이런 식으로 파이썬의 나눗셈 연산자가 나누어지는데, '//' 로 나눗셈을 진행한다고 해서 5/2의 몫이 2가 나오고 나머지 1이 나오는게 아닌, 2.5로 출력이 되지만, 0.5를 숨겨주는 꼴로 내부 시스템이 작동이 되어진다. (아주 똑똑하고 교묘한 녀석..)

 

ㄴ.. 나눗셈을 고냥 다 해주시네 파이썬은?!

 

오늘 숙제는 3420원이라는 지폐를 천원, 백원, 십원으로 나눠주는 프로그램을 만드는 문제였는데,

C언어에서는 정수형으로 나누면 정수형 몫만 빼고 원하는 나머지를 반환해주어서 쉽게 분할을 할 수 있었다.

그렇지만, 이 친절한 파이썬은 정수형 나눗셈을 했는데 실수형으로 반환을 해주고,, 편리한 것 같았지만 내가 기존에 사용하는 알고리즘에는 부합하지 않았다.

그래서 구글링을 하고 또 구글링을 했다! 그렇게 찾은게 divmod 라는 메소드이다.

>>> divmod(5, 2)
(2, 1)

이런 식으로 몫과 나머지를 반환해준다. (ㅇ,, 이게 내가 원하던 값이란말이다-!)

>>> quotient, remainder = divmod(5, 2)
>>> print(quotient, remainder) # 몫, 나머지
2 1

뭐 이런 식으로, 변수에 몫과 나머지를 대입해줄 수도 있다고 한다.

(맞아,, 개발자들은 정말 천재야,, 그래서 개발자를 하는거겠지,,?)

이렇게 메소드를 찾거나, 코드를 쉬운방향으로 해결을 하면 기분이 너무 좋아지고 행복해지곤 한다,, 어쩌면 적성에 맞을지도,,

 

price = int(input("상품의 가격을 입력하세요:"))

a_1, a_2 = divmod(price, 1000)
b_1, b_2 = divmod(a_2, 100)
c_1, c_2 = divmod(b_2, 10)

print("1000원 : " + str(a_1))
print("100원 : " + str(b_1))
print("10원 : " + str(c_1))

print("필요한 동전의 개수 : " + str(b_1+c_1))

 

코뮤니티를 보니 다른 사람들은 다 백의 자리를 구하면 나머지에 백을 곱해주고 다시 계산을 해주고 하던데, 이런 방식으로 하면 편리하게 접근을 할 수 있었다.

뭐 어찌되었든 편한 방법으로, 사용자과 원하는 결과값만 출력을 하면 되는거니까!

 

아 그리고, 자바나 C언어에서는 printf문을 사용하여 %d, %f, %lf 등으로 정수형을 출력하고는 하는데 파이썬에서는 printf문을 지원하지 않는다.

그래서 문자열이랑 어떻게 한번에 출력을 해볼까하다가, 구글링을 하고 또 구글링을 했다.

그러다보니까 정수형을 그냥 냅다 print("필요한 동전의 개수 : " + a) 이런 식으로 붙였었는데, int형에는 +가 먹지 않아 오류메세지는 당연 ☹️

찾아보니 int형을 형변환해서 str형으로 출력하는 것도 그리 나쁜 방법은 아니라고 한다.

그래서 바로 int형 str형으로 강제형변환해서 문자열하고 자연스레 어울리게 출력을 해버렸다.

 

근데,, 파이썬 너무 재미있다,, 이렇게 구글링하면서 알아가는 것도 너무너무 재미있구,, 오늘도 클리어 😇

 

5일차

 

오늘은, 모닝 커피를 마시며 아침부터 대외활동 과제를 풀이했다!

엊그제 4일차에서 구글링을 하며 사용자로부터 입력을 받는 input문, 그리고 형변환까지 어쩌다보니 운이 좋게 배워버렸는데

5일차 커리큘럼에서는 input문과 형변환 부분이 나왔다. 미리 공부하고, 또 한번 복습해가는 과정에서 이것이 배움의 즐거움이 아닐까 싶은 생각이 들었다.

 

5일차 과제는 생각보다 엄청 간단했다, 생일을 입력하고 그 생일을 부분부분으로 나눠주는 프로그램을 만드는 것이다. (예를 들어, 20050607를 입력했다면 2005년, 6월, 7일 이런 식으로 나누어주는 프로그램을 작성하는 것이다-!)

birthday = input("생일을 입력해주세요 (ex:20050607) : ")

    print(birthday[0:4] + "년")
    print(birthday[5:6] + "월")
    print(birthday[7:8] + "일")

뭐, 이런 식으로 간단하게 코딩을 할 수 있었는데 뭔가 밋밋한 느낌이 들었다.

모든 프로그램에는 완벽한 프로그램은 없겠지만, 학교 교수님의 말씀 중에 조금 더 세세한 프로그램을 짜는 것이 개발자의 덕목이라는 말씀이 생각이 났다.

그래서 현재 위 코드에서는 8자리라는 생년월일의 양식에서 벗어나게 되면 프로그램 자체에서 오류코드를 발생시켰는데, 이를 막아주기 위해서

문자열의 크기를 8개로 제한하여 8자리로 들어오는 입력만 받아 출력을 시켜주는 프로그램을 만들기로 했다.

C언어에서는 sizeof나, strlen 이라는 문자열의 크기를 받아오는 메소드가 있지만, 파이썬에서는 어떤 방법과 코드로 받아오는지를 도통 몰랐다.

 

그럴 때는 구글링도 실력이라고, 바로 내 코드로 담아오려고 구글링을 했다.

python에서는 len이라는 메소드를 통해 문자열의 크기를 받아올 수 있는 아주 기발한 방법이 있었다.

birthday = input("생일을 입력해주세요 (ex:19980607) : ")

if (len(birthday) == 8) :

    print(birthday[0:4] + "년")
    print(birthday[5:6] + "월")
    print(birthday[7:8] + "일")
    
else :
    print("잘못 입력하셨습니다, 올바른 생년월일을 입력해주세요.")

그래서, 따란-!

이런 식으로 if문을 이용하여 사용자가 birthday에 입력 값을 8자리로 입력하지 않는다면 else문으로 프로그램을 처리할 수 있도록 했다.

이렇게 하면 양식에 딱 맞게 입력을 받을 수 있고, 예외처리를 통해 다른 오류코드로 이어질 수 없게 할 수 있다.

간단하지만, 이렇게 한 부분 한 부분 신경쓰고 개발하는 것도 개발 실력을 증진시키는데 도움이 많이 되는 부분 중 하나라고 생각이 든다.

이렇게 오늘도 한 발짝 다가섰다! 끝-!

 

6일차

 

6일차에서는 관계연산자(비교연산자)와 조건문이라는 파트에 접어들었다. 

두 수를 비교하고 하는 부분에 대해서는 C언어와 공통적인 부분들이 많지만, 논리연산자 부분에서는 신기한 부분이 많았다.

C언어에서 AND(&&), OR(||), NOT(!) 이렇게 특수기호로 표시하던 부분을 파이썬에서는 순수하게 영어 그대로 쓴다.

(ㅇ,, 이게 언어에서도 가능은 하구나,, 신기방구,,)

 

✔ a and b : a와 b 모두 참이여도 참이다.

✔ a or b : a와 b 둘 중 하나만 참이여도 참이다.

✔ not a : a가 거짓이면 참이다. a가 참이면 거짓이다.

 

약간 이런 느낌으로 다가갈 수 있는 것이다, 아주 신기하고 신기한 부분,,

 

그리고 조건문 if문 파트에서도 마찬가지였는데 C언어에서는 if, else if, else문으로 구분이 된다면, 파이썬에서는 if, elif, else문으로 구분이 된다.

else if문 또한 elif문으로 줄여놓은 것을 볼 수 있었다. C언어에서는 사용자에 따라 들여쓰기를 잘 하지 않아도 컴파일이 알아서 되는 모습을 보여주는데,

파이썬에서는 들여쓰기가 되지 않는다면 오류 메세지를 출력하고 컴파일이 되지 않는다.

 

# 조건문이 참이라면 if문을 실행
if 조건문1:
    실행문1

# if 조건문이 거짓이라면 elif 조건문을 실행
elif 조건문2:
    실행문2

# if, elif 조건문들이 거짓이라면 최종적으로 else 조건문을 실행
else:
    실행문3

따라서 파이썬은 다음과 같이 들여쓰기를 형식에 맞게 잘 해줘야 정상적인 컴파일이 진행된다.

 

4,5일차에서 파이썬에서는 문자열의 부분 부분을 편리하게 잘라온다고 포스팅을 했는데, 조건문에서도 메소드를 이용하여 유용하게 잘라올 수 있다.

line = "Hello World"

# line이라는 변수에 Hello가 있나요?
if "Hello" in line:
    print("Hello가 있습니다")
else:
    print("Hello가 없습니다")
# 6일차 숙제, 단어와 문장을 입력받아 검색하는 프로그램 제작

word = input("단어를 입력해주세요 :")
sentence = input("문장을 입력해주세요 :")

if (word in sentence) :
    print("단어가 존재합니다.")
else :
    print("단어가 없습니다.")

C언어에서는 반복문을 돌려서 문자열을 찾아주고, 잘라왔다면 파이썬에서는 그럴 필요가 없다.

다음과 같이 변수에 문자열을 지정해주고, 지정해준 변수에 "Hello" 라는 값이 있다면 if, else에 해당하는 조건문을 출력해줄 수 있다.

(ㅇ,, 이 마술같은 언어,, 얼른 마스터해서 멋쟁이사자처럼을 들어가는 미래를 꿈꿔보자-!)

오늘의 6일차 포스팅도 성공적으로 마무리!

 

7일차

 

7일차는 반복문에 대해서 배워보았다!

C언어에서 배웠던 for문과 while문에 대해서 배워보았는데, 파이썬은 또 문법이 어딘가가 이상했다-

C언어에서는 while(1)의 무한루프가 가능했다면, 파이썬에서는 자바와 같이 while(1)을 지원하지 않고, while(True)를 지원하며

++와 같은 후위연산자를 지원하지 않아 변수를 지정하여 그 변수에 += 형식으로 덧셈을 해주는 방법으로 계산식을 지정을 해야했다.

 

나는 보통 for문을 사용하여 반복문을 만들고, 그 안에 조건을 지정해주곤 하는데

오늘 파이썬에서는 while문으로도 한번 반복문을 구현하고, 그 안에 조건문을 만들어주고 싶었다.

 

count = 0

for i in range(1,101):
    # i가 증가하면서 짝수이면서, 동시에 7의 배수가 아닌 조건 구현
    if (i % 2 == 0) and (i % 7 != 0):
        count += 1
print("1부터 100까지의 수 중에서 짝수이면서 7의 배수가 아닌 수의 개수는 "+str(count) + "개 입니다")

count = 1
i = 1

while (i < 101):
    # i가 증가하면서 짝수이면서, 동시에 7의 배수가 아닌 조건 구현
    if (i % 2 == 0) and (i % 7 != 0):
        count += 1
    i += 1
print("1부터 100까지의 수 중에서 짝수이면서 7의 배수가 아닌 수의 개수는 "+str(count-1) + "개 입니다")

C언어에서는 괄호 "{" 를 이용하여 어디부터 어디까지의 범위를 사용하겠다는 명령을 지정해줄 수 있는데, 파이썬은 그 부분이 모호하다.

그래서 처음에 count 값을 1씩 증가시켜주고 싶었는데, 왠지 모르게 되지 않았다. (알고,, 보니 if문 안에서 count += 1 코드가 갇혀있었다,,)

계속 이렇게 연습하며 코딩을 하고보니 어느정도 감은 잡히는 것 같은데, 나중에 프로젝트를 하곤 할때 그 많은 코드들 중 많은 반복문이 나올텐데

ㄱ,, 그때는,, 뭐,, 계속 연습하고 연습하고 있으니까 어느정도 잘할 수 있을거라고 생각한다-!

 

while 문에서는 if문과 다르게 결과 값에 1이 증가되어 나왔는데, 예~전 C언어 코딩했을 때 while 문으로 결과 값을 출력했을 때도 1이 증가되어 나왔던 기억이 있었다. 그래서, 출력 값에 -1을 해주어서 for문과 같은 출력 값을 나타내주었다. (엑셀로 for문과 while문의 조건에 대한 개수를 확인했을 때 둘 다 같았다.)

(반,, 반성해라,, count 값을 1로 설정을 해놓아서 이렇게 나온것을,, 일단 이것도 경험이니 소스코드는 수정하지 않겠다.)

 

number = 0
result = 0

while True:
    number = int(input("숫자를 입력하세요 :"))
    result += number
    if (number == 0):
        print("프로그램이 종료되었습니다")
        print("입력해주셨던 숫자들의 합은 "+str(result)+" 입니다.")
        break

위의 코드는 while의 무한루프를 돌리고, 입력한 숫자만큼 합을 구해주고 일정 입력을 받으면 루프를 멈추는 프로그램이다.

이 반복문도 처음에는 범위에 대한 경계가 모호했는데, 위에 올렸던 소스코드들을 구현하고 나니까 바로 수월하게 코딩을 할 수 있었다-!

앗, 파이썬은 정말 세미콜론이 들어가지 않는 것 같다, C언어에서는 교수님이 세미콜론을 붙여라~ 붙여라 했었는데,

아무래도 정말 직관적인 언어라는 뜻이겠지?! 아무튼 7일차도 잘 마무리하였습니다!

(여행 중에 코딩을 했다는 것은 비밀-)

 

8일차

 

오늘은 어제에 이은, 반복문과 조건문에 대한 도전문제를 풀이하는 시간이었다.

예~전에 학교에서 시험으로 출제되었던 BMI 프로그램을 만드는 문제였는데, 예전에는 첫 시작도 버거워했는데 이제 조금은 문제만 보고 어떻게 알고리즘을 짜야할 지 감이 온다. (ㅁ,, 물론 쉬운 문제만,,)

 

알고리즘을 짜고, 코딩을 해보았는데 마음에 들지 않았다.

숫자를 입력받고, 그 숫자를 계산하여 조건에 대한 출력을 해주면 되는 간단한 프로그램이었는데, 

문제는 사용자가 어떤 입력을 할 지 모른다는 것이었다. 이를 처음에는 조건문으로 처리를 해주려고 했는데 어떤 블로그에서는 input으로 입력을 받으면 자동으로 형변환을 해준다고 적혀있는데, 아무리봐도 input으로 입력을 받고 출력을 해도 타입명은 string형으로 그대로였다.

 

int형의 input으로 입력을 받는 것이 가장 편리한데,, 이렇게 지정을 해주면 문자열을 입력했을 때 맞지 않는 타입으로 실행조차 되지 않고 바로 오류메세지를 띄어버린다. 어떻게 할지 고민을 하던 차에 자바의 try-catch문이 생각났다. 평시에 사용하던 코드를 try에 넣어주고, 만약 어떤 오류로 인해 오류메세지를 출력하려고 하면 예외적인 부분을 catch문 안에 설정한 코드로 보내버리는 것이다.

 

자바에서는 try-catch로 유용하게 사용했는데, 파이썬에서도 try-except라는 코드를 사용할 수 있었다.

weight = 0
height = 0
BMI = 0

try:
    weight = int(input("키를 입력하세요 :"))
    if (weight <= 500 and weight >= 0):
        weight = weight / 100
    else:
        print("부정확한 데이터를 입력하였습니다")
        print("프로그램을 종료합니다.")
        exit()
    
    height = int(input("몸무게를 입력하세요 :"))

    if(height <= 300 and height >= 0):
        BMI = height // (weight * weight)
    else:
        print("부정확한 데이터를 입력하였습니다")
        print("프로그램을 종료합니다.")
        exit()
except:
    print("부정확한 데이터를 입력하였습니다")
    print("프로그램을 종료합니다.")
    exit()
    
if (BMI >= 25):
    print("비만입니다.")
elif (BMI <= 25 and BMI >= 23):
    print("과체중입니다.")
elif (BMI <= 23 and BMI >= 18.5):
    print("정상체중입니다.")
else:
    print("저체중입니다.")

try-except 문을 사용하게 되면, int형의 input을 입력받더라도 형변환을 통해 비교를 하고 걸러주지 않아도 숫자가 아닌 것들은 다 except 쪽으로 보내버릴 수 있었다. 이 오류를 어떻게 해결할까에 대해서 1시간 정도 고민을 했는데, 이 오류에 대한 해답을 찾고 해결하는 과정에서 그 시간들이 전혀 아깝지않았다.

오히려 그 시간들조차 내 영양가있는 시간이 되었다. 컴공생은 스스로 알아가며 배워가는 것이 대부분이라고 들었는데, 정말 구글링을 하며 배운 자료들이 학교에서 배운 내용들보다 더 머리에 잘 들어오고 오래남는 기분이다. 오늘의 도전문제도 무난하게 잘 마무리했고, 내일을 향해 또 열심히 달려보자 아쟈쟈-

 

9일차

 

오늘은 새로운 챕터를 배울 줄 알았는데, 기상을 하고 알림을 보니 오늘도 도전문제에 관련된 공지가 올라왔다.

조건문에 대한 내용이 나왔는데 그 만큼 조건문이 중요하고, 많이 쓰이구나 하는 생각이 들었다.

오늘도 문제를 보며 머릿속으로 알고리즘을 생각하고 바로 맥북과 함께 코딩을 시작했다.

오늘은 사용자가 연도를 입력하면, 컴퓨터가 그 연도를 윤년 여부를 알려주는 프로그램을 만들어보는 문제였다.

 

윤년은 다음 3가지 법칙에 의해 결정이 되는데,

  1. 연도가 4로 나누어 떨어지는 해는 윤년이다.
  2. 그 중 100으로 나누어 떨어지는 해는 윤년이 아니다.
  3. 400으로 나누어 떨어지는 해는 무조건 윤년이다.

1번에서 4로 나누어 떨어지면 윤년인데, 그 중에서 100으로 나누어 떨어지는 해는 윤년이 아니라는 말은 1번과 2번은 공통적으로 묶여주되,

3번은 개별로 가동을 해주면 된다는 의미로 받아들였다. 그래서 1번과 2번 조건은 AND 연산으로 두 조건이 다 참일 경우 실행을 시켜주면 되는 것이고,

3번은 묶인 1번과 2번의 관계에 대해 OR 연산자로 묶어주면 되는 문제였다.

 

예전 C언어에서 윤년 출력 프로그램을 만들곤했는데, 그때 알고리즘을 천천히 익혀가는 과정이 많이 도움이 되었던 것 같다.

year = 0

try:
    year = int(input("연도를 입력하세요 : "))
    
    if (year % 4 == 0 and year % 100 != 0) or (year % 4 == 0):
        print(str(year) + "년은 윤년입니다.")
    else:
        print(str(year) + "년은 윤년이 아닙니다.")

except:
    print("잘못된 입력을 하셨습니다.")
    print("프로그램을 종료합니다.")
    exit()

 

이런 식으로 소스코드를 만들어줄 수 있었는데, 어제 try-except 문의 응용에 이어서 오늘도 사용자가 잘못된 입력을 하면 예외메세지를 출력해주는 방향으로 조금 세세한 프로그래밍을 해보려고 노력을 했다. C언어에서는 파이썬의 코드에 비해 조금은 많은 코드를 내비쳤을텐데 그 만큼 파이썬은 인간과 밀접한 프로그래밍 언어라는 것을 한번 더 알게해준다. 그리고, 예전에는 한 문제에 오랜시간을 소모하며 문제를 풀곤했는데 알고리즘이 바로바로 생각나는 문제들이 서서히 보이기 시작했다, 더 노력하고 노력해서 내가 꿈꾸는 곳으로 갈 수 있도록 오늘도 열심히해보자,

오늘은 모닝부터 코딩을 했는데 너무 상쾌하다, 오늘도 숙제를 마친 뒤 좋은 하루로 시작-!

 

10일차

 

10일차, 오늘의 모각코 대외활동 시작-

오늘은 모든 언어들의 공통적인 꽃의 챕터 함수에 대해 배워보는 시간을 가졌다.

함수는 소스코드를 간결하게 또 보기쉽게 효율적인 사용성에 도움을 주는 친구인데, 다양한 언어들에서 다양한 함수선언들을 하는 것처럼

파이썬에서는 def라는 메소드를 통해 함수를 선언한다. (ㅇ,, 아마 define의 줄임말이겠지,,?)

def 함수명(매개변수1,...):
    함수내용​

다음과 같이, 간단명료하게 함수를 설정할 수 있다.

함수를 무난하게 설정을 해주고, 끌어와 쓸 수 있었는데 여기서 한가지 의문점이 생겼다.

파이썬에서 보이지 않는 범위를 딱 맞추는 것도 힘든데 어떻게 전역변수, 지역변수를 설정할 수 있을까에 대한 생각을 했다.

 

구글링을 해보고, 파이썬에서 전역변수를 사용하고 나니까 정말 사용하기 싫어졌다.

왜냐하면,, 전역변수에서 변수 값을 설정을 해주면 다른 블럭에서 바로 사용을 할 수 있는 것이 아닌,

i = 1
.
.

def 변수이름 (매개변수 ...):
    global i​

 

다음과 같이 지역에 있는 블록에서도 전역변수를 사용하겠다~ 하는 선언을 해줘야했다.

이렇게 사용할빠에는, 지역변수로 선언하고 사용하는게 메모리상으로도 좋고 간략한 소스코드를 위해서도 좋은 것 같다.

 

오늘은 사용자로부터 정수를 입력받아, 1부터 그 정수까지의 합을 구하는 프로그램을 만드는 문제였다.

예전 이 프로그램도 한번 코딩을 해본 적이 있었기 때문에 머릿속으로 알고리즘을 연상시키고 바로 문제풀이에 들어갔다.

number = int(input("정수를 입력하세요 : "))

def getNum (a):
    
    sum = 0
    
    for i in range (1,a+1):
        sum += i
    return sum
    
def getNum_2 (a):
    
    sum = 0
    i = 1
    
    while (i<=number):
            sum += i
            i += 1
    return sum
    
print("1부터 "+ str(number)+"까지의 합은 "+str(getNum(number))+"입니다")
print("1부터 "+ str(number)+"까지의 합은 "+str(getNum_2(number))+"입니다")​

 

다음과 같이 간단하게 프로그램을 작성할 수 있는데, 파이썬에서는 while문이 쉽게 다가오고 for문이 아직도 낯설게만 느껴진다.

(range 명령어 ㄸ,, 때문인가,, for 문에서는 변수 i 값을 따로 지정해주지 않아도 위의 형식처럼만 지정을 해준다면 바로 사용할 수 있다)

 

번외로, for 문이 가물가물해서 7일차 과제를 잠시 들여다보았는데 while 문에서 코딩실수가 있었다.

왜냐하면, while문에서 count 값이 +1 값으로 계속 증가되어서 나왔었는데 알고보니 내가 count의 초기값을 1로 잡아놓아서 1씩 증가된다면

결과적으로는 +1의 값이 나오게 되는 불상사를 저질렀던 것이다. (그래서 바로 블로그 내용을 일부수정했다)

 

지금은 수월하게 다가갈 수 있는 파이썬이지만, 분명 점점 다양한 챕터를 거듭할 수록 어렵고 할애하는 시간이 많을 것이라고 생각이 된다.

그때마다 포기하기보다는 이것도 수월하게 할 수 있다는 자신감으로 덤빌생각이다. 오늘의 과제도 여기서 마무리-

 

お疲れ様でした-!!

 

11일차

 

11일차 모각코의 주제는, 배열이라고도 하는 리스트 챕터-!

오늘은 전에 구글링을 하여 사용을 했던 len을 주로 사용하는 챕터이기도 하다. (C언어에서는 strlen을 사용하는 배열-)

 

뭐, 전체적인 맥락은 C언어의 배열과 같았다.

배열을 예를 들어 [1,2,3] 으로 설정을 하면, 이 배열의 크기는 3이고 각 원소는 1부터 3까지의 수가 포함되어있는 그런 배열이었다.

 

단지 조금 다른 점은, 다른 언어같은 경우에는 배열의 자료형을 통일 시켜줘야했었는데 파이썬은 그런게 없다. (ㅇ,, 왜 없는거지,, 완전 이게 언어인가,,?)

example_lst = [1,"python",1.3]

이런 식으로 변수에 각 배열의 원소를 집어넣어주는데 int형과 float형, 그리고 문자형까지 아주 뒤죽박죽이다.

그 만큼, 파이썬이 인간에게 더욱 더 친숙한 언어라는 이유를 보여주는 부분이기도 한 것 같다. (이 친숙함은 언어에 대한 편리성도 업-!)

 

이전의 챕터에서 배웠듯이, 이 배열 또한 문자열처럼 슬라이싱이 가능하다.

(여기서 슬라이싱을 까먹었다면, 3일차 기록을 다시 한번 살펴보자)

 

또한 배열에 삽입을 하는 방법 같은 경우에도 비슷하면서 약간의 차이가 있었다.

C언어에서는 반복문을 돌려 i 값에 직접 원소 번호를 지정해줘서 넣어주는 방식을 이용했는데

example_lst = [1,2,3,4,5]
print(example_lst)

example_lst.append(6)
print(example_lst)

파이썬에서는 append를 이용하여 배열 끝에 순차적으로 이어서 붙여줄 수 있는 메소드가 있다.

append (넣을 원소)

example_lst = [1,2,3,4,5]
print(example_lst)

example_lst.insert(3,6)
print(example_lst)

또, 다른 방법으로는 insert 메소드가 있는데 방법은 다음과 같다.

insert (지정 할 배열 원소의 번호, 넣을 원소)

 

넣었다면, 제거도 할 수 있지 않을까? 라는 생각을 한번 쯤은 할 수도 있다. (ㄴ,, 나는 한번도 하지 않았지만,, 넣으면 ㅈ,, 장땡이다-!)

example_lst = [1,3,5,7,9]
print(example_lst)

del example_lst[3]
print(example_lst)

먼저, del 메소드이다. 

del 배열변수이름 [지정할 원소번호] 와 같이 지정을 해준다면, 지정된 원소의 번호가 사라진다. 비교적 간단한 편이다.

example_lst = [1, 3, 5, 7, 9]
print(example_lst)

example_lst.remove(7)
print(example_lst)

다음으로는 remove 메소드이다.

remove.[지정할 원소번호]  와 같이 지정을 해준다면, 이 메소드 역시 원소의 번호를 쉽게 사라지게 할 수 있다.

 

이렇게 배열을 입력 그리고 제거하는 부분으로 크게 나누어 정리를 하고 나니까, 별로 어려워보이지 않는다.

(처음에 오랜만에 들어와보는 배열챕터라서 어려웠는ㄷ,,)

 

오늘의 모각코 과제는 7가지의 숫자를 연속으로 입력받아, 이 숫자에 대한 평균값을 출력하는 문제였다.

예외처리를 위해 try-except 문을 사용했으며, 각 코드에 주석을 달아 이해하기 쉽게 소스코드를 배열해놓았다.

# num_array의 배열을 설정해주고, sum의 값을 0으로 초기화 시켜준다.
num_array = []
sum = 0

# 사용자가 이상한 입력을 했을 경우, 예외처리를 위해 try-except 문을 사용해준다.

try:
# i를 0부터 6까지 7회 반복을 시켜준다.
    for i in range (0,7):
        ''' 특정 자리를 지정해 값을 넣어주는데, 이때 자리값을 i로 지정하여
             0부터 6까지 반복문을 돌리며 총 7가지 자리의 값을 넣어준다 '''
        num_array.insert(i,	int(input("값을 입력해주세요:")))
        # sum에 각 i번째 원소의 값을 반복하여 더해준다.
        sum += num_array[i]
    # avg 변수에 sum 총 값을 num_array의 크기의 값으로 나누어주면 평균값을 나타낼 수 있다.
    avg = sum / len(num_array)
    # 평균값을 출력해준다.
    print("평균 : " + str(avg))

except:
    print("잘못된 입력을 하셨습니다.")
    print("프로그램을 종료합니다.")
    exit()

다른 사람들의 풀이를 보니까 누군가는 배열을 초기에 []로 잡고 append로 추가해주는 방식을 택했는데,

나는 insert로 반복문을 통해 i 번째 값을 돌려가며 계속해서 넣어주었다.

프로그램에서 문제가 발생하고 어떤 변동이 생겼을 때, 대처하기 위해서는 이렇게 알고리즘을 짜는게 옳다고 생각을 했다.

 

아, 그리고 C언어에서는 i 값에 직접 값을 넣어줄 수 있었는데 파이썬에서는 직접 값을 넣어주는 것이 불가능했다.

처음에 NULL 값으로 배열을 지정해주어서 지정을 할 수 없다나 뭐라나,,

그래서 파이썬에서는 배열에 값을 넣어줄 때는 insert 또는 append 만을 사용해 넣어주어야한다는 사실 또한 알게되었다-!

 

C언어에서는 내 생각대로 코드를 작성하고 "과연 이게 될까,,?" 하며 코드를 입력하면, 디버깅이 안되는 일이 빈번하게 발생했는데,

파이썬에서는 내 생각대로 코드를 작성하고 디버깅을 하면 신기하게도, 다 디버깅이 원활하게 되어버린다.

(ㅅ,, 실력도 분명 일취월장했다고 믿는다아-!)

 

오늘의 모각코 코딩도 성공적으로 끄읏-

 

12일차

 

금일 12일차 파이썬 모각코에서 다뤄볼 이야기는, 튜플과 딕셔너리이다-! (추가적으로, 집합또한-)

파이썬을 1학년때 가물가물하게 배워놔서 챕터마다 다른 사람들보다는 손쉽게 다가갈 수 있었는데,

이번에는 ㅌ,, 튜플,,? ㄷ,, 딕셔너리,,? 무슨 뚱딴지 같은 챕터들을 만났다.

 

11일차에는 리스트에 대해서 배워보았는데, 튜플이랑 딕셔너리는 리스트와 비슷한 맥락의 챕터라고 이해하면 조금 쉽다고 적혀있었다.

처음에 튜플과 리스트에 대해서 이 두 가지를 비교해보는데 너무 헷갈렸다. (튜플도 리스트처럼 인덱스를 이용한 소스코드 구현이 가능하다)

 

이 둘의 가장 큰 특징이자 차이점은, 리스트는 [ ] 로, 튜플은 ( ) 로 둘러싼다.

그리고, 리스트는 값의 생성,삭제,수정이 가능하지만 튜플은 수정을 할 수 없으며 값을 바꿀 수 없다.

 

(사실 튜플 중간에 리스트를 끼어놔서 헷갈렸던 것도 있다, 엥 이건 리스트가 아닌가,,? 하다가 튜플인 것을 30분만에 알게 되었다는,,)

 

example_tupleOne = (1,2,3)
example_tupleTwo = (4,5,6,7)

multi_tuple = example_tupleOne * 2

print(example_tupleOne + example_tupleTwo)
print(multi_tuple)

튜플은 인덱스로 접근이 가능하며 값을 추가 및 삭제를 할 수는 없지만, "+", "*"와 같이 여러 개를 붙여 동시에 사용을 할 수 있다.

(이 말은 리턴 값을 여러 개로 묶어 다수출력이 가능하다는 말이다)

 

def minmax(ex_lst):
    return min(ex_lst), max(ex_lst)


ex_lst = [1, 2, 3, 4, 5]
result_tuple = minmax(ex_lst)

print(result_tuple)

약간 이런 식으로도 리스트로 뽑아온다음 튜플로 적용이 가능하다.

(위에 내가 헷갈렸다는 부분이 이 파트였다, 급리스트가 등장을 해서,,)

 

다음으로는 집합 파트이다, 우리가 중 고등교육으로 배웠던 집합말이다-

One = {1,2,3}
Two = set([7,6,5,4,1])
Three = set("Hello World!")

print(One)
print(Two)
print(Three)

집합 부분은 { } 와 같이 지정을 하거나, set([ ]) 와 같이 지정을 해줄 수 있다.

하지만, 집합을 선언해줄 때 { }와 같은 부분은 안에 원소의 값이 하나도 없으면 딕셔너리로 처리가 될 수도 있으니 유의해야한다.

집합은 중복을 허락하지 않는다, 그리고 Two 변수처럼 순서대로 되지 않은 변수들은 출력해줄 때 중복을 제거해서 출력을 해주고, 순서대로 재정렬을 하여 출력을 해준다. (그래서 집합에서는 인덱스를 이용한 소스코드 구현을 하지 못한다)

 

파이썬의 집합에서도 교집합, 합집합, 차집합을 사용할 수 있는데,

사실상 AND, OR을 이용한 원리와 비슷하다.

setOne = {1, 2, 3}
setTwo = {2, 3, 4}

# 교집합
print(setOne & setTwo)
# = print(setOne.interaction(setTwo))
# 합집합
print(setOne | setTwo)
# = print(setOne.union(setTwo))
# 차집합
print(setOne - setTwo)
# = print(setOne.difference(setTwo))

위의 소스코드처럼 다음과 같이 집합을 교집합, 합집합, 차집합으로 구분을 해줄 수 있다.

처음에는 조금 헷갈렸지만, 직접 소스코드를 쳐보고 디버깅을 해보니까 금방 알 수 있던 사실이었다.

 

튜플에서는 값의 변경이 불가능하고 했지만, 집합에서는 값의 변경이 가능하다. 

즉, 튜플에서는 추가 및 수정이 가능하다는 이야기다.

 

튜플에서 값을 추가하는 방법은 크게 ADD 함수, UPDATE 함수를 사용하는 것이다.

또한, 값을 제거하는 방법은 리스트에서는 DEL과 REMOVE가 있었지만, 집합에서는 REMOVE 함수 하나만이 가능하다.

 

setOne = {1, 2, 3}
setTwo = {2, 3, 4}

print(setOne) # 1,2,3 출력
print(setTwo) # 2,3,4 출력

setOne.add(5) # setOne에 5를 추가
setTwo.update([9, 8, 7]) # setTwo에 9,8,7을 추가

print(setOne) # 1,2,3,5 출력
print(setTwo) # 2,3,4,7,8,9 출력

먼저, 추가하는 함수를 살펴보겠다.

출력은 아까 이야기 한 듯이 숫자의 순서대로 출력이 되어진다.

추가 되는 부분에는 문제가 없지만 가만 살펴보면 알아야할 점이 있다, 바로 하나의 원소를 추가할 때랑 여러개의 원소를 추가할 때 쓰는 함수가 다르다.

하나의 함수를 추가할 때는 ADD 함수를 사용하고, 여러 개의 함수를 추가할 때는 UPDATE를 사용한다.

 

setOne = {1, 2, 3}

print(setOne) # 1,2,3 출력

setOne.remove(2) # setOne 변수에서 2라는 값을 제거

print(setOne) # 1,3 출력

REMOVE 함수는 우리가 리스트에서 다뤘던 내용처럼 이렇게 원소를 지정하여 지워줄 수 있다.

 

다음은, 너모너모 신기하게 쳐다보았던 딕셔너리라는 챕터이다.

딕셔너리를 짧게 말해보자면, 듀플과 리스트와 순서적으로 보는 방식이 아닌 KEY와 VALUE 값만을 이용하는 챕터이다.

이게 약간 배우면서도 C언어의 CASE 문을 보는 듯한 느낌이어서 너무 반가웠다.

ex_dict = { "a" : "python", "b" : "C", "c" : "java"}

print(ex_dict)
# 출력은 { "a" : "python", "b" : "C", "c" : "java"} 과 같이 된다.

print(ex_dict["a"])
# 출력은 python

다음 소스코드를 보자, ex_dict 라는 변수에는 a와 b 그리고 c라는 키 값이 들어가있고 그 상세내용으로는 다양한 벨류값이 존재한다.

키 값을 이용하여 벨류값을 꺼내올 수 있다는 이야기다, 이 부분을 보고 case문과 비슷하다는 느낌을 많이 받았다.

ex_dict = { "a" : "python", "b" : "C", "c" : "java"}

ex_dict["d"] = "C++"   # 딕셔너리에 키 값은 d, 벨류값은 C++로 추가를 하겠다는 말이다.
print(ex_dict) # {'a': 'python', 'b': 'C', 'c': 'java', 'd': 'C++'} 키 값이 추가되어 출력이 된다.

ex_dict.update({"b" : "javascript", "e" : "C#"})
print(ex_dict) # {'a': 'python', 'b': 'javascript', 'c': 'java', 'd': 'C++', 'e': 'C#'} 여러 개의 키 값이 추가되어 출력이 된다.

딕셔너리도 집합과 마찬가지로 여러개의 키와 벨류값을 추가할 때는 UPDATE 함수를 써주면 된다.

이때, 유의할 점은 이미 키 값이 존재한다면 벨류값은 기존 벨류값에서 새로운 벨류값으로 덮어쓰기 되어진다. 

 

딕셔너리에서 삭제는 del 함수를 사용해주면 된다.

ex_dict = { "a" : "python", "b" : "C", "c" : "java"}

del ex_dict["a"] # a의 키 값을 삭제해주면 벨류값도 같이 삭제가 되어진다.

print(ex_dict) # {'b': 'C', 'c': 'java'} 딕셔너리 값들이 출력이 된다.

키 값을 선택해주고 del 함수를 입력해주면, 벨류값 까지 동시에 같이 날아가게 된다.

혹시 그렇다면, 딕셔너리의 값들은 키와 벨류값으로 나눠져 있으니 따로 구분하여 출력을 할 수는 없을까 하는 생각이 들기도 한다.

다행히도, 딕셔너리에서는 구분을 해줄 수 있는 함수들을 지원해준다. 방법은 다음과 같다.

print(변수명.keys())
print(변수명.values())

keys와 values를 통해 구분 값을 따로 나열해줄 수 있다.

그런데 이렇게 나열을 하게 되면 변수_keys[(키 값들)] 와 같이 깔끔하게 출력이 되지 않는 문제점을 발생시킬 수 있다.

(사실 이게 상관없는 사람들이 있겠지만, 나는 깔끔한게 보기가 좋,, 좋다,,)

이를 해결해주기 위해서는 list 형으로 출력 형식을 변경해주어야한다. 

keys_lst = list(변수명.keys())
values_lst = list(변수명.values())

# [ ] 안에 원소들만이 들어가 깔끔한 출력을 할 수 있다.

앞에 list 를 붙여 list형으로 형 변환을 시켜줄 수 있다. 그렇게 되면 { } 와 부가적인 부분들을 제외한 [ ]의 리스트 원소 값만을 가져올 수 있다.

 

ㅇ,, 아,, 오늘 파이썬 챕터는 평소에는 짧게 다가왔는데 두 챕터를 연속으로 하려니까 살짝 힘들었다.

뭐 이 정도는 평소라면 힘들지 않았겠지만 짧은 챕터였다가 갑자기 길어지니까 몸이 못 받아들였나,, 

블로그 정리하는 부분은 내가 나중에도 볼 부분이라 꼼꼼하게 해야하는데 두 챕터를 한 번에 정리를 하려니 조금 힘들었지만, 오늘도 이렇게 막을 내렸다.

 

오늘은 3개의 문자열이 담긴 튜플을 선언하고, 딕셔너리를 통해 각각의 문자열의 길이를 저장한뒤 출력해보세요. 라는 주제로 과제가 나왔는데,

사실 튜플을 선언하고, 딕셔너리로 연결을 해주어 출력만 해주면 되는 간단한 과제이지만 나는 사용자로부터 입력을 받아 딕셔너리로 또 출력을 해주는 프로그램을 만들어보고 싶었다.

 

# 튜플로 변수에 문자열들을 넣어준다, 튜플은 값 변경 불가능
set01 = ("Hello")
set02 = ("This is Python")
set03 = ("Bye")

# 딕셔너리에 키 값은 튜플의 변수명으로, 벨류값은 튜플로 가져온 문자열들의 크기 값으로 넣어준다.
set04 = { set01 : len(set01), set02 : len(set02), set03 : len(set03)}
# 출력을 하게되면 set04 변수에 설정되어진 딕셔너리 값들이 출력이된다.
print(set04 , end="\n\n")

# try-except 문을 통해 예외처리, 추가적인 소스코드 부분
try:
    # 사용자에게 딕셔너리에 키와 벨류값을 넣을건지에 대한 의문을 제기한다.
    button = input("다음 듀플에 추가를 하고 싶다면 'P' 버튼을 입력해주세요 : ")
    # 대문자 P와 p가 아니면 예외처리문으로 향해 프로그램을 종료한다.
    if (button == "P") or (button == "p"):
        key = input("넣고싶은 키 값을 입력해주세요 : ")
        value = input("넣고싶은 벨류 값을 입력해주세요 :")
        print("입력이 모두 완료되었습니다 잠시만 기다려주세요…")
        # 사용자로부터 받은 키와 벨류값을 set04 변수에 딕셔너리 칸에 넣어준다.
        set04[key] = value
        # 추가 확인 메세지 및 출력부
        print("추가가 완료되었습니다.")
        print("추가되어진 딕셔너리 : " + str(set04))
    # 잘못 입력시에, 에러 except부로 향하도록 코딩했다.
    else:
        print(e)
# 예외발생시에 처리되는 프로그램 종료부
except:
    print("잘못 입력하셨습니다, 올바른 문자를 입력해주세요.")
    print("프로그램을 종료합니다.")
    exit()

그래서, 이렇게 조그마하게 만들어보았다. 평소에는 print(e)를 사용해보지 못했는데 에러출력부로 보내버리는 메세지를 오늘 이렇게 구글링하며 또 새롭게 알게되어 기분이 좋다. 한 부분 한 부분 내 알고리즘으로 만들어보니 코딩 하는 방식과 방법도 점차 알게 되어가는 것 같고, 멋진 컴퓨터 공대생이 되어야지-

 

뭐, 프로그램은 잘 작동한다. 반복문으로 무한루프를 돌려 계속 실행되는 프로그램을 만드려고 했으나, 너무 과제에 범위에서 멀어지는 것 같아서 저 기능만 추가를 하여 구현을 해보았다. 그렇게 오늘의 12일차도 무난하게 끝이 났다. 내일부터는 할머니 농장에서 일을 도와드리며 블로그 정리도 해야하고, 과제도 해야하는데 밀리지만 말자는 다짐을 오늘 굳게 하며 블로그 포스팅을 마쳐본다-! 화이또 화이또-!

 

13일차

13일차 대망의 클래스 챕터-

 

클래스는 붕어빵과 붕어방 틀에 비유를 한다고 한다,

붕어빵을 만들기 위해서는 붕어빵 재료, 팥, 붕어빵 틀 등이 있는데 여기서 클래스는 붕어빵 틀에 해당하는 친구이다.

그리고 이 붕어빵 틀을 통해 만들어지는 붕어빵을 객체라고 한다.

 

이 클래스에 의한 객체들은 각각의 고유의 기능고 성격을 가지고 있어 서로 다른 객체들에게 영향을 미치지 않는다는 특징을 가지고 있다.

클래스는 기본적으로 다음과 같이 선언을 해줄 수 있다.

class Test:
	pass

Test 라는 이름의 클래스를 만들어주었고, 그 안에는 pass를 넣어주었다.

여기서, pass 라는 코드는 클래스 안에 아무 코드가 정해지지 않았을 경우, 코드 대신 넣어주는 친구이다.

(pass로 이루어진 클래스는 아무 기능을 갖지 않은 클래스라는 말이다)

 

클래스가 만들어졌다면, 객체를 만들어주어야한다.

자바에서도 배웠듯이 일정 변수로 객체를 선언해주어야 메인부에서도 그 객체를 이용하여 코드를 헤쳐나갈 수 있다.

a = Test()   # a 객체 생성
b = Test()  # b 객체 생성

Test 클래스의 객체 a와 b를 생성해주었다.

클래스에 관련된 내용을 코드에 명시해줄때는 ( )를 사용해주는데, 이는 함수 사용법과 비슷한 모습을 띈다.

 

여기서 인스턴스라는 말이 있다고 한다. 배우면서도, 객체라는 말은 많이 사용을 했는데 인스턴스라는 단어에 대해서는 무언가 생소했다.

배우는 과정에서 다음과 같이 설명이 잘 되어있어 이렇게 블로그에도 주섬주섬,,

 

a는 객체이다. (O)

b는 Test의 객체이다. ( ? )

a는 Test의 인스턴스이다 (O)

 

객체와 인스턴스의 상관관계를 다음의 문장들을 보면 이해하기가 쉽다.

처음에는 무슨소리인가,, 했는데 자세히 보고 소스코드를 쳐보며 이해를 하니까 바로 이해가 되었다.

 

class Test:
    def setdata(self, x, y):
        self.x = x
        self.y = y
        
a = Test()
a.setdata(2,3)

print(a.x)
print(a.y)

위에 클래스를 명시해주고, 객체를 생성하는 방법을 배웠으니 한번 실전에 응용을 해보자

Test라는 클래스를 명시해주었고, 클래스 내부 함수에는 setdata라는 함수를 넣어주었다.

그런데 매개변수에 x,y 라는 값 이외에 self 라는 별도의 값이 또 하나가 존재한다. (ㅇ,, 이 뭐지,,? 처음보는 코드인데,,)

이 self 라는 친구는 setdata 함수를 불러온 객체 a를 전달하는 역할을 한다.

 

그러니까 매개변수로 쉽게 설명을 하자면, a.setdata(2,3) 으로 설정을 했다고 하면

def setdata(a, 2, 3) 이런 식으로 a의 객체를 전달하는 의미를 가진다.

그리고 그 함수 안에 self.x 와 self.y 또한 a.x와 a,y 로 해석을 할 수 있겠다.

 

· a → self 로 전달

· 2 → first로 전달

· 3 → second로 전달

 

이런 식으로 말이다, 처음에는 무슨 소리인가 했는데.. 이렇게 정리를 하고보니까 완벽히 이해를 했다.

 

위에 내가 클래스 안에 있는 setdata는 함수라고 명시를 했다.

그런데, 클래스 안에 있는 setdata와 같은 요소들이 함수는 맞지만 클래스 안 함수를 명시할 때는 메소드라고 명시를 한다고 한다.

(ㄱ,, 고쳐서 읽어야겠다,, 메소드으,,)

 

앗, 그리고 클래스는 동일하지만 객체명을 다르게 선언해준다면 위에서 말했듯이 메소드만 동일하게 쓰는 것이지 서로에게 전혀 영향을 주지 않는다.

(ㄷ,, 당연한 말이지만 나에게는 고냥 당연한 말이다-!)

 

그렇다면, 이 객체들에 넣어준 값들로 연산을 지정해보려고 한다.

class Test:
    def setdata(self, x, y):
        self.x = x
        self.y = y
    
    def add(self):
        sum = self.x + self.y
        return sum
        
a = Test()
a.setdata(2,3)

print(a.add())

위 코드에 add 메소드를 이어서 추가를 하였다.

여기서 add 메소드에서는 왜 매개변수를 써주지 않느냐에 대한 의문을 제기 할 수 있다.

그 이유는, 위에 setdata에서 x와 y에 대한 값을 지정해주었기때문에 setdata에서 x와 y값을 빼오는 add 메소드에서는 따로 지정을 해 줄 필요가 없다.

 

setdata라는 객체는 우리가 직접적으로 값을 매겨넣어주었지만,

객체를 생성하고, setdata라는 메소드를 통해 매개변수 값들을 매번 초기화시켜주어야한다.

이런 멤버 변수들을 일일이 설정하는 함수를 호출하는 것은 에러를 발생시킬 수 있는 가능성이 있으므로, 생성자를 통해 객체를 생성하게 되면

멤버변수들을 자동적으로 초기화시켜주는 것이 가능하다.

 

생성자를 생성하는 방법은 setdata의 방법보다 비교적 더 단순하다.

class Test:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        
    # def setdata(self, x,y):
        # self.x = x
        # self.y = y
    
    def add(self):
        sum = self.x + self.y
        return sum
        
a = Test(2,3)
# a.setdata(2,3)
print(a.add())

setdata 자리에 __init__ 을 넣어주면 된다.

다음 소스코드에 비교를 위해 위에 올려놓았던 setdata 코드와 같이 넣어놓았다.

 

이전 setdata에서는 객체를 생성해주고 또 그 객체를 이용해 setdata에 값을 넣어주었는데, 

생성자를 이용하면 객체 생성과 동시에 값을 매겨줄 수 있다.

또한, 코드의 가독성도 좋아지는 효과를 얻으며 효율적인 소스코드를 얻을 수 있다.

 

오늘은 클래스 부분이다, 자바에서도 어려웠던 클래스 부분이었지만 한 부분 한 부분 정독하고 또 정독하면서

소스코드 한 부분 한 부분에 열정을 쏟아보았다, 오늘의 과제는 클래스를 이용하여 자신만의 계산기를 만드는 내용이다.

사실 파이썬에도 case 문이 있는 줄 알았지만, if-elif 문을 통해 case 문을 손쉽게 만들 수 있다는 부분에서 파이썬에서는 case문이 없다는 것을 알았다.

그 덕에 if 문으로 호다닥 계산기도 만들고, 또 예외처리문도 조금은 더 완벽해질 수 있는 기회였다.

class Caculator:
        
    def __init__ (self, x, y):
        self.x = x
        self.y = y
    
    def add (self):
        sum = self.x + self.y
        return sum
        
    def minus(self):
        minus = self.x - self.y
        return minus
    
    def div(self):
        div = self.x / self.y
        return div
    
    def mul(self):
        mul = self.x * self.y
        return mul
        
while(True):
    try:
        num1 = input("첫번째 숫자를 입력해주세요 (종료는 P): ")
        if (num1 == "P") or (num1 == "p"):
            print("프로그램이 정상적으로 종료되었습니다.")
            break
        elif (type(int(num1)) == int):
            num1 = int(num1)
        else:
            print(e)
            
        num2 = int(input("두번째 숫자를 입력해주세요: "))

        a = Caculator(int(num1),num2)

        print("선택 가능한 사칙연산: +  -  *  / ")
        statement = input("원하는 사칙연산을 입력해주세요: ")

        if (statement == "+"):
            print("두 숫자의 합은 " + str(a.add()) + " 입니다.",end="\n\n")

        elif (statement == "-"):
            print("두 숫자의 뺄셈은 " + str(a.minus()) + " 입니다.",end="\n\n")

        elif (statement == "/"):
            print("두 숫자의 나눗셈은 " + str(a.div()) + " 입니다.",end="\n\n")

        elif (statement == "*"):
            print("두 숫자의 곱셈은 " + str(a.mul()) + " 입니다.",end="\n\n")
        else:
            print(e)
    except:
        print("잘못 입력하셨습니다, 다시 입력을 해주세요")

오늘 엄청 오랜시간이 걸릴 줄 알았는데, 속초 할머니 농장으로 가는 길에 차에서 클래스 챕터에 대한 부분을 공부하고

머릿 속으로 알고리즘을 생각하여 숙소에 도착하자마자 소스코드를 만들기 시작했다.

호다닥 블로그 정리도 끝내고, 나는 정말 미리미리 해놓아야한다. (ㅁ,, 밀리면,, 끝장나유,,)

그래도 오늘의 과제도 이렇게 성공적으로 끄읏-!

프로그램에 오류 하나 없다-! 점점 파이썬에 가까워지고 많이 친근해진 느낌, 내 꿈으로 한발짝 드가쟈-!

 

14일차

오늘은 클래스에 이어서, 상속에 대한 부분을 배워보았습니다-!

다른 곳에 맥북을 들고와서 과제를 하기까지의 이야기,, (사실 지굼 블로그 포스팅이 처음 이렇게 귀찮아진 느낌,, 그래도 해야지 현우야-!)

 

상속에 관한 챕터는 사실, 자바 프로그래밍을 배웠을 때 미리 배워보았던 내용이다.

부모 클래스를 통해 자식 클래스가 상속을 받아 부모의 속성을 그대로 사용하는 것인데, 부모 클래스에 대부분의 요소들이 들어있다면

자식 클래스는 상속만 받게되면 빈 내용으로도 여러 요소들을 받아 사용할 수 있다.

 

자바에서는 분명 조금 복잡하게 상속을 받았던 것 같은데, 파이썬에서는 정말 간단하게 상속 방식을 사용할 수 있었다.

class 아들클래스(부모클래스):
	pass

다음과 같이 아들클래스에 부모클래스를 씌어주는 느낌이다.

그리고, 부모클래스의 객체를 생성해주는 것이 아닌 아들클래스의 객체를 생성해주면 된다.

그렇게되면 자동적으로 부모클래스의 대부분의 요소들은 아드클래스로 자동 상속이 된다.

a = 아들클래스(2, 2) # 부모클래스의 여러 요소들을 상속받은 아들클래스에 (2,2)를 대입

이렇게 아들클래스의 객체를 만들어주면, 상속의 준비는 다 끝난 것이다.

그러면 한번 아들클래스 안에 요소들을 한번 추가해보자.

class 아들클래스(부모클래스):
	def Test(self):
		result = self.first + self.second
		return result

일부를 발췌해왔지만, 부모클래스에도 Test 라는 메소드가 있다고 가정을 해보자.

아들클래스와 부모클래스에 중첩된 메소드가 있다면, 부모클래스에 있는 Test 라는 메소드는 아들 클래스의 Test 메소드로 덮혀씌어진다.

이를 오버라이딩이라고 한다. 쉽게 말해, 아들클래스에 중복된 메소드를 사용하면 아들클래스가 새롭게 덮어쓰기를 하는 것이다. (새,, 새롭게 개척,,)

 

아, 그리고 위의 예제에서 아들클래스 안에 메소드에서 바로 매개변수도 받지 않고 self를 사용했는데

부모클래스에서 이미 매개변수들을 받았다면, 파이썬에서는 아들클래스에도 매개변수를 자동적으로 상속을 시켜준다.

(ㅁ,, 매우 신기하고,, 친화적인 친구다,, 나랑 더 친해지쟈 파이썬,,)

 

아들클래스의 생성자에서 따로 하는 작업이 없다면 굳이 자식클래스의 생성자를 만들어 줄 필요가 없지만,

나는 굳이 아들클래스에서 생성자에 관련된 작업을 하고 싶다한다면,

class 아들 클래스(부모 클래스):

def __init__(self, first, second):

super().__init__(first, second)

super() 이라는 메소드를 통해 생성자를 상속받을 수 있다. (안해줘도 파이썬에서 자동적으로 상속을 해준다-!)

(ㄱ,, 굳이 하고싶지는 않지만 혹시나 궁금해하는 사람들을 위해 이렇게 코뮤중앙에서 포스팅을 해준 것 같다!)

 

우리가 객체를 생성하고 했던 객체변수에서는 변수가 한번 생성이 되어지면 다른 객체에 영향을 주지 않고 영향을 받지 않는 고유의 형태를 띄게되는데,

클래스 변수는 클래스로 만든 모든 객체에 공유가 되어진다.

(ㅇ,, 이게 무슨 말이야-?!)

class Food:
	favorite = "테스트 전"

a = Food()
b = Food()
print(a.favorite, b.favorite)

# 값 바꾸기
Food.favorite = "테스트 중"
print(a.favorite, b.favorite)

Food 라는 클래스 안에 favorite 변수에 "테스트 전" 이라는 값이 들어가있다.

하지만, 밑에 클래스 안에 변수를 "테스트 후" 로 변경을 시킴으로써 클래스 안의 변수는 "테스트 후" 로 프로그램이 종료되기 전까지 값을 유지한다.

class Food:
	favorite = "테스트 전"

a = Food()
b = Food()
print(a.favorite)
print(id(a.favorite))  #id() 함수로 메모리값 확인
print(b.favorite)
print(id(b.favorite))  #id() 함수로 메모리값 확인

Food.favorite = "테스트 중"

print(Food.favorite)
print(id(Food.favorite))

print(a.favorite)
print(id(a.favorite))  #id() 함수로 메모리값 확인
print(b.favorite)
print(id(b.favorite))  #id() 함수로 메모리값 확인

이런 식으로, 이해가 안간다면 id 메소드를 통해 메모리 값을 확인할 수 있다.

테스트 전         # a.favorite의 값
2530850365488 # a.favorite의 메모리값
테스트 전         # b.favorite의 값
2530850365488 # b.favorite의 메모리값
테스트 후     # 클래스변수를 수정하고 클래스 변수 출력
2530850365584 # 클래스변수의 메모리값
테스트 후     # a.favorite의 값
2530850365584 # a.favorite의 메모리값
테스트 후     # b.favorite의 값
2530850365584 # b.favorite의 메모리값

이거 정말 이렇게까지 정리를 했는데, 까먹고 무슨 소리인지 모른다 현우야-?

나는 정말 바보녀석 인정이야,, 오늘은 상속에 대한 내용이 그리 길지 않아서 여기까지 정리를 하려고 한다-!

그래도 오늘 과제가 저번 클래스를 이용한 계산기 프로그램에 이어서 (어제 만든 계산기 프로그램으로 오늘의 코메상을 받았ㄷ,, 얏호-!) 상속을 받아 조금 더 완벽한 계산기 프로그램을 만드는 것인데, 오늘은 한번 더 신박하게 접근을 해보았다. 오늘 프로그래밍을 하면서 느낀거였는데, 처음에는 파이썬의 파라는 단어도 모르던 내가 어느새 긴 코드를 짜고 있다는 것을 ㄲ,, 깨달았다,, 유레카,,

count = 0

class Calculator:
    def __init__ (self, x, y):
        self.x = x
        self.y = y
    def add(self):
        sum = self.x + self.y
        return sum
    def div(self):
        sum = self.x / self.y
        return sum
    def minus(self):
        sum = self.x - self.y
        return sum
    def mul(self):
        sum = self.x * self.y
        return sum

class PerfectCalc(Calculator):
    def div(self):
        sum_1, sum_2 = divmod(self.x, self.y)
        return (sum_1, sum_2)

while(True):
    try:
        if (count == 0 ):
            print("사칙연산 계산기 프로그램입니다.")
        
        statement = input("연산 프로그램을 시작하시겠습니다? (Y/N): ")

        if (statement == "Y" or statement == "y"):
            num1 = int(input("첫번째 숫자를 입력해주세요 : "))
            num2 = int(input("두번째 숫자를 입력해주세요 : "))
            
            a = PerfectCalc(num1, num2)
            
            print("다음은 사용가능한 계산 기호들입니다.")
            print("1. 더하기")
            print("2. 빼기")
            print("3. 나눗셈")
            print("4. 곱셈")
            num3 = int(input("계산하고자 하는 기호의 숫자를 입력해주세요 : "))
            
            if(num3 == 1):
                print("두 수의 합은 " + str(a.add()) + " 입니다")
            elif(num3 == 2):
                print("두 수의 차는 " + str(a.minus()) + " 입니다")
            elif(num3 == 3):
                print("두 수를 나눴을 때, 몫은 " + str(a.div()[0]) + " 나머지는 " + str(a.div()[1]) + " 입니다")
            elif(num3 == 4):
                print("두 수의 곱은 " + str(a.mul()) + " 입니다")
            
        elif (statement == "N" or statement == "n"):
            print("종료버튼을 누르셨습니다. 프로그램을 종료합니다")
            break
            exit()

        else:
            print(e)
            
    except:
        print("잘못된 입력입니다, 다시 입력해주세요.")
        count += 1

이번에는 디테일하게 프로그램을 한번 만져보았는데, 처음 시작할때부터 YES OR NO 에 대한 질문이 오간다.

그리고, 부모클래스로부터 상속을 받아 일반적인 나눗셈을 divmod 파이썬 메소드를 통해 몫과 나머지를 구분지었다.

여기서 수업시간에 배운 튜플을 이용하여 인덱싱으로 출력을 해주었는데, 처음에 내가 직접 나눗셈을 해보는데 값이 다르게 나와서 이게 맞나,,

싶었는데 직접 나눗셈을 하고도 틀린 나의 머리를 탓했다-! (역시 컴퓨터는 거짓말을 하지 않아 찡긋-) 예외처리문도 깔끔하게 정리를 해주었다.

앗, 그리고 처음 알게된 사실인데 exit()를 시켜도 무한 루프에서 프로그램을 바로 종료시키는 것이 아니라 break 문으로 종료를 시켜줘야한다.

(ㅇ,, 이것때문에 연산 프로그램 시작할거냐 200번 본 것 같다,,)

 

그리고 다음 루프시에, 반복문구들이 너무 많아보여서 카운트 변수 값을 0으로 지정해주고 루프를 돌때마다 1을 증가하도록 하였다.

그리고 1 이상의 루프시에는 반복문구들이 나오지 않도록, 설계해놓았는데 어제보다 조금 더 디테일 한 계산기 프로그램이 완성되었다.

ㅃ,, 뿌듯- 

오늘은 농장에서 일도하고 와서 너~무 힘든 하루였는데, 간신히 멘탈을 부여잡고 과제에 임했다.

집에서 농장으로 가는 길에 과제를 미리 풀어놓아서 다행이기도 하고, 또 다양한 언어를 통해 미리 공부를 해놓아서 다행이다 싶었다.

오늘이 벌써 목요일이다. 아, 이번주 너무 바쁘게 살아,, 았나,, 다음주가 개강인데 이번주는 바쁘게 안 살아도 될 것 같기도 하구,,

그래도 오늘도 뿌듯하게 끝-! 수고하셨습니다 (__)!

 

코메가 약간 인싸느낌이었는데, 아싸의 인싸도전기,,

15일차

오늘은 마지막 모각코 대외활동의 날-

사실, 파이썬에 어떻게 다가갈지에 대한 의문을 한꺼번에 풀어준 모각코였는데 어느새 파이썬에 익숙해질 때쯔음 끝나가니 많이 아쉽다.

마지막 챕터는 어떤 내용을 배울까에 대해 궁금했는데, 오늘은 함수와 반복문에 관련된 도전문제로 막을 내렸다.

 

과제에 대한 주제는 리스트의 크기를 7이상으로 잡고, 그 리스트 안에서 최대 값의 위치를 찾는 과제였다.

(단, 매개변수를 이용한 함수를 사용해야ㅎ,, 한다-!)

 

예전에 배웠던 내용들이 가물가물했지만, 직접 한 부분 정리를 해가며 코딩을 했던 부분들이 많이 기억에 남아서

과제의 내용들을 보자마자 바로 코딩에 들어갔다. 오늘 할머니 농장에서 집으로 오는 동안, 차에서 거의 끝내놓을 정도로 파이썬에 관련된 

개발 실력이 많이 늘었다고 생각이 들었다. 중앙 코뮤니티에서 원하는 과제에 대한 해답은 모두 소스코드로 개발을 해놓았지만,

무언가 세세한 개발자라면 오류의 한끗이라도 놓치고 싶지않는 마음에 예외처리 부분, 사용자의 입력으로부터 이어질 오류에 대한 부분들을 한 부분 한 부분 

파악해가며 소스코드를 짜내려갔다.

 

예외처리도 금방하고, 함수 구현도 금방했는데 발목을 잡는 것은 바로 사용자로부터 입력을 받아 입력과 동시에 숫자들의 중복성을 제거하는 과정이었다.

어떻게 출력부분에서는 중복되는 부분을 찾게되는데 내부에서 중복을 처리하더라도, 리스트의 사이즈가 강제로 커지는 등 다양한 오류가 생겼다.

 

그렇게 3시간이 넘는 시간을 맥북을 붙잡고 늘어지고 늘어졌다.

도저히 답이 안나와서, 그냥 제출할까 하다가 언젠가는 내가 이 알고리즘을 배워야하고 이 알고리즘을 내가 직접 구현을 해본다면

언젠가 이 문제에 대한 해답이 내 머리 속 깊숙하게 있다가 바로 나와 도와줄 수 있다는 생각에 새벽까지 버티고 버텼다.

 

ㄱ,, 결국 구현을 해냈다, 인간승리,, ㅎ,, 흐엉,,

 

정말 간단하게 생각을 하게 소스코드를 작성했으면 되었었는데, 너무 복잡하게 생각을 했었던 것 같다.

def max_locate (x):

    count = 0
    
    for i in range (0, len(x)):
        if (max(x) != x[i]):
            count += 1
        elif (max(x) == x[i]):
            return count + 1
         
try :
            
    list = []


    print("여러 수들의 최댓값과 최대값의 위치를 찾는 프로그램입니다.")
    number = int(input("리스트의 크기를 입력해주세요: "))
    print("입력하신 리스트의 크기는 " + str(number) + " 입니다.",end="\n\n")

    for i in range (0, number):
        list_number = int(input(str(i+1)+"번째 숫자를 입력해주세요: "))
        list.insert(i,list_number)
                
        if (i>0):
            for j in range (0, i):
                if (list_number == list[j]):
                    del list[i]
                    while (list_number == list[j]):
                        list_number = int(input("중복 숫자가 존재 합니다, 다시 입력을 해주세요: "))
                        if (list_number != list[j]):
                            list.insert(i,list_number)
                        

    print("입력하신 숫자는 다음과 같습니다")
    print(list)

    print("최대 값은 " + str(max(list)) + "이고, 최대 값의 위치는 " + str(max_locate(list)) + "번째에 위치해있습니다")

except:
    print("잘못된 값을 입력하셨습니다, 프로그램을 종료합니다.")
    exit()

사실 파이썬의 문법만으로도 쉽게 구현을 할 수 있었지만, 그러기에는 너무 파이썬이라는 언어에 의존하는 것 같았다.

다양한 언어에서의 알고리즘을 차용하여 구현을 해보고 싶었고, C언어와 유사하게 초기화하거나 해당 메모리값을 지우는 형식으로 소스코드를 만들었다.

ㅊ,, 출력도 원활하게 잘 되어진다, 새벽 3시 48분 인간승리를 하고 여유로이 잠에 빠져든다.

 

15일이 넘는 시간 동안 전역을 하고 처음으로 도전하게 된 온라인 대외활동이다.

다음 시즌도 도전을 할 지는 의문이지만, 학습에 대한 즐거움이 무엇인지 알게되었으며

코딩에 대한 자신감도 얻었고 도전정신도 뿜뿜하게 얻게되었던 대외활동이었다.

 

너무 행복했던 시간이었고, 너무 값진 시간이었다. 그러기에 이 블로그 포스팅이 싫지만은 않았던 것 같다.

더 멋진 사람이 되기위한 한 발짝이었고, 앞으로도 더 넓은 세계로 향해보자-

그러면 빠이빠이-

 

 

댓글