계산기 프로세스부터 진행
#2일차 계산기 프로세스 부분 진행
# gui 가상환경에서 진행함 .\Scripts\activate
from tkinter import Tk, Button, Entry, END
win = Tk()
opers = []
nums = []
numStr = ''
def calc(target):
ch = target['text']
global opers, nums, numStr
if len(ch) == 1:
if ch != 'C' and ch != '%' and ch != 'v':
txt.insert(END, ch)
if ord(ch) >= 48 and ord(ch) <= 57:
numStr += ch
if ch == '+' or ch == '-' or ch == '*' or ch == '/':
nums.append(numStr)
opers.append(ch)
numStr = ''
if ch == '=':
nums.append(numStr)
result = int(nums[0])
for i, oper in enumerate(opers):
if oper == '+':
result += int(nums[i+1])
elif oper == '-':
result -= int(nums[i+1])
elif oper == '*':
result *= int(nums[i+1])
elif oper == '/':
result //= int(nums[i+1])
txt.insert(END, str(result))
return 0
txt = Entry(win, justify="right")
txt.grid(row=0, column=0, columnspan=5, pady=2)
btns = [
[Button(win, text="MC"), Button(win, text="MR"), Button(win, text="MS"), Button(win, text="M+"), Button(win, text="-M")],
[Button(win, text="<-"), Button(win, text="CE"), Button(win, text="C"), Button(win, text="+-"), Button(win, text="V")],
[Button(win, text="7"), Button(win, text="8"), Button(win, text="9"), Button(win, text="/"), Button(win, text="%")],
[Button(win, text="4"), Button(win, text="5"), Button(win, text="6"), Button(win, text="*"), Button(win, text="1/x")],
[Button(win, text="1"), Button(win, text="2"), Button(win, text="3"), Button(win, text="-"), Button(win, text="=")],
[Button(win, text="0"), Button(win, text="."), Button(win, text="+")]
]
for btnArr in btns:
for btn in btnArr:
def clickEvent(target=btn):
calc(target)
btn.config(command=clickEvent)
for i in range(1, 6):
for j in range(5):
if i==6 and j==3:
break
if i==5 and j==4:
btns[i-1][j].grid(row=i, column=j, rowspan=2, padx=2, pady=2, sticky='wens')
else:
btns[i-1][j].grid(row=i, column=j, padx=2, pady=2, sticky='wens')
btns[5][0].grid(row=6, column=0, columnspan=2, padx=2, pady=2, sticky='wens')
btns[5][1].grid(row=6, column=2, padx=2, pady=2, sticky='wens')
btns[5][2].grid(row=6, column=3, padx=2, pady=2, sticky='wens')
if __name__ == '__main__':
win.mainloop()
|
4.2 메모장 만들기
메모장 개발
- GUI 구성
- 메모장 기능 구현
import os
from tkinter import *
root = Tk()
root.title("메모장 이름")
root.geometry("640x480") # 가로 * 세로
# 열기, 저장 파일 이름
filename = "저장됐을 때 파일 이름"
def open_file():
if os.path.isfile(filename): # 파일 있으면 True, 없으면 False
with open(filename, "r", encoding="utf8") as file:
txt.delete("1.0", END) # 텍스트 위젯 본문 삭제
txt.insert(END, file.read()) # 파일 내용을 본문에 입력
def save_file():
with open(filename, "w", encoding="utf8") as file:
file.write(txt.get("1.0", END)) # 모든 내용을 가져와서 저장
menu = Menu(root)
menu_file = Menu(menu, tearoff=0)
menu_file.add_command(label="열기", command=open_file)
menu_file.add_command(label="저장", command=save_file)
menu_file.add_separator()
menu_file.add_command(label="끝내기", command=root.quit)
menu.add_cascade(label="파일", menu=menu_file)
# 편집, 서식, 보기, 도움말(장식)
menu.add_cascade(label="편집")
menu.add_cascade(label="서식")
menu.add_cascade(label="보기")
menu.add_cascade(label="도움말")
# 스크롤 바
scrollbar = Scrollbar(root)
scrollbar.pack(side="right", fill="y")
# 본문 영역
txt = Text(root, yscrollcommand=scrollbar.set)
txt.pack(side="left", fill="both", expand=True)
scrollbar.config(command=txt.yview)
root.config(menu=menu)
root.mainloop()
if __name__ == '__main__':
root.mainloop()
|
프로세스 추가
from tkinter import *
import os
from tkinter.filedialog import *
es = ""
def newFile():
top.title("제목없음- 메모장")
file = None
ta.delete(1.0,END)
def openFile():
file = askopenfilename(title = "파일 선택", filetypes = (("텍스트 파일", "*.txt"),("모든 파일", "*.*")))
top.title(os.path.basename(file) + " - 메모장")
ta.delete(1.0, END)
f = open(file,"r")
ta.insert(1.0,f.read())
f.close()
def saveFile():
f = asksaveasfile(mode = "w", defaultextension=".txt")
if f is None:
return
ts = str(ta.get(1.0, END))
f.write(ts)
f.close()
def cut():
global es
es = ta.get(SEL_FIRST, SEL_LAST)
ta.delete(SEL_FIRST, SEL_LAST)
def copy():
global es
es = ta.get(SEL_FIRST, SEL_LAST)
def paste():
global es
ta.insert(INSERT, es)
def delete():
ta.delete(SEL_FIRST, SEL_LAST)
def help():
he = Toplevel(top)
he.geometry("200x200")
he.title("정보")
lb = Label(he, text = "메모장 버전 1.0\n 파이썬으로 만든 메모장입니다^^")
lb.pack()
top = Tk()
top.title("메모장")
top.geometry("400x400")
ta = Text(top)
sb = Scrollbar(ta)
sb.config(command = ta.yview)
top.grid_rowconfigure(0, weight=1)
top.grid_columnconfigure(0, weight=1)
sb.pack(side = RIGHT, fill = Y)
ta.grid(sticky = N + E + S + W)
file = None
mb = Menu(top)
fi = Menu(mb, tearoff=0)
fi.add_command(label="새파일", command=newFile)
fi.add_command(label="열기", command=openFile)
fi.add_command(label="저장", command=saveFile)
fi.add_separator()
fi.add_command(label="종료", command=top.destroy)
mb.add_cascade(label="파일", menu=fi)
e = Menu(mb, tearoff=0)
e.add_command(label="잘라내기", command=cut)
e.add_command(label="복사", command=copy)
e.add_command(label="붙이기", command=paste)
e.add_command(label="삭제", command=delete)
mb.add_cascade(label="편집", menu=e)
h = Menu(mb, tearoff=0)
h.add_command(label="메모장 정보", command = help)
mb.add_cascade(label="도움말", menu=h)
top.config(menu=mb)
top.mainloop()
|
Tips & Examples
1. Magic Commands
- IPython 커널에서 제공되는 기능으로 '%' 또는 '%%' 접두사를 사용하며, 다양한 기능을 수행함
- 자주 쓰이는 Magic Commands
- %time 및 %timeit: 코드 실행 시간 측정
- %time: 한 번 실행한 시간 표시
- %timeit: 여러 번 실행하여 평균 및 표준 편차 제공
- %autosave: 파일 자동 저장 주기 설정
- %%html: HTML 코드를 셀 내에서 실행하고 표시
- %system: 시스템 명령어 실행
- %%writefile: : 파일 쓰기
- %run: 외부 Python 파일 실행
- %who: 변수 목록을 표시
- %store: 변수를 저장하고 공유하는 기능 제공. 주피터 노트북 간의 데이터 공유에 활용됨
- %env: 환경 변수 나열
- %matplotlib inline: matplotlib 그래프를 Jupyter Notebook에 표시
- %history: 코드셀의 실행 이력을 목록으로 취득
- %time 및 %timeit: 코드 실행 시간 측정
- 자주 쓰이는 Magic Commands
- IPython: Python 언어를 위해 개발된 상호작용적인 컴퓨팅을 위한 명령 셸
- 자가 검사(introspection): 객체나 함수의 정보를 쉽게 확인할 수 있음
- 대화형 매체(interactive media): 그림, 음성, 비디오 등 다양한 미디어를 표시, 재생할 수 있음
- 셸 문법(shell syntax): 셸 명령어를 사용하여 파일을 관리하거나 시스템 명령을 실행할 수 있음
- 탭 완성(tab completion): 탭 키를 누르면 자동으로 변수, 함수, 모듈 이름을 완성해줌
- 히스토리(history): 이전에 실행한 코드를 검색하고 재사용할 수 있음
- %time : 한 번 실행한 시간 측정
CPU times: user 321 µs, sys: 53 µs, total: 374 µs
Wall time: 377 µs
49995000
- %timeit: 여러 번 실행하여 평균 및 표준 편차 제공
211 µs ± 8.9 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
- Loop 횟수: 200번, 시행횟수: 5회 지정
205 µs ± 12.2 µs per loop (mean ± std. dev. of 5 runs, 200 loops each)
- 코드 셀 전체에 적용할 때 %% 사용
66.3 µs ± 6.13 µs per loop (mean ± std. dev. of 3 runs, 500 loops each)
- 파일 자동 저장 주기 설정 (예: 60초)
- 코렙의 경우 따로 하지 않아도 자동 설정되어 있음.
Autosaving every 60 seconds
- HTML 코드 실행 및 표시
Hello, world!
- 시스템 명령어 실행 (예: 디렉토리 내 파일 목록)
['sample_data']
- 파일 쓰기
Writing my_file.txt
Writing my_script.py
- 외부 Python 파일 실행
Hello, World!!!
300
변수 목록 표시
a b c
데이터 공유
Stored 'data' (list)
노트북 종료하고 다시 시작한 수 변수 불러오기
[1, 2, 3]
환경 변수 나열
matplotlib 그래프 Jupyter Notebook에 표시(Colab에서는 불필요함)
앞에 작성했던 코드들 쭉 나열
2. Examples
2.1.1 총 페이지 뷰 수 계산하기
총 페이지뷰: [327]
2.1.2 고유 방문자 수 계산하기
고유 방문자수: [99]
2.1.3 총 서비스 용량 계산하기
총 서비스 용량: 29289KB
2.1.4 사용자별 서비스 용량 계산하기
서비스 아이피에 대해서 용량 정렬
2.2 에코 서버 만들기(1)
- 에코 서버
- 네트워크로 메시지를 수신하여 송신자에게 수신한 메시지를 그대로 돌려보내는 서버
- 네트워크 통신의 기본이 되는 소켓 프로그래밍을 접해보자
- 네트워크 소켓
- 네트워크 통신에 있어서 시작점이자 끝점
- 클라이언트-서버 프로그램의 가장 핵심이 되는 모듈
- 서버와 클라이언트는 각자의 네트워크 소켓을 가지고 있음
- 네트워크 통신을 위해 사용되는 프로토콜의 종류에 따라 TCP/UDP/Raw 소켓으로 구분됨
- TCP 소켓:
- TCP(Transmission Control Protocol)를 활용하는 네트워크 소켓
- 연결 지향적 프로토콜(두 개를 완전히 연결)
- 포트 번호를 이용하여 서비스를 식별
- 데이터의 신뢰성 있는 전송을 보장함(중간에 떨어지지 않음)
- 데이터의 순서, 무결성, 신뢰성을 보장함
- 주로 웹, 메일, 파일 공유와 같이 데이터 누락을 허용하지 않는 서비스에서 사용됨
- TCP(Transmission Control Protocol)를 활용하는 네트워크 소켓
- UDP 소켓:
- UDP(User Datagram Protocol)를 활용하는 네트워크 소켓
- 비연결 지향적 프로토콜
- 포트 번호를 이용하여 서비스를 식별
- 빠른 데이터 전송을 목적으로함(신뢰성 보다는 속도를 중시함)
- 연결 설정 과정 없이 데이터를 전송
- 데이터의 순서나 무결성은 보장하지 않음
- VoIP (Voice over IP)와 같이 속도가 중요한 서비스에서 사용됨
- UDP(User Datagram Protocol)를 활용하는 네트워크 소켓
- Raw 소켓:
- 특정한 프로토콜에 대한 전송 계층 포매팅 없이 인터넷 프로토콜 패킷을 직접 주고 받을 수 있는 인터넷 소켓
- 데이터를 전송할 때 직접 프로토콜 헤더를 만들어 전송하고, 데이터를 수신할 때도 프로토콜 헤더를 포함하여 수신
- 라우터나 네트워크 장비 등에 주로 활용되며 사용자 공간에서 새로운 전송 계층 프로토콜을 구현하는 데에도 활용됨
- TCP 소켓:
2.2.1 서버
import socket
HOST = ''
PORT = 9009
def runServer():
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
sock.bind(HOST, PORT) # 바인딩
sock.listen(1)
print("클라이언트 연결을 기다리는 중")
conn, addr = sock.accept()
with conn:
print('[%s]와 연결됨' % addr[0])
while True:
data = conn.recv(1024)
if not data:
break
print('메세지 수진 [%s]' %data.decode())
conn.sendall(data)
runServer()
|
2.2.2 클라이언트
클라이언트는 한번 주고 받으면 끝인데, 일을 계속 하고싶으면 계속 돌리면 된다.
import socket
HOST = 'localhost' # 127.0.0.1
PORT = 9009
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
sock.connect((HOST, PORT))
msg = input('메시지 입력: ')
sock.sendall(msg.encode()) # 클라이언트는 인코딩을 통해 전달함
data = sock.recv(1024)
print('에코 서버로부터 받은 데이터 [%s]' %data.decode())
|
각각 따로 터미널에서 실행시켜서 클라이언트 를 활용해 아래와 같이 동작시킴
터미널 2개를 따로 사용함(server 와 client 를 각각 다른 터미널에서 동작시킴)
메시지 입력: 안녕하세요
에코 서버로부터 받은 데이터 [안녕하세요]
2.3 에코 서버 만들기(2)
2.3.1 서버
import socketserver
HOST = ''
PORT = 9009
class MyTcpHandler(socketserver.BaseRequestHandler):
def handle(self):
print('[%s] 연결됨' %self.client_address[0])
try:
while True:
self.data = self.request.recv(1024)
if self.data.decode() == '/quit':
print('[%s] 사용자에 의해 중단' %self.client_address[0])
return
print('[%s]' %self.data.decode())
self.request.sendall(self.data)
except Exception as e:
print(e)
def runServer():
print('+++ 에코 서버를 시작합니다.')
print('+++ 에코 서버를 끝내려면 Ctrl-C를 누르세요.')
try:
server = socketserver.TCPServer((HOST, PORT), MyTcpHandler)
server.serve_forever()
except KeyboardInterrupt:
print('--- 에코 서버를 종료합니다.')
runServer()
|
2.3.2 클라이언트
import socket
HOST = 'localhost'
PORT = 9009
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
sock.connect((HOST, PORT))
while True:
msg = input('메시지 입력: ')
if msg == '/quit':
sock.sendall(msg.encode())
break
sock.sendall(msg.encode())
data = sock.recv(1024)
print('에코 서버로부터 받은 데이터 [%s]' %data.decode())
print('클라이언트 종료')
|
메시지 입력: 안녕하세요2
에코 서버로부터 받은 데이터 [안녕하세요2]
메시지 입력: 반갑습니다
에코 서버로부터 받은 데이터 [반갑습니다]
메시지 입력: 파이팅
에코 서버로부터 받은 데이터 [파이팅]
메시지 입력: /quit
클라이언트 종료
'PYTHON-BACK' 카테고리의 다른 글
#파이썬 도서관 출납 시스템_16일차 (1) | 2024.07.22 |
---|---|
#파이썬 기초 16일차 (0) | 2024.07.22 |
#파이썬 기초 14일차 (0) | 2024.07.18 |
#파이썬 기초 13일차 (0) | 2024.07.17 |
#파이썬 기초 12일차 (3) | 2024.07.16 |