미국 공학박사 아빠의 코딩 연구소

딕셔너리(Dictionary)로 코딩을 편리하게

보다 효율적이고 체계적이며 확장성이 좋은 코딩을 위해, 우리의 코딩 지식을 조금씩 확장하고 있는데요.
이번 강의에서는 Python의 또 다른 데이터 타입인 딕셔너리(Dictionary)를 이용해서 코딩을 조금 더 편리하게 해보려 해요.
이번에도 키클봇 서버 코드를 조금만 바꿔 볼게요. 정말 조금만 바꿀 거랍니다.


강의들은 모두 무료입니다. 단, 저작권은 키클 코딩랩 에 있으며, 무단 복제 및 배포를 엄금합니다.
이를 어길 시, 본 사이트의 서버가 미국에 있으므로, 미국법에 의해 처벌될 수도 있습니다.




키클봇 서버 코드 분석하기

먼저, 원하는 폴더에 새로운 Python파일을 만들고, "lec14_kiklebot.py"라고 파일 이름을 지어 보세요.
그리고, 파일을 열고, 강의 라이브러리로 코딩을 고급스럽게에서 작성했던 키클봇 서버 코드("lec13_kiklebot.py")를 아래와 같이 복사해 넣을게요. 각 코드들에 대한 자세한 설명으로 복습이 필요하면 꼭 되돌아 가서 확인하고 오세요.
그리고, 키클봇 라이브러리(lec13_kiklebot_lib.py) 파일을 "lec14_kiklebot.py"와 같은 폴더에 다운로드 받으세요. 키클봇 라이브러리를 계속 사용할 것이랍니다.

lec14_kiklebot.py
import socket               
import matplotlib.pyplot as plt
import numpy as np
from lec13_kiklebot_lib import KikleBot   # import lec13_kiklebot_lib as my_lib
	
s = socket.socket()         
host = "localhost" 
port = 5000                
s.bind((host, port))        
s.listen(5)                 
conn, addr = s.accept()     

my_bot = KikleBot(np.array([[0, 0]]))   # my_bot = my_lib.KikleBot(np.array([[0, 0]]))
fig = plt.figure()

while (True):
	fig.clf()
	plt.plot(my_bot.coord[0, 0], my_bot.coord[0, 1], 'bs', markersize=10)
	plt.plot(my_bot.traj[:, 0], my_bot.traj[:, 1], 'b')
	plt.xlim([-10 + my_bot.coord[0, 0], 10 + my_bot.coord[0, 0]])	
	plt.ylim([-10 + my_bot.coord[0, 1], 10 + my_bot.coord[0, 1]])	
	plt.pause(0.01)

	print("waiting...")
	key = conn.recv(5)
	conn.send("server received command".encode("utf-8"))
	key = key.decode('utf-8')

	idx_move = 0
	if (key == 'l'):
		idx_move = 0
	elif (key == 'i'):
		idx_move = 1
	elif (key == 'j'):
		idx_move = 2
	elif (key == 'k'):
		idx_move = 3
	elif (key == 'q'):
		conn.close()               
		break
	
	my_bot.move_bot(idx_move)

위 코드를 보면, 다소 불편하게 만들어진 코드가 있는데요.
바로, 줄30~줄37 부분이예요. 각 키값마다, 이동 방향을 저장하는 idx_move 변수에 들어갈 값을 정하느라 비슷한 패턴의 코드가 반복해서 들어가고 있지요.
이렇게 반복적인 패턴을 간결한 기법으로 코딩을 해놓으면, 가독성이 좋아져 추후에 코드를 다시 읽기에도 편하고 다른 사람과 협동 프로젝트를 수행하기에도 좋답니다. 코드의 수준이 높아보여, 다른 사람들에게 자신의 실력을 뽐내기에도 좋은 것은 덤이지요!
그럼 어떤 방법을 사용해야 될까요? 우리는 딕셔너리(Dictionary)를 적용할 거랍니다.




딕셔너리(Dictionary) 공부하고 이용하기

딕셔너리(Dictionary)는 사전이라는 의미이지요?
그 의미처럼 코딩하는 방식도 사전이랑 비슷하답니다. 아래에서 자세히 알아볼게요.

[문법] 딕셔너리 (Dictionary)

딕셔너리에 대한 공부가 충분히 되었나요?
그럼, "lec14_kiklebot.py"의 줄30~줄37에서 나타나는 반복적인 패턴을 딕셔너리를 이용하여 간편하면서 효율적인 코딩으로 교체해 볼게요.
아래에서 줄16과 줄32~줄36 부분을 주목해서 보세요.

lec14_kiklebot.py
import socket               
import matplotlib.pyplot as plt
import numpy as np
from lec13_kiklebot_lib import KikleBot   # import lec13_kiklebot_lib as my_lib
	
s = socket.socket()         
host = "localhost" 
port = 5000                
s.bind((host, port))        
s.listen(5)                 
conn, addr = s.accept()     

my_bot = KikleBot(np.array([[0, 0]]))   # my_bot = my_lib.KikleBot(np.array([[0, 0]]))
fig = plt.figure()

key_dict = {"l": 0, "i": 1, "j": 2, "k": 3}

while (True):
	fig.clf()
	plt.plot(my_bot.coord[0, 0], my_bot.coord[0, 1], 'bs', markersize=10)
	plt.plot(my_bot.traj[:, 0], my_bot.traj[:, 1], 'b')
	plt.xlim([-10 + my_bot.coord[0, 0], 10 + my_bot.coord[0, 0]])	
	plt.ylim([-10 + my_bot.coord[0, 1], 10 + my_bot.coord[0, 1]])	
	plt.pause(0.01)

	print("waiting...")
	key = conn.recv(5)
	conn.send("server received command".encode("utf-8"))
	key = key.decode('utf-8')

	idx_move = 0
	if (key == 'q'):
		conn.close()               
		break
	else:
		idx_move = key_dict[key]
	
	my_bot.move_bot(idx_move)

줄16에서는, 딕셔너리를 선언하고 있어요. 키 "l"는 0, "i"는 1, "j"는 2, "k"는 3과 짝을 이루어 딕셔너리를 구성하고 있지요.
줄32~줄36은 기존에 있던 반복적인 if 문들을 딕셔너리를 이용한 간단한 코드로 교체하고 있어요.
줄32는 명령 클라이언트에서 받은 키보드 명령이 저장되어 있는 key 변수(여기서 key는 단지 변수 이름일 뿐이예요. 딕셔너리에서 말하는 key와는 상관이 없답니다.)가 'q'를 가지고 있는지를 점검하는 코드예요.
줄33에서는, 만약 키보드 명령이 'q'라면, 명령 클라이언트와의 연결을 유지하는 소켓 conn을 닫으라고 하고 있어요.
줄34에서는, 키보드 명령이 'q'인 경우, break를 이용하여 무한루프를 탈출하고 있지요.
줄35에서는, 키보드 명령이 'q'가 아닌 경우를 위하여, else문을 시작하고 있어요.
줄36에서는, 줄16에서 만든 딕셔너리를 이용하고 있는데요. 키보드 명령을 지니고 있는 key변수를 전달함으로써, 그에 대응하는 숫자 value를 딕셔너리로부터 반환하고, 그 숫자를 이동 방향을 저장하는 변수 idx_move에 할당하고 있지요.
어떤가요? 딕셔너리를 이용함으로써, 비슷한 패턴을 가지고 반복적으로 작성되었던 코드를 간단하고 명료한 코드로 교체할 수 있다는 것을 느낄 수 있었나요?
이번 강의의 내용은 이것이 전부예요. 약속한대로 정말 조금만 바꾸었답니다~~




원격 조종 실행하기

이제, 딕셔너리를 이용해 조금더 간단하고 명료해진 키클봇 서버 코드를 실행 해볼까요?
위에서 작성한 파일 "lec14_kiklebot.py"을 저장하고, 터미널에서 "python3 lec14_kiklebot.py"로 키클봇 서버를 실행해 보세요. 단, 강의 처음에서 말했듯이, 같은 폴더에 "lec13_kiklebot_lib.py"가 있어야 한답니다.

이제, 명령 클라이언트를 실행해 볼게요. 이전 강의 원격으로 키클봇 조종하기에서 작성했던 명령 클라이언트(lec12_cmd.py)을 "lec14_kiklebot.py"와 같은 폴더에 다운로드 받으세요.
그리고, 아래 보이는 것처럼 "lec14_kiklebot.py"을 실행한 터미널 창 위의 아무 지점에서나 마우스 오른쪽 버튼을 누르세요. 그러면 새로 열리는 팝업 메뉴에서 "Open Terminal"을 클릭해서 새 터미널 창을 여세요.

그리고, "python3 lec12_cmd.py"로 클라이언트를 실행해 보세요. (실행 방법에 대해서 복습이 필요하면 여기로)
실행하면, 아래와 같이 클라이언트를 실행한 터미널 창 위에 figure창이 생성되지요.
이렇게 Figure창이 활성화되면, 키보드 명령을 내릴 수가 없으니, 아래 보이는 화살표 표시 처럼, 명령 클라이언트를 실행한 터미널 창을 마우스 왼쪽버튼 클릭하여 활성화 상태로 만드세요.

그리고, 'i', 'j', 'k', 'l' 키들을 누르면, figure 창에 움직이는 키클봇이 보인답니다. 즉, 클라이언트를 통해 원격으로 명령을 보내고, 그 명령을 받은 서버가 키클봇에게 전달하여 키클봇이 움직이는 것이지요.
원격 조종을 멈추고 싶다면, 'q'를 눌러서 무한루프 탈출해야 하는 것 잊지 마세요!

강의에서 작성된 소스 코드 (source code)를 다운받으려면, 다음 링크를 클릭하세요: 서버 소스 코드 다운로드, 키클봇 라이브러리 소스 코드 다운로드, 명령 클라이언트 소스 코드 다운로드
혹시, 이해가 잘 안되는 부분에 대한 질문이 있거나 다루어 줬으면 하는 주제가 있으면, 화면 오른쪽 하단에 "질문하기" 버튼을 이용해 주세요.






발자취

2019-09-11 "키클 코딩랩 - 미국 공학박사 아빠의 코딩 연구소"로 이름 변경
2019-06-28 코딩 교실 공개
2019-03-18 코딩 교실 제작 시작

바로가기
About
Contact
Privacy Policy
강의목록
질문하기
처음으로