포토샵

from tkinter import *
from tkinter .filedialog import *
from tkinter .simpledialog import *
from PIL import Image, ImageFilter, ImageEnhance, ImageOps

# 함수 선언 부분
def displayImage(img, width, height):
    global window, canvas, paper, photo, photo2, oriX, oriY
    
    window.geometry(str(width) + "x" + str(height))
    if canvas != None:
        canvas.destroy()
    
    canvas = Canvas(window, width=width, height=height)
    paper = PhotoImage(width=width, height=height)
    canvas.create_image((width / 2, height / 2), image=paper, state="normal")
    rgbString = ""
    rgbImage = img.convert('RGB')
    for i in range(0, height):
        tmpString = ""
        for k in range(0, width):
            r, g, b = rgbImage.getpixel((k, i))
            tmpString += "#%02x%02x%02x " % (r, g, b) #x 뒤에 한 칸 공백
        rgbString += "{" + tmpString + "} " # } 뒤에 한 칸 공백
    paper.put(rgbString)
    canvas.pack()

def func_open():
    global window, canvas, paper, photo, photo2, oriX, oriY
    readFp = askopenfilename(parent=window, filetypes=(("모든 그림 파일", "*.jpg;*.jpeg;*.bmp;*.png;*.tif;*.gif"),("모든 파일", "*.*")))
    photo = Image.open(readFp).convert('RGB')
    oriX = photo.width
    oriY = photo.height

    photo2 = photo.copy()
    newX = photo2.width
    newY = photo2.height
    displayImage(photo2, newX, newY)

def func_save():
    global window, canvas, paper, photo, photo2, oriX, oriY

    if photo2 == None:
        return
    saveFp = asksaveasfile(parent = window, mode = "w", defaultextension= ".jpg",
                filetypes = (("JPG 파일", "*.jpg; *.jpeg"), ("모든 파일", "*.*")))
    
    photo2.save(saveFp.name)

def func_exit():
    exit()

def func_zoomin():
    global window, canvas, paper, photo, photo2, oriX, oriY
    scale = askinteger("확대", "확대할 배율을 입력하세요", minvalue= 2, maxvalue= 4)
    photo2 = photo.copy()
    photo2 = photo2.resize((int(oriX*scale), int(oriY*scale)))
    newX = photo2.width
    newY = photo2.height
    displayImage(photo2, newX, newY)

def func_zoomout():
    global window, canvas, paper, photo, photo2, oriX, oriY
    scale = askinteger("축소", "축소할 배율을 입력하세요", minvalue= 2, maxvalue= 4)
    photo2 = photo.copy()
    photo2 = photo2.resize((int(oriX/scale), int(oriY/scale)))
    newX = photo2.width
    newY = photo2.height
    displayImage(photo2, newX, newY)

def func_mirror1():
    global window, canvas, paper, photo, photo2, oriX, oriY
    photo2 = photo.copy()
    photo2 = photo2.transpose(Image.FLIP_TOP_BOTTOM)
    newX = photo2.width
    newY = photo2.height
    displayImage(photo2, newX, newY)

def func_mirror2():
    global window, canvas, paper, photo, photo2, oriX, oriY
    photo2 = photo.copy()
    photo2 = photo2.transpose(Image.FLIP_LEFT_RIGHT)
    newX = photo2.width
    newY = photo2.height
    displayImage(photo2, newX, newY)

def func_rotate():
    global window, canvas, paper, photo, photo2, oriX, oriY
    dgree = askinteger("회전", "회전할 각도를 입력하세요", minvalue= 0, maxvalue= 360)
    photo2 = photo.copy()
    photo2 = photo2.rotate(dgree, expand=True)
    newX = photo2.width
    newY = photo2.height
    displayImage(photo2, newX, newY)

def func_bright():
    global window, canvas, paper, photo, photo2, oriX, oriY
    value = askfloat("밝게", "값을 입력하세요(1.0 ~ 10.0)", minvalue= 1.0, maxvalue= 10.0)
    photo2 = photo.copy()
    photo2 = ImageEnhance.Brightness(photo2).enhance(value)
    newX = photo2.width
    newY = photo2.height
    displayImage(photo2, newX, newY)

def func_dark():
    global window, canvas, paper, photo, photo2, oriX, oriY
    value = askfloat("어둡게", "값을 입력하세요(0.0 ~ 1.0)", minvalue= 0.0, maxvalue= 1.0)
    photo2 = photo.copy()
    photo2 = ImageEnhance.Brightness(photo2).enhance(value)
    newX = photo2.width
    newY = photo2.height
    displayImage(photo2, newX, newY)

def func_blur():
    global window, canvas, paper, photo, photo2, oriX, oriY
    photo2 = photo.copy()
    photo2 = photo2.filter(ImageFilter.BLUR)
    newX = photo2.width
    newY = photo2.height
    displayImage(photo2, newX, newY)

def func_emboss():
    global window, canvas, paper, photo, photo2, oriX, oriY
    photo2 = photo.copy()
    photo2 = photo2.filter(ImageFilter.EMBOSS)
    newX = photo2.width
    newY = photo2.height
    displayImage(photo2, newX, newY)

def func_bw():
    global window, canvas, paper, photo, photo2, oriX, oriY
    photo2 = photo.copy()
    photo2 = ImageOps.grayscale(photo2)
    newX = photo2.width
    newY = photo2.height
    displayImage(photo2, newX, newY)

# 전역 변수 선언 부분
window, canvas, paper = None, None, None
photo, photo2 = None, None
oriX, oriY = 0, 0

# 메인 코드 부분
window = Tk()
window.geometry("250x250")
window.title("미니 포토샵")

mainMenu = Menu(window)
window.config(menu=mainMenu)

fileMenu = Menu(mainMenu)
mainMenu.add_cascade(label="파일", menu=fileMenu)
fileMenu.add_command(label="파일 열기", command=func_open)
fileMenu.add_command(label="파일 저장", command=func_save)
fileMenu.add_separator()
fileMenu.add_command(label="프로그램 종료", command=func_exit)

imageMenu1 = Menu(mainMenu)
mainMenu.add_cascade(label="이미지 처리(1)", menu=imageMenu1)
imageMenu1.add_command(label="확대", command=func_zoomin)
imageMenu1.add_command(label="축소", command=func_zoomout)
imageMenu1.add_separator()
imageMenu1.add_command(label="상하 반전", command=func_mirror1)
imageMenu1.add_command(label="좌우 반전", command=func_mirror2)
imageMenu1.add_command(label="회전", command=func_rotate)

imageMenu2 = Menu(mainMenu)
mainMenu.add_cascade(label="이미지 처리(2)", menu=imageMenu2)
imageMenu2.add_command(label="밝게", command=func_bright)
imageMenu2.add_command(label="어둡게", command=func_dark)
imageMenu2.add_separator()
imageMenu2.add_command(label="블러링", command=func_blur)
imageMenu2.add_command(label="엠보싱", command=func_emboss)
imageMenu2.add_separator()
imageMenu2.add_command(label="흑백 이미지", command=func_bw)

window.mainloop()

 

 

게임

import pygame
import random
import sys


## 함수 선언 부분 ##
def paintEntity(entity, x, y):
    monitor.blit(entity, (int(x), int(y)))


def writeScore(score):
    myFont = pygame.font.Font('ch14/NanumGothic.ttf', 20)  # 한글 폰트
    txt = myFont.render(u'파괴한 우주괴물 수 : ' + str(score), True, (255-r, 255-g, 255-b))
    monitor.blit(txt, (10, sheight - 40))


def playGame():
    global monitor, ship, monster, missile

    r = random.randrange(0, 256)
    g = random.randrange(0, 256)
    b = random.randrange(0, 256)

    # 우주선의 초기 위치와 키보드를 눌렀을 때 이동량을 저장할 변수를 선언
    shipX = swidth / 2
    shipY = sheight * 0.8
    dx, dy = 0, 0

    # 우주괴물을 무작위로 추출하고 크기와 위치를 설정
    monster = pygame.image.load(random.choice(monsterImage))
    monsterSize = monster.get_rect().size
    monsterX = 0
    monsterY = random.randrange(0, int(swidth * 0.3))
    monsterSpeed = random.randrange(1, 5)

    # 미사일 좌표 초기화
    missileX, missileY = None, None

    # 맞춘 우주괴물 숫자를 저장할 변수
    fireCount = 0

    # 무한 반복
    while True:
        (pygame.time.Clock()).tick(50)
        monitor.fill((r, g, b))  # 게임 진행을 늦춘다(10~100 정도가 적당)

        # 키보드나 마우스 이벤트가 들어오는지 체크
        for e in pygame.event.get():
            if e.type in [pygame.QUIT]:
                pygame.quit()
                sys.exit()

            if e.type in [pygame.KEYDOWN]:
                if e.key == pygame.K_LEFT:
                    dx = -5
                elif e.key == pygame.K_RIGHT:
                    dx = +5
                elif e.key == pygame.K_UP:
                    dy = -5
                elif e.key == pygame.K_DOWN:
                    dy = +5
                elif e.key == pygame.K_SPACE:
                    if missileX == None:  # 미사일을 쏜 적이 없다면
                        missileX = shipX + shipSize[0] / 2
                        missileY = shipY  # 우주선 위치에서 미사일을 발사

            if e.type in [pygame.KEYUP]:
                if e.key == pygame.K_LEFT or e.key == pygame.K_RIGHT or \
                   e.key == pygame.K_UP or e.key == pygame.K_DOWN:
                    dx, dy = 0, 0

        # 우주선이 화면 안에서만 움직이게 한다.
        if (0 < shipX + dx and shipX + dx <= swidth - shipSize[0]) and \
           (sheight / 2 < shipY + dy and shipY + dy <= sheight - shipSize[1]):
            shipX += dx
            shipY += dy

        paintEntity(ship, shipX, shipY)

        # 우주괴물이 자동으로 나타나 왼쪽에서 오른쪽으로 움직인다.
        monsterX += monsterSpeed
        if monsterX > swidth:
            monsterX = 0
            monsterY = random.randrange(0, int(swidth * 0.3))
            monster = pygame.image.load(random.choice(monsterImage))
            monsterSize = monster.get_rect().size
            monsterSpeed = random.randrange(1, 5)

        paintEntity(monster, monsterX, monsterY)

        # 미사일을 화면에 표시한다.
        if missileX != None:
            missileY -= 10
            if missileY < 0:
                missileX, missileY = None, None

        # 우주괴물이 미사일에 맞았는지 체크
        if missileX != None:
            paintEntity(missile, missileX, missileY)
            if (monsterX < missileX and missileX < monsterX + monsterSize[0]) and \
               (monsterY < missileY and missileY < monsterY + monsterSize[1]):
                fireCount += 1  # 우주괴물을 맞혔을 때
                
                monster = pygame.image.load(random.choice(monsterImage))
                monsterSize = monster.get_rect().size
                monsterX = 0
                monsterY = random.randrange(0, int(swidth * 0.3))
                monsterSpeed = random.randrange(1, 5)
                missileX, missileY = None, None

        writeScore(fireCount)  # 점수를 화면에 출력
        pygame.display.update()  # 화면을 업데이트


## 전역 변수 선언 부분 ##
r, g, b = [0] * 3
swidth, sheight = 500, 700
monitor = None
ship, shipSize = None, 0
monsterImage = ['ch14/game_image/monster01.png', 'ch14/game_image/monster02.png', 'ch14/game_image/monster03.png', 'ch14/game_image/monster04.png', 
                'ch14/game_image/monster05.png', 'ch14/game_image/monster06.png', 'ch14/game_image/monster07.png', 'ch14/game_image/monster08.png', 
                'ch14/game_image/monster09.png', 'ch14/game_image/monster10.png']
monster = None
missile = None

## 메인 코드 부분 ##
pygame.init()
monitor = pygame.display.set_mode((swidth, sheight))
pygame.display.set_caption('우주괴물 무찌르기')

ship = pygame.image.load('ch14/game_image/ship01.png')
shipSize = ship.get_rect().size
missile = pygame.image.load('ch14/game_image/missile.png')

playGame()

 

*폰트는 여기서 다운 받으면 된다.

https://hangeul.naver.com/font

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

데이터베이스  (1) 2024.12.05
객체지향 프로그래밍  (1) 2024.12.05
파일 입출력  (0) 2024.12.05
윈도 프로그래밍  (2) 2024.12.05
함수와 모듈  (0) 2024.12.05

https://eatitstory.tistory.com/69

 

악성코드 샘플 분석2

샘플파일이번에 분석해 볼 파일은 dgrep.exe 기초 분석 Virustotal-Virustotal에서 스캔을 해보았다.-72개의 엔징 중 68개의 엔진이 해당 파일을 악성 파일로 추정된다.-각 엔진들을 봐보면 Backdoor, Trojan,

eatitstory.tistory.com

 

위에 정리한 글을 토대로 악성코드 분석 보고서 작성

 

악성코드 분석 보고서.docx
4.33MB

 

 

 

 

 

'Notice' 카테고리의 다른 글

[알토르] 웹사이트 프로젝트 수업 정리  (0) 2024.06.18

데이터베이스 소프트웨어=DBMS

DBMS에는 계층형, 망형, 관계형, 객체지향형, 객체관계형 등으로 나눈다.

그중 가장 많이 사용하는 건 관계형 DBMS(=RDBMS)
속도가 느리다는 단점이 있기는 하지만 요즘 기술이 발달해 예전보다는 많이 나아짐

DBMS-DB-TABLE-ROW&COLUMN





selfstudy13-1.py

 
.open 데이터베이스 이름
-데이터베이스 생성 또는 열기(있으면 열고 없으면 생성)
 
create table 테이블 이름(열이름1 데이터형식, 열이름2 데이터형식.....)
-테이블 생성
 
insert into 테이블 이름 values(값1, 값2...)
-데이터 입력
 
select * from 테이블이름
-데이터 조회
 
 +추가
.header: 현재 db의 테이블 목록을 보여준다.
.schema 테이블이름: 테이블의 열 및 데이터 형식 등 정보를 보여준다
.header on. 조회시 헤더를 보여준다
mode column: 조회시 컬럼 모드로 출력한다
.quit: 종료
 

데이터베이스 연결을 위한 코드

.connect()
-데이터베이스 연결
 
.cursor()
-커서생서->통로 생성
 
.execute
-명령어 실행(ex. insert.... 또는  select..... 등등)
 
.commit
-저장
 
.fetchnone()
-한 행씩 출력
 
.close
-닫기
 
 
 
Code13-01.py

import sqlite3

##변수 선언 부분##
con, cur = None, None
data1, data2, data3, data4 = "", "", "", ""
sql = ""

##메인코드부분##
con = sqlite3.connect("c:/sqlite/naverDB")
cur = con.cursor()

while(True):
    data1 = input("사용자ID ==> ")
    if data1 == "":
        break
    data2 = input("사용자이름 ==> ")
    data3 = input("이메일 ==> ")
    data4 = input("출생연도 ==> ")
    sql = "INSERT INTO userTable VALUES ('" + data1 + "', '" + data2 + "','" + data3 + "', " + data4 +")" #char같은 문자열은 '를 넣어주고 int 같은 숫자는 그냥 집어 넣는다
    cur.execute(sql)

con.commit()
con.close()

 data1~3은작은따옴표로 묶지만 data4는 정수이므로 묶으면 안된다.
 
selftstudy13-2.py

import sqlite3

# 변수 선언 부분
con, cur = None, None
data1, data2, data3, data4 = "", "", 0, 0  # 데이터 입력 변수 초기화
sql = ""

# 메인 코드 부분
con = sqlite3.connect("c:/sqlite/naverDB")  # 데이터베이스 파일 연결
cur = con.cursor()

# 테이블 생성 (존재하지 않을 경우)
cur.execute("""
    CREATE TABLE IF NOT EXISTS productTable (
        pCode char(5) PRIMARY KEY,
        pName char(3),
        price int,
        amount int
    )
""")

while True:
    data1 = input("제품 코드 ==> ")
    if data1 == "":
        break
    data2 = input("제품 이름 ==> ")
    data3 = input("가격 ==> ")
    data4 = input("재고수량 ==> ")
    
    # SQL문 작성 및 실행
    try:
        sql = "INSERT INTO productTable (pCode, pName, price, amount) VALUES (?, ?, ?, ?)"
        cur.execute(sql, (data1, data2, int(data3), int(data4)))  # 파라미터 바인딩으로 안전하게 값 입력
    except sqlite3.IntegrityError:
        print(f"제품 코드 '{data1}'는 이미 존재합니다. 다른 코드를 사용하세요.")
    except ValueError:
        print("가격과 재고는 숫자로 입력해야 합니다.")
    except Exception as e:
        print(f"오류 발생: {e}")

con.commit()  # 변경 사항 저장
con.close()   # 연결 종료

print("프로그램이 종료되었습니다.")

 
selfstudy13-3.py

import sqlite3

## 변수 선언 부분 ##
con, cur = None, None
data1, data2, data3, data4 = "", "", 0, 0
row = None

## 메인 코드 부분 ##
con = sqlite3.connect("c:/sqlite/naverDB")  # 데이터베이스 연결
cur = con.cursor()

cur.execute("SELECT * FROM productTable")  # productTable 조회
print("제품 코드      제품 이름      가격      재고수량")
print("------------------------------------------------")

while True:
    row = cur.fetchone()
    if row is None:
        break
    data1 = row[0]  # pCode
    data2 = row[1]  # pName
    data3 = row[2]  # price
    data4 = row[3]  # amount
    print("%8s %10s %10d %10d" % (data1, data2, data3, data4))

con.close()  # 데이터베이스 연결 종료

 
Code13-02.py

import sqlite3

##변수 선언 부분##
con, cur = None, None
data1, data2, data3, data4 = "", "", "", ""
row = None

##메인코드부분##
con = sqlite3.connect("c:/sqlite/naverDB")
cur = con.cursor()

cur.execute("SELECT * FROM userTable")
print("사용자ID        사용자이름       이메일    출생연도")
print("--------------------------------------------------------------------")

while(True):
    row = cur.fetchone()
    if row == None:
        break
    data1 = row[0]
    data2 = row[1]
    data3 = row[2]
    data4 = row[3]
    print("%5s %15s %20s %d" %(data1,data2,data3,data4))

con.close()

 
 
Code13-03.py

import sqlite3
from tkinter import *
from tkinter import messagebox

# 데이터 삽입 함수
def insertData():
    con, cur = None, None
    data1, data2, data3, data4 = "", "", "", ""
    sql = ""

    con = sqlite3.connect("c:/sqlite/naverDB")  # DB 경로 설정
    cur = con.cursor()

    data1 = edt1.get()
    data2 = edt2.get()
    data3 = edt3.get()
    data4 = edt4.get()

    try:
        sql = "INSERT INTO userTable VALUES('" + data1 + "', '" + data2 + "', '" + data3 + "', " +data4 + ")"
        cur.execute(sql)
    except:
        messagebox.showerror('오류', '데이터 입력 오류가 발생함')
    else:
        messagebox.showinfo('성공', '데이터 입력 성공')
        con.commit()
        con.close()

# 데이터 조회 함수
def selectData():
    strData1, strData2, strData3, strData4 = [], [], [], []
    con = sqlite3.connect("c:/sqlite/naverDB")  # DB 경로 설정
    cur = con.cursor()
    cur.execute("SELECT * FROM userTable")
    strData1.append("사용자ID")
    strData2.append("사용자이름")
    strData3.append("이메일")
    strData4.append("출생연도")

    strData1.append("--------")
    strData2.append("--------")
    strData3.append("--------")
    strData4.append("--------")

    while True:
        row = cur.fetchone()
        if row is None:
            break
        strData1.append(row[0])
        strData2.append(row[1])
        strData3.append(row[2])
        strData4.append(row[3])

    listData1.delete(0, listData1.size() -1)
    listData2.delete(0, listData2.size() -1)
    listData3.delete(0, listData3.size() -1)
    listData4.delete(0, listData4.size() -1)

    for item1, item2, item3, item4 in zip(strData1, strData2, strData3, strData4):
        listData1.insert(END, item1)
        listData2.insert(END, item2)
        listData3.insert(END, item3)
        listData4.insert(END, item4)

    con.close()

# 메인 코드
window = Tk()
window.geometry("600x300")
window.title("GUI 데이터 입력")

edtFrame = Frame(window)
edtFrame.pack()
listFrame = Frame(window)
listFrame.pack(side=BOTTOM, fill=BOTH, expand=1)

edt1 = Entry(edtFrame, width=10)
edt1.pack(side=LEFT, padx=10, pady=10)
edt2 = Entry(edtFrame, width=10)
edt2.pack(side=LEFT, padx=10, pady=10)
edt3 = Entry(edtFrame, width=10)
edt3.pack(side=LEFT, padx=10, pady=10)
edt4 = Entry(edtFrame, width=10)
edt4.pack(side=LEFT, padx=10, pady=10)

btnInsert = Button(edtFrame, text="입력", command=insertData)
btnInsert.pack(side=LEFT, padx=10, pady=10)
btnSelect = Button(edtFrame, text="조회", command=selectData)
btnSelect.pack(side=LEFT, padx=10, pady=10)

listData1 = Listbox(listFrame, bg='yellow')
listData1.pack(side=LEFT, fill=BOTH, expand=1)
listData2 = Listbox(listFrame, bg='yellow')
listData2.pack(side=LEFT, fill=BOTH, expand=1)
listData3 = Listbox(listFrame, bg='yellow')
listData3.pack(side=LEFT, fill=BOTH, expand=1)
listData4 = Listbox(listFrame, bg='yellow')
listData4.pack(side=LEFT, fill=BOTH, expand=1)

window.mainloop()

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

미니프로젝트  (0) 2024.12.06
객체지향 프로그래밍  (1) 2024.12.05
파일 입출력  (0) 2024.12.05
윈도 프로그래밍  (2) 2024.12.05
함수와 모듈  (0) 2024.12.05

 

 

클래스=현실 세계의 사물을 컴퓨터 안에서 구현하려고 고아뇐 개념

 

속성=필드

클래스 안 함수= 매소드

 

Code12-01.py

#class 이름 앞글자는 대문자/ 붕어빵 틀
#class 안에 함수는 메소드
#class 사용 -> 객체
#클래스로 만든게 인스턴스디 / 인스턴스마다 인스턴스 변수가 다르다
#클래스 안에 변수는 필드
#필드는 값을 저장
#메소드는 작업
#클래스(설계도)->인스턴스(실제 자동차/클레스로 만들어낸 객체를 부르는 명칭)


class Car :
    color = ""
    speed = 0.

    def upSpeed(self, value):
        self.speed += value
    
    def downSpeed(self, value):
        self.speed -= value

-self.speed->자신의 클래스에 있는 speed 변수

-매소드(self, value)-self는 사용안되고 value만 사용된다

-self를 사용하는 이유는 필드에 접근하기 위해서다.

 

 

 

인스턴스->실제로 구현 됨=객체

 

Code12-02.py

#클래스 선언 부분
class Car :
    color = "" #필드선언
    speed = 0

    def upSpeed(self, value): #매서드선언
        self.speed += value
    
    def downSpeed(self, value):
        self.speed -= value

# 메인 코드 부분
myCar1 = Car()          #인스턴스
myCar1.color = "빨강"    #인스턴스 필드명 = 값
myCar1.speed = 0          #매소드 

myCar2 = Car()
myCar2.color = "파랑"
myCar2.speed = 0

myCar3 = Car()
myCar3.color = "노랑"
myCar3.speed = 0

myCar1.upSpeed(30) #인스턴스 매서드()
print("자동차1의 색상은 %s이며, 현재 속도는 %dkm입니다." % (myCar1.color, myCar1.speed))

myCar2.upSpeed(60)
print("자동차2의 색상은 %s이며, 현재 속도는 %dkm입니다." % (myCar2.color, myCar2.speed))

myCar3.upSpeed(0)
print("자동차3의 색상은 %s이며, 현재 속도는 %dkm입니다." % (myCar3.color, myCar3.speed))

-

 

 

selfstudy12-1.py

# 클래스 선언 부분
class Car:
    color = ""  # 필드 선언
    speed = 0

    def upSpeed(self, value):  # 메서드 선언
        self.speed += value
        if self.speed > 150:  # 최대 속도 제한
            self.speed = 150

    def downSpeed(self, value):
        self.speed -= value

# 메인 코드 부분
myCar1 = Car()  # 인스턴스
myCar1.color = "빨강"
myCar1.speed = 0

myCar2 = Car()
myCar2.color = "파랑"
myCar2.speed = 0

myCar3 = Car()
myCar3.color = "노랑"
myCar3.speed = 0

myCar1.upSpeed(200)  # 150으로 제한됨
print("자동차1의 색상은 %s이며, 현재 속도는 %dkm입니다." % (myCar1.color, myCar1.speed))

myCar2.upSpeed(60)
print("자동차2의 색상은 %s이며, 현재 속도는 %dkm입니다." % (myCar2.color, myCar2.speed))

myCar3.upSpeed(0)
print("자동차3의 색상은 %s이며, 현재 속도는 %dkm입니다." % (myCar3.color, myCar3.speed))

 

 

생성자 = 인스턴스르 생성하면 무조건 호출되는 매서드

인스턴스를 생성하면서 필드값을 초기화시키는 함수

 

Code12-03.py

#클래스 선언 부분
class Car :
    color = "" #필드선언
    speed = 0

    def __init__(self):
        self.color = "빨강"
        self.speed = 0

    def upSpeed(self, value): #매서드선언
        self.speed += value
    
    def downSpeed(self, value):
        self.speed -= value

# 메인 코드 부분
myCar1 = Car()#인스턴스
myCar2 = Car()

print("자동차1의 색상은 %s이며, 현재 속도는 %dkm입니다." % (myCar1.color, myCar1.speed))
print("자동차2의 색상은 %s이며, 현재 속도는 %dkm입니다." % (myCar2.color, myCar2.speed))

-init은 self외에 별도의 매개변수가 없는 생성자를 기본 생성자라 한다

 

Code12-04.py

#클래스 선언 부분
class Car :
    color = "" #필드선언
    speed = 0

    def __init__(self, value1, value2):
        self.color = value1
        self.speed = value2

    def upSpeed(self, value): #매서드선언
        self.speed += value
    
    def downSpeed(self, value):
        self.speed -= value

# 메인 코드 부분
myCar1 = Car("빨강", 30)  #인스턴스
myCar2 = Car("파랑", 60)

print("자동차1의 색상은 %s이며, 현재 속도는 %dkm입니다." % (myCar1.color, myCar1.speed))
print("자동차2의 색상은 %s이며, 현재 속도는 %dkm입니다." % (myCar2.color, myCar2.speed))

-매개변수가 있는 생성자

 

Code12-05.py

#클래스 선언 부분
class Car :
    name = "" #필드선언
    speed = 0

    def __init__(self, name, speed):
        self.name = name
        self.speed = speed

    def getName(self): #매서드선언
        return self.name
    
    def getSpeed(self):
        return self.speed

#변수선언 부분
car1, car2 = None, None

# 메인 코드 부분
car1 = Car("아우디", 0)#인스턴스
car2 = Car("벤츠", 0)

print("%s의 현재 속도는 %dkm입니다." % (car1.getName(), car1.getSpeed()))
print("%s의 현재 속도는 %dkm입니다." % (car2.getName(), car2.getSpeed()))

-getName(), getSpeed()메서드를 사용해서 자동차 이름과 속도를 반환하고  값을 알아낸다.

 

Code12-06.py

#클래스 선언 부분
class Car :
    color = "" #인스턴스 변수
    speed = 0 #인슽너스 변수
    count = 0 #클래스 변수

    def __init__(self):
        self.speed = 0
        Car.count += 1

#변수선언 부분
car1, car2 = None, None

# 메인 코드 부분
myCar1 = Car()
myCar1.speed = 30
print("자동차1의 현재 속도 %dKM, 생산된 자동차는 총 %d대입니다." % (myCar1.speed, Car.count))

myCar2 = Car()
myCar2.speed = 60
print("자동차2의 현재 속도 %dKM, 생산된 자동차는 총 %d대입니다." % (myCar2.speed, Car.count))

-인스턴스 변수는 인스턴스에 공간이 생김

-클래스 변수는 클래스 안에 공간이생김

 

 

 

상속

class 서브클래스(슈퍼클래스)

 

Code12-07.py

# 클래스 선언 부분
class Car:
    speed = 0

    def upSpeed(self, value):
        self.speed += value
        
        print("현재 속도(슈퍼 클래스): %d" % self.speed)


class Sedan(Car):
    def upSpeed(self, value):
        self.speed += value
        
        if self.speed > 150:  # 속도 제한
            self.speed = 150

            print("현재 속도(서브 클래스): %d" % self.speed)


class Truck(Car):
    pass

# 변수 선언 부분
sedan1, truck1 = None, None

# 메인 코드 부분
truck1 = Truck()
sedan1 = Sedan()

print("트럭 --> ", end="")
truck1.upSpeed(200)  # 트럭의 속도를 200 증가

print("승용차 --> ", end="")
sedan1.upSpeed(200)  # 승용차의 속도를 200 증가 (제한 적용)

-매서드 오버라이딩:상위 클래스의 매서드를 서브 클래스에서 재정의

 

 

selfstudy12-2.py

# 클래스 선언 부분
class Car:
    speed = 0

    def upSpeed(self, value):
        self.speed += value
        print("현재 속도(슈퍼 클래스): %d" % self.speed)


class Sedan(Car):
    def upSpeed(self, value):
        self.speed += value
        if self.speed > 150:  # 속도 제한
            self.speed = 150
        print("현재 속도(서브 클래스): %d" % self.speed)


class Truck(Car):
    pass


class Sonata(Sedan):  # Sonata 클래스는 Sedan을 상속받음
    pass


# 변수 선언 부분
sedan1, truck1, sonata1 = None, None, None

# 메인 코드 부분
truck1 = Truck()
sedan1 = Sedan()
sonata1 = Sonata()

print("트럭 --> ", end="")
truck1.upSpeed(200)  # 트럭의 속도를 200 증가

print("승용차 --> ", end="")
sedan1.upSpeed(200)  # 승용차의 속도를 200 증가 (제한 적용)

print("소나타 --> ", end="")
sonata1.upSpeed(200)  # 소나타의 속도를 200 증가 (제한 적용)

 

Code12-08.py

import turtle
import random

# 슈퍼 클래스
class Shape:
    myTurtle = None
    cx, cy = 0, 0

    def __init__(self):
        self.myTurtle = turtle.Turtle('turtle')

    def setPen(self):
        r = random.random()
        g = random.random()
        b = random.random()
        self.myTurtle.pencolor((r, g, b))
        pSize = random.randrange(1, 10)
        self.myTurtle.pensize(pSize)

    def drawShape(self):
        pass


class Rectangle(Shape):
    width, height = [0] * 2

    def __init__(self, x, y):
        super().__init__()  # 부모 클래스 초기화
        self.cx = x
        self.cy = y
        self.width = random.randrange(20, 100)
        self.height = random.randrange(20, 100)

    def drawShape(self):
        sx1 = self.cx - self.width / 2
        sy1 = self.cy - self.height / 2
        sx2 = self.cx + self.width / 2
        sy2 = self.cy + self.height / 2

        self.setPen()  # 펜 설정
        self.myTurtle.penup()
        self.myTurtle.goto(sx1, sy1)  # 시작 위치 이동
        self.myTurtle.pendown()
        self.myTurtle.goto(sx1, sy2)  # 위쪽 변
        self.myTurtle.goto(sx2, sy2)  # 오른쪽 변
        self.myTurtle.goto(sx2, sy1)  # 아래쪽 변
        self.myTurtle.goto(sx1, sy1)  # 왼쪽 변


# 함수 선언 부분
def screenLeftClick(x, y):
    rect = Rectangle(x, y)  # 클릭한 좌표에 Rectangle 객체 생성
    rect.drawShape()        # 사각형 그리기


# 메인 코드 부분
turtle.title('거북이로 객체지향 사각형 그리기')
turtle.onscreenclick(screenLeftClick, 1)  # 왼쪽 클릭 이벤트 등록
turtle.done()

 

클래스의 특별한  메서드

Code12-09.py

##클래스 선언 부분##
class Line :
    length = 0
    def __init__(self, length) :
        self.length = length
        print(self.length, '길이의 선이 생성되었습니다.')

    # 소멸자
    def __del__(self):
        print(self.length, '길이의 선이 삭제되었습니다.')

    # 객체 표현 (출력 시 호출)
    def __repr__(self):
        return "선의 길이 : " + str(self.length)

    # 두 선 길이 더하기
    def __add__(self, other):
        return self.length + other.length

    # 두 선 비교 (길이가 작은 경우)
    def __lt__(self, other):
        return self.length < other.length

    # 두 선 비교 (길이가 같은 경우)
    def __eq__(self, other):
        return self.length == other.length


# 메인 코드
myLine1 = Line(100)
myLine2 = Line(200)

# 객체 출력
print(myLine1)

# 두 선의 길이 합
print('두 선의 길이 합:', myLine1 + myLine2)

# 두 선 비교
if myLine1 < myLine2:
    print('선분 2가 더 기네요.')
elif myLine1 == myLine2:
    print('두 선분이 같네요.')
else:
    print('모르겠네요.')

# 객체 삭제
del(myLine1)

# #100 길이의 선이 생성되었습니다.
# 200 길이의 선이 생성되었습니다.
# 선의 길이 : 100
# 두 선의 길이 합: 300
# 선분 2가 더 기네요.
# 100 길이의 선이 삭제되었습니다.
# 200 길이의 선이 삭제되었습니다. -> 얘는 우리 코드가 아닌 프로그램이 종료되면서 자동으로 생성됨

 

 

추상메서드

Code12-10.py

# 클래스 선언 부분
class SuperClass:
    def method(self):
        pass

class SubClass1(SuperClass):
    def method(self):       # 메서드 오버라이딩
        print('SubClass1에서 method()를 오버라이딩함')

class SubClass2(SuperClass):
    pass

# 메인 코드 부분
sub1 = SubClass1()
sub2 = SubClass2()

sub1.method()
sub2.method()

-메서드오버라이딩을 하려는데 슈퍼클래스는 빈 껍질로 만들고 서브를 오버라이딩 하려면 pass 사용하면 된다.

 

 

멀티 스레드

스레드: 프로그램 하나에서 여러 개를 동시에 처리할 수 있도록 제공하는 기능

 

Code12-11.py

import time

class RacingCar:
    def __init__(self, name):
        self.carName = name

    def runCar(self):
        for _ in range(3):
            carStr = self.carName + " ~ 달립니다.\n"
            print(carStr, end="")
            time.sleep(0.1)  # 0.1초 멈춤


# 메인 코드 부분
car1 = RacingCar("@자동차1")
car2 = RacingCar("#자동차2")
car3 = RacingCar("$자동차3")

car1.runCar()
car2.runCar()
car3.runCar()

 

 

Code12-12.py

import threading
import time

class RacingCar:
    def __init__(self, name):
        self.carName = name

    def runCar(self):
        for _ in range(3):
            carStr = self.carName + " ~ 달립니다.\n"
            print(carStr, end="")
            time.sleep(0.1)  # 0.1초 멈춤

# 메인 코드 부분
car1 = RacingCar("@자동차1")
car2 = RacingCar("#자동차2")
car3 = RacingCar("$자동차3")

th1 = threading.Thread(target = car1.runCar)
th2 = threading.Thread(target = car2.runCar)
th3 = threading.Thread(target = car3.runCar)

th1.start()
th2.start()
th3.start()

 

멀티 프로세싱:동시에 여러 cpu 사용

Code12-13.py

import multiprocessing
import time

#클래서 선언
class RacingCar:
    def __init__(self, name):
        self.carName = name

    def runCar(self):
        for _ in range(3):
            carStr = self.carName + " ~ 달립니다.\n"
            print(carStr, end="")
            time.sleep(0.1)  # 0.1초 멈춤

# 메인 코드 부분
if __name__ == "__main__":
    car1 = RacingCar("@자동차1")
    car2 = RacingCar("#자동차2")
    car3 = RacingCar("$자동차3")

    mp1 = multiprocessing.Process(target = car1.runCar)
    mp2 = multiprocessing.Process(target = car2.runCar)
    mp3 = multiprocessing.Process(target = car3.runCar)

    mp1.start()
    mp2.start()
    mp3.start()

    mp1.join() # 기다린다
    mp2.join()
    mp3.join()

 

selfstudy12-3.py

import threading

# 합 계산을 위한 클래스 정의
class SumCalculator:
    def __init__(self, start, end):
        self.start = start
        self.end = end
        self.result = 0

    def calculate_sum(self):
        self.result = sum(range(self.start, self.end + 1))
        print(f"Sum of {self.start} to {self.end}: {self.result}")

# 메인 코드 부분
calc1 = SumCalculator(1, 1000)
calc2 = SumCalculator(1, 100000)
calc3 = SumCalculator(1, 10000000)

# 각 계산을 별도의 스레드로 실행
th1 = threading.Thread(target=calc1.calculate_sum)
th2 = threading.Thread(target=calc2.calculate_sum)
th3 = threading.Thread(target=calc3.calculate_sum)

# 스레드 시작
th1.start()
th2.start()
th3.start()

# 모든 스레드가 끝날 때까지 대기
th1.join()
th2.join()
th3.join()

print("모든 계산이 완료되었습니다.")

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

미니프로젝트  (0) 2024.12.06
데이터베이스  (1) 2024.12.05
파일 입출력  (0) 2024.12.05
윈도 프로그래밍  (2) 2024.12.05
함수와 모듈  (0) 2024.12.05

키보드에 입력되는 것을 표준입력

화면에 출력되는 것을 표준출력

키보드+화면 콘솔

 

파일 입출력 기본 과정

파일열기(변수명 = open("파일명", "r" or "w"))->파일 읽기 및 파일 쓰기 작업->파일 닫기(변수명.close())

 

 

 

텍스트 파일 입출력

data1.txt

CookBook 파이썬을 공부합니다.
완전 재미있어요. ^^
파이썬을 공부하기 잘했네요~~

 

 

Code11-01.py

inFp = None
inStr = ""

inFp = open("ch11/data1.txt", "r", encoding="utf-8")  

inStr = inFp.readline()
print(inStr, end = "")

inStr = inFp.readline()
print(inStr, end = "")

inStr = inFp.readline()
print(inStr, end = "")

inFp.close()

-.readline():한행씩 읽어 inFp 파일에 집어 넣는다

 

Code11-02.py

inFp = None
inStr = ""

inFp = open("ch11/data1.txt", "r", encoding="utf-8")  

while True:
    inStr = inFp.readline()
    if inStr == "" :
        break
    print(inStr, end = "")

inFp.close()

 

 

selfstudy11-1.py

inFp = None
inStr = ""
line_number = 1

inFp = open("ch11/data1.txt", "r", encoding="utf-8")

while True:
    inStr = inFp.readline()
    if inStr == "":
        break
    print("%d %s" % (line_number, inStr), end="")
    line_number += 1

inFp.close()

 

 

Code11-03.py

inFp = None
inStr = ""

inFp = open("ch11/data1.txt", "r", encoding="utf-8")  

inList = inFp.readlines()
print(inList)

inFp.close()

-readlines():통째로 읽어서 저장

 

 

Code11-04.py

inFp = None
inList, inStr = [],""

inFp = open("ch11/data1.txt", "r", encoding="utf-8")  

inList = inFp.readlines()
for inStr in inList:
    print(inStr, end= "")

inFp.close()

 

 

selfstudy11-2.py

inFp = None
inList, inStr = [], ""

inFp = open("ch11/data1.txt", "r", encoding="utf-8")

inList = inFp.readlines()
for line_number, inStr in enumerate(inList, start=1):
    print("%d %s" % (line_number, inStr), end="")

inFp.close()

 

 

Code11-05.py

inFp = None
fName, inList, inStr = "", [],""

fName = input("파일명을 입력하세요 : ")
inFp = open(fName, "r", encoding="utf-8")  

inList = inFp.readlines()
for inStr in inList:
    print(inStr, end= "")

inFp.close()

 

Code11-06.py

import os

inFp = None
fName, inList, inStr = "", [], ""

fName = input("파일명을 입력하세요: ")

if os.path.exists(fName):  # 파일 존재 여부 확인
    inFp = open(fName, "r")  # 파일 열기

    inList = inFp.readlines()  # 파일 내용 읽기
    for inStr in inList:  # 읽은 내용 출력
        print(inStr, end='')
    
    inFp.close()  # 파일 닫기
else:
    print(f"{fName} 파일이 없습니다.")

-파일이 없는 경우는 오류 발생하지 않기 위해 os.path.sxists(파일명) 형식을 사용

 

 

파일을 이용한 출력

data2.txt

야야야ㅑ
하하하
마마마

 

 

Code11-07.py

outFp= None
outStr= None

outFp = open("ch11/data2.txt", 'w',encoding="utf-8") #w는 덮어쓰기

while True:
    outStr = input("내용 입력 : ")
    if outStr != "" :
        outFp.writelines(outStr+ "\n")
    else:
        break

outFp.close()
print("--- 정상적으로 파일에 씀 ---")

-파일 내용을 쓸때는 write() / witelines()함수 사용

 

selfstudy11-3.py

outFp = None
outStr = None

outFname = input("저장할 파일명을 입력하세요: ")
outFp = open(outFname, 'w', encoding="utf-8")  # 'w'는 덮어쓰기

while True:
    outStr = input("내용 입력 : ")
    if outStr != "":
        outFp.writelines(outStr + "\n")
    else:
        break

outFp.close()
print("--- 정상적으로 파일에 씀 ---")

 

 

복사

Code11-08.py

inFp, outFp = None, None
inStr = ""

inFp = open("C:/Windows/win.ini", "r") 
outFp = open("C:/Temp/data3.txt", "w") 

inList = inFp.readlines()  
for inStr in inList:
    outFp.writelines(inStr)  

inFp.close()
outFp.close()
print("-- 파일이 정상적으로 복사되었습니다. --")

 

 

selfstudy11-4.py

inFp, outFp = None, None
inStr = ""

inFname = input("소스 파일명을 입력하세요: ") 
outFname = input("타깃 파일명을 입력하세요: ") 

inFp = open(inFname, "r") 
outFp = open(outFname, "w") 

inList = inFp.readlines() 
for inStr in inList:
    outFp.writelines(inStr)  

inFp.close()  
outFp.close()  
print(f"--- {inFname} 파일이 {outFname} 파일로 복사되었음 ---")

 

 

Code11-09.py

#변수 선언 부분
inFp, outFp = None, None
inStr, outStr = '', ''
i =0
secu = 0 

#메인코드 부분
secuYN = input("1. 암호화 2. 암호 해석 중 선택 : ")
inFname = input("입력 파일명을 입력하세요: ")
outFname = input("출력 파일명을 입력하세요: ")

if secuYN == "1":
    secu = 100  # 암호화
elif secuYN == "2":
    secu = -100  # 복호화

inFp = open(inFname, 'r', encoding='utf-8')
outFp = open(outFname, 'w', encoding='utf-8')

while True:
    inStr = inFp.readline()  # 한 줄씩 읽기
    if not inStr:
        break  # 더 이상 읽을 내용이 없으면 종료
    
    outStr = ''  # 출력 문자열 초기화
    for i in range(len(inStr)):
        ch = inStr[i]
        chNum = ord(ch)  # 문자 -> 숫자 변환
        chNum = chNum + secu  # 암호화/복호화
        ch2 = chr(chNum)  # 숫자 -> 문자 변환
        outStr = outStr + ch2  # 결과 문자열에 추가
    
    outFp.write(outStr)  # 출력 파일에 기록

outFp.close()
inFp.close()
print('%s -> %s 변환 완료' % (inFname, outFname))

-ord():문자->숫자

-chr():숫자->문자

 

 

 

이진파일 입출력

이진파일은 텍스트 파일을 제외 한 나머지 파일(비트 단위로 의미가 있는 파일)

 

Code11-10.py

inFp, outFp = None, None
inStr = ""

inFp = open("C:/Windows/notepad.exe", "rb")
outFp = open("C:/Temp/notepad.exe", "wb")

while True:
    inStr = inFp.read(1)
    if not inStr:
        break
    outFp.write(inStr)

inFp.close()
outFp.close()
print("--- 이진 파일이 정상적으로 복사되었음 ---")

-이진파일 복사

-"rb"/"wb"

 

 

Code11-11.py

from tkinter import *

# 변수 선언 부분
window = None
canvas = None
XSIZE, YSIZE = 256, 256

# 메인 코드 부분
window = Tk()  # 창 생성
canvas = Canvas(window, height=XSIZE, width=YSIZE)  # 캔버스 생성

canvas.pack()  # pack() 메소드 호출 오류 수정
window.mainloop()  # mainloop() 메소드 호출 오류 수정

 

 

Code11-12.py

from tkinter import *

# 함수 선언 부분
def loadImage(fname):
    global inImage, XSIZE, YSIZE
    fp = open(fname, 'rb')  # 파일을 이진 모드로 열기

    for i in range(0, XSIZE):
        tmpList = []  
        for k in range(0, YSIZE):
            data = int(ord(fp.read(1))) 
            tmpList.append(data)  
        inImage.append(tmpList)  

    fp.close() 

def displayImage(image):
    global XSIZE, YSIZE
    rgbString = ""
    for i in range(0, XSIZE):
        tmpString = ""
        for k in range(0, YSIZE):
            data = image[i][k]  # 
            tmpString += "#%02x%02x%02x " % (data, data, data)  
        rgbString += "{" + tmpString + "} "
    paper.put(rgbString) 

# 전역 변수 선언 부분
window = None
canvas = None
XSIZE, YSIZE = 256, 256
inImage = []  

# 메인 코드 부분
window = Tk()
window.title("흑백 사진 보기")
canvas = Canvas(window, height=XSIZE, width=YSIZE)
paper = PhotoImage(width=XSIZE, height=YSIZE)
canvas.create_image((XSIZE / 2, YSIZE / 2), image=paper, state="normal")

# 파일 --> 메모리
filename = 'ch11/gif/tree.raw'
loadImage(filename)

# 메모리 --> 화면
displayImage(inImage)

canvas.pack()
window.mainloop()

 

 

예외처리

Code11-13.py

myStr = "파이썬은 재미 있어요. 파이썬만 매일매일 공부하고 싶어요. ^^"
strPosList = []
index = 0

while True:
    index = myStr.index("파이썬", index)
    strPosList.append(index)
    index = index + 1

print("파이썬 글자 위치 -->", strPosList) #실행될 수가 없기에(무한) 희미하게 보인다.

 

 

Code11-14.py

myStr = "파이썬은 재미 있어요. 파이썬만 매일매일 공부하고 싶어요. ^^"
strPosList = []
index = 0

while True:
    try:
        index = myStr.index("파이썬", index)
        strPosList.append(index)
        index = index + 1
    except :
        break

print("파이썬 글자 위치 -->", strPosList)

 

 

Code11-15.py

num1 = input("숫자1 --> ")
num2 = input("숫자2 --> ")

try :
    num1 = int(num1)
    num2 = int(num2)
    while True :
        res = num1/num2

except ValueError:
    print("문자열은 숫자로 변환할 수 없습니다.")

except ZeroDivisionError :
    print("0으로 나눌 수 없습니다")

except KeyboardInterrupt :
    print("Ctrl+C를 눌렀군요.")

 

 

 

Code11-16.py

num1 = input("숫자1 --> ")
num2 = input("숫자2 --> ")

try :
    num1 = int(num1)
    num2 = int(num2)

except :
    print("오류가 발생했습니다.")

else :
    print(num1, "/", num2, "=", num1/num2)

finally :
    print("이 부분은 무조건 나옵니다.")

-try문에서 오류가 발생하면 except문 실행되며, 오류가 발생하지 않으면 else 문이 실행이된다. finally문은 오류가 발생하든 그렇지 않든 무조건 실행된다.

 

selfstudy11-5.py

from tkinter import *
from tkinter import filedialog, messagebox

# 함수 선언 부분
def loadImage(fname):
    global inImage, XSIZE, YSIZE
    try:
        # 파일을 이진 모드로 열기
        with open(fname, 'rb') as fp:
            for i in range(0, XSIZE):
                tmpList = []  
                for k in range(0, YSIZE):
                    data = int(ord(fp.read(1))) 
                    tmpList.append(data)  
                inImage.append(tmpList)
    except Exception as e:
        messagebox.showerror("오류", f"처리에 실패했습니다: {e}")
        return False
    return True

def displayImage(image):
    global XSIZE, YSIZE
    rgbString = ""
    for i in range(0, XSIZE):
        tmpString = ""
        for k in range(0, YSIZE):
            data = image[i][k]
            tmpString += "#%02x%02x%02x " % (data, data, data)  
        rgbString += "{" + tmpString + "} "
    paper.put(rgbString)

# 전역 변수 선언 부분
window = None
canvas = None
XSIZE, YSIZE = 256, 256
inImage = []

# 메인 코드 부분
window = Tk()
window.title("흑백 사진 보기")
canvas = Canvas(window, height=XSIZE, width=YSIZE)
paper = PhotoImage(width=XSIZE, height=YSIZE)
canvas.create_image((XSIZE / 2, YSIZE / 2), image=paper, state="normal")

# 파일 선택 대화상자 띄우기
filename = filedialog.askopenfilename(title="이미지 파일 선택", filetypes=[("Raw files", "*.raw"), ("All files", "*.*")])

if filename:
    # 파일 로딩 시도
    if loadImage(filename):
        # 성공적으로 이미지 로드된 경우
        displayImage(inImage)
        messagebox.showinfo("성공", f"{filename} 파일이 정상적으로 처리되었습니다.")
else:
    # 파일 선택이 없을 경우
    messagebox.showwarning("경고", "파일이 선택되지 않았습니다.")

# 종료 메시지 출력
messagebox.showinfo("종료", "수고하셨습니다.")

# 화면에 표시
canvas.pack()
window.mainloop()

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

데이터베이스  (1) 2024.12.05
객체지향 프로그래밍  (1) 2024.12.05
윈도 프로그래밍  (2) 2024.12.05
함수와 모듈  (0) 2024.12.05
문자열  (3) 2024.10.24

위젯은 위도창에 나올 수 있는 문자, 버튼, 체크박스, 라디오 버튼 등을 의미한다.

 

필수

Code10-01.py

from tkinter import *

window = Tk()

##이 부분에서 화면을 구성하고 처리##

window.mainloop() ##필수

기본적인 윈도창의 구성이다.

 

-tkinter는 gui 관련 보듈을 제공해주는 표준 위도 라이브러리이다.

-window = tk()르 통해 윈도창이 화면에 출련된다.

-window.mainloop()는 다양한 이벤트를 처리하는데 필요

 

 

Code10-02.py

from tkinter import *

window = Tk()
window.title("윈도우 연습")
window.geometry("400x100")
window.resizable(width = False, height = False) #크기 변동x

##이 부분에서 화면을 구성하고 처리##

window.mainloop() ##필수

 

레이블

Code10-03.py

from tkinter import *
window = Tk()

label1 = Label(window, text = "COOKBOOK~~Pytthon을")
label2 = Label(window, text = "열심히", font=("궁서체", 30), fg = "blue") 
label3 = Label(window, text = "공부 중입니다.", bg = "magenta", width = 20, height=5, anchor = SE) 


label1.pack()
label2.pack()
label3.pack()

window.mainloop() ##필수

-레이블 =문자를 표현하는 위젯

-Label(부모윈도, 옵션...)

-레이블 같은 위젯은 .pack()함수를 호출해야한다.

-anchor는 위젯의 위치

 

Code10-04.py

from tkinter import *
window = Tk()

photo = PhotoImage(file= "C:/tukdata/ch10/image/GIF/dog.gif")
label1 = Label(window, image = photo)

label1.pack()

window.mainloop() ##필수

-글자 대신 이미지가 들어갔다.

 

selfstudy10-4.py

from tkinter import *
window = Tk()

# 첫 번째 이미지
photo1 = PhotoImage(file="C:/tukdata/ch10/image/GIF/dog.gif")
label1 = Label(window, image=photo1)
label1.pack(side=LEFT)

# 두 번째 이미지
photo2 = PhotoImage(file="C:/tukdata/ch10/image/GIF/dog2.gif") 
label2 = Label(window, image=photo2)
label2.pack(side=LEFT)

window.mainloop()

 

 

버튼

Code10-05.py

from tkinter import *
window = Tk()

button1 = Button(window, text = "파이썬 종료", fg = "red", command = quit)

button1.pack()

window.mainloop() ##필수

-마우스 버튼을 누르면 효과가 실행되는 위젯

-command 옵션은 버튼을 눌렀을때 지정한 작업을 처리할 수 있다.

 

 

Code10-06.py

from tkinter import *
from tkinter import messagebox

##함수 선언 부분##
def myFunc() :
    messagebox.showinfo("강아지 버튼", "강아지가 귀엽죠? ^^")

##메인코드 부분##
window = Tk()

photo = PhotoImage(file= "C:/tukdata/ch10/image/GIF/dog2.gif")
button1 = Button(window, image = photo, command = myFunc)


button1.pack()

window.mainloop() ##필수

 

 

체크버튼

Code10-07.py

from tkinter import *
from tkinter import messagebox
window = Tk()

##함수 선언 부분##
def myFunc() :
    if chk.get() == 0 :
        messagebox.showinfo("", "체크버튼이 꺼졌어요.")
    else :
        messagebox.showinfo("", "체크버튼이 켜졌어요.")

##메인코드 부분##
chk = IntVar()
cb1 = Checkbutton(window, text = "클릭하세요", variable = chk ,command = myFunc)

cb1.pack()

window.mainloop() ##필수

-intvar함수는 정수형 타입의 변수 생성

-체크버튼을 키면 chk 1대입 끄면 0 대입

 

라디오버튼

Code10-08.py

from tkinter import *
window = Tk()

##함수 선언 부분##
def myFunc() :
    if var.get() == 1 :
        label1.configure(text = "파이썬")
    elif var.get() ==2 :
        label1.configure(text = "C++")
    else :
        label1.configure(text = "java")

##메인코드 부분##
var = IntVar()
rb1 = Radiobutton(window, text = "파이썬", variable = var, value=1, command = myFunc)
rb2 = Radiobutton(window, text = "C++", variable = var, value=2, command = myFunc)
rb3 = Radiobutton(window, text = "java", variable = var, value=3, command = myFunc)

label1 = Label(window, text = "선택한 언어 : ", fg = "red")

rb1.pack()
rb2.pack()
rb3.pack()
label1.pack()

window.mainloop() ##필수

 

정렬

Code10-09.py

from tkinter import *
window = Tk()

button1 = Button(window, text = "버튼1")
button2 = Button(window, text = "버튼2")
button3 = Button(window, text = "버튼3")

button1.pack(side=LEFT)
button2.pack(side=LEFT)
button3.pack(side=LEFT)

window.mainloop() ##필수

-pack() 함수 옵션에서 side = 사용하면 된다.

 

Code10-10.py

from tkinter import *
window = Tk()

btnList = [None]*3

for i in range(0, 3) :
    btnList[i] = Button(window, text = "버튼" + str(i+1))

for btn in btnList :
    # btn.pack(side = RIGHT)
    btn.pack(side = RIGHT, fill =X, ipadx = 10, ipady = 10, padx = 10, pady = 10)

window.mainloop() ##필수

 

Code10-11.py

from tkinter import *

##전역 변수 선언 부분##
btnList = [None]*9
fnameList = ["honeycomb.gif", "icecream.gif", "jellybean.gif", "kitkat.gif", "lollipop.gif", "marshmallow.gif", "nougat.gif", "oreo.gif", "pie.gif"]
photoList = [None]*9
i,k=0,0
xPos,yPos = 0,0
num = 0

##메인 코드 부분##
window = Tk()
window.geometry("210x210")

for i in range(0, 9) :
    photoList[i] = PhotoImage(file = "ch10/image/GIF/" + fnameList[i])
    btnList[i] = Button(window, image=photoList[i])

for i in range(0, 3) :
    for k in range(0,3) :
        btnList[num].place(x = xPos, y = yPos)
        num += 1
        xPos += 70
    xPos =0
    yPos += 70

window.mainloop() ##필수

 

-수평 side = left or right

-수직 = top or bottom

-폭조정 fill = x

-여백 = padx= 10 or pady = 10

-내부여백 ipadx = 10

고정위치 -> .place() 함수 사용

 

 

selfstudy10-2.py

from tkinter import *
import random  # 랜덤 모듈 임포트

# 전역 변수 선언 부분
btnList = [None] * 9
fnameList = ["honeycomb.gif", "icecream.gif", "jellybean.gif", "kitkat.gif", "lollipop.gif", 
             "marshmallow.gif", "nougat.gif", "oreo.gif", "pie.gif"]
photoList = [None] * 9
i, k = 0, 0
xPos, yPos = 0, 0
num = 0

# 리스트를 랜덤하게 섞음
random.shuffle(fnameList)

# 메인 코드 부분
window = Tk()
window.geometry("210x210")

for i in range(0, 9):
    photoList[i] = PhotoImage(file="ch10/image/GIF/" + fnameList[i])
    btnList[i] = Button(window, image=photoList[i])

for i in range(0, 3):
    for k in range(0, 3):
        btnList[num].place(x=xPos, y=yPos)
        num += 1
        xPos += 70
    xPos = 0
    yPos += 70

window.mainloop()

 

Code10-12.py

from tkinter import *
from time import *

# 전역 변수 선언 부분
frameList = ["jeju1.gif", "jeju2.gif", "jeju3.gif", "jeju4.gif", "jeju5.gif", "jeju6.gif", "jeju7.gif", "jeju8.gif", "jeju9.gif"]
photoList = [None] * 9
num = 0

# 함수 선언 부분
def clickNext():
    global num
    num += 1
    if num > 8:
        num = 0
    photo = PhotoImage(file="ch10/image/GIF/" + frameList[num])
    pLabel.configure(image=photo)
    pLabel.image = photo

def clickPrev():
    global num
    num -= 1
    if num < 0:
        num = 8
    photo = PhotoImage(file="ch10/image/GIF/" + frameList[num])
    pLabel.configure(image=photo)
    pLabel.image = photo

# 메인 코드 부분
window = Tk()
window.geometry("700x500")
window.title("사진 앨범 보기")

btnPrev = Button(window, text="« 이전", command=clickPrev)
btnNext = Button(window, text="다음 »", command=clickNext)

photo = PhotoImage(file="ch10/image/GIF/" + frameList[0])
pLabel = Label(window, image=photo)

btnPrev.place(x=250, y=10)
btnNext.place(x=400, y=10)
pLabel.place(x=15, y=50)

window.mainloop()

 

selfstudy10-3.py

from tkinter import *
from time import *

# 전역 변수 선언 부분
frameList = ["jeju1.gif", "jeju2.gif", "jeju3.gif", "jeju4.gif", "jeju5.gif", 
             "jeju6.gif", "jeju7.gif", "jeju8.gif", "jeju9.gif"]
photoList = [None] * 9
num = 0

# 함수 선언 부분
def clickNext():
    global num
    num += 1
    if num > 8:
        num = 0
    updateImage()

def clickPrev():
    global num
    num -= 1
    if num < 0:
        num = 8
    updateImage()

def updateImage():
    # 이미지 업데이트
    photo = PhotoImage(file="ch10/image/GIF/" + frameList[num])
    pLabel.configure(image=photo)
    pLabel.image = photo
    # 파일명 업데이트
    fileNameLabel.config(text=frameList[num])

# 메인 코드 부분
window = Tk()
window.geometry("700x500")
window.title("사진 앨범 보기")

btnPrev = Button(window, text="« 이전", command=clickPrev)
btnNext = Button(window, text="다음 »", command=clickNext)

photo = PhotoImage(file="ch10/image/GIF/" + frameList[0])
pLabel = Label(window, image=photo)

# 파일명 표시용 라벨 추가
fileNameLabel = Label(window, text=frameList[0], font=("Arial", 12))
fileNameLabel.place(x=320, y=15)

btnPrev.place(x=250, y=10)
btnNext.place(x=400, y=10)
pLabel.place(x=15, y=50)

window.mainloop()

 

 

 

마우스 이벤트 처리

def 이벤트처리함수(event):
	#이 부분에 마우스 이벤트가 발생할 때 작동할 내용 작성
    
위젯.bind("마우스이벤트", 이벤트처리함수)

 

Code10-13.py

from tkinter import *
from tkinter import messagebox

#함수 선언 부분
def clickLeft(event):
    messagebox.showinfo("마우스", "마우스 왼쪽 버튼이 클릭됨")

##이 부분에서 화면을 구성하고 처리##
window = Tk()

window.bind("<Button-1>", clickLeft)

window.mainloop() ##필수

 

 

Code10-14.py

from tkinter import *
from tkinter import messagebox

#함수 선언 부분
def clickImage(event):
    messagebox.showinfo("마우스", "토끼에서 마우스가 클릭됨")

##이 부분에서 화면을 구성하고 처리##
window = Tk()
window.geometry("400x400")

photo = PhotoImage(file = "ch10/image/GIF/rabbit.gif")
label1 = Label(window, image = photo)


label1.bind("<Button>", clickImage)

label1.pack(expand = True, anchor = CENTER)

window.mainloop() ##필수

-label.bind로 이미지를 클릭할 때만 이벤트 처리된다(window.bind면 위젯 자체)

 

 

Code10-15.py

from tkinter import *

#함수 선언 부분
def clickMouse(event):
    txt = ""
    if event.num == 1:
        txt += "마우스 왼쪽 버튼이 ("
    elif event.num == 3:
        txt += "마우스 오른쪽 버튼이 ("

    txt += str(event.y) + "," + str(event.x) + ")에서 클릭됨"
    label1.configure(text = txt)

#메인 코드 부분##
window = Tk()
window.geometry("400x400")

label1 = Label(window, text= "이곳이 바뀜")

window.bind("<Button>", clickMouse)

label1.pack(expand = True, anchor = CENTER)
window.mainloop() ##필수

 

 

 

키보드 이벤트 기본처리

Code10-16.py

from tkinter import *
from tkinter import messagebox

#함수 선언 부분
def keyEvent(event):
    messagebox.showinfo("키보드 이벤트", "눌린 키 : " + chr(event.keycode))

#메인 코드 부분##
window = Tk()

window.bind("<Key>", keyEvent)

window.mainloop() ##필수

-.event.keycode에 눌려진 키의 숫자값이 chr()함수를 사용해서 문자로 변환시켰다

 

 

 

selfstudy10-4.py

from tkinter import *
from tkinter import messagebox

# 함수 선언 부분
def keyEvent(event):
    # Shift 키와 화살표 키 조합에 따라 메시지 출력
    if event.keycode == 37:
        messagebox.showinfo("키보드 이벤트", "눌린 키 : Shift + 왼쪽 화살표")
    elif event.keycode == 38:
        messagebox.showinfo("키보드 이벤트", "눌린 키 : Shift + 위쪽 화살표")
    elif event.keycode == 39:
        messagebox.showinfo("키보드 이벤트", "눌린 키 : Shift + 오른쪽 화살표")
    elif event.keycode == 40:
        messagebox.showinfo("키보드 이벤트", "눌린 키 : Shift + 아래쪽 화살표")

# 메인 코드 부분
window = Tk()
# Shift와 각 화살표 키 조합에 대해 이벤트 바인딩
window.bind("<Shift-Left>", keyEvent)
window.bind("<Shift-Up>", keyEvent)
window.bind("<Shift-Right>", keyEvent)
window.bind("<Shift-Down>", keyEvent)

window.mainloop()

 

 

 

메뉴의 생성

메뉴자체 = Menu(부모윈도)
부모윈도.config(menu = 메뉴자체)

상위메뉴 = Menu(메뉴자체)
메뉴자체.add_cascade(label = "상위메뉴텍스트", menu = 상위메뉴)
상위메뉴.add_command(label = "하위메뉴1", command = 함수1)
상위메뉴.add_command(label = "하위메뉴2", command = 함수2)

 

Code10-17.py

from tkinter import *

window = Tk()

mainMenu = Menu(window) #메뉴자체 변수
window.config(menu = mainMenu) #생성한 메뉴 자체를 윈도창 메뉴로 지정

fileMenu = Menu(mainMenu) #상위 메뉴인 파일을 생성하고 메뉴 자체에 부착
mainMenu.add_cascade(label="파일", menu = fileMenu)
fileMenu.add_command(label="열기")#하위메뉴
fileMenu.add_separator()
fileMenu.add_command(label="종료")

window.mainloop() ##필수

 

Code10-18.py

from tkinter import *
from tkinter import messagebox

#함수 선언 부분
def func_open():
    messagebox.showinfo("메뉴선택", "열기 메뉴를 선택함")

def func_exit():
    window.quit()
    window.destroy()

#메인 코드 부분##
window = Tk()

mainMenu = Menu(window)
window.config(menu = mainMenu)

fileMenu = Menu(mainMenu)
mainMenu.add_cascade(label="파일", menu = fileMenu)
fileMenu.add_command(label="열기", command = func_open)
fileMenu.add_separator()
fileMenu.add_command(label="종료", command= func_exit)

window.mainloop() ##필수

-add_command()함수: 무언가 작동

 

 

대화상자의 생성과 사용

Code10-19.py

from tkinter import *
from tkinter.simpledialog import*

#함수 선언 부분
window = Tk()
window.geometry("400x100")

label1 = Label(window, text = "입력된 값")
label1.pack()

value = askinteger("확대배수", "주사위 숫자(1~6)을 입력하세요", minvalue = 1, maxvalue = 6)

label1.configure(text = str(value))
window.mainloop() ##필수

-tkinter.simpledialog모듈 임포트

-askinteger("제목", "내용", 옵션)

 

숫자나 문자를 입력받으려면 tkinter.simpledialog 모듈을 입포트한 후 askinteger(), askfloa(), askstring()함수 등을 사용한다.

 

 

Code10-20.py

from tkinter import *
from tkinter.filedialog import*

#함수 선언 부분
window = Tk()
window.geometry("400x100")

label1 = Label(window, text = "선택된 파일 이름")
label1.pack()

filename = askopenfilename(parent=window, filetypes=(("GIF 파일", "*.gif"), ("모든 파일", "*.*")))

label1.configure(text = str(filename))

window.mainloop() ##필수

-tkinter.filedialog 임포트

-askopenfilename()함수

 

파일을 열거나 저장할 때 나타나는 대화상자는 tkinter.filedilog 모듈을 임포트한 후 askopenfilename() 또는 asksaveasfile()함수를 사용한다.

 

 

Code10-21.py

from tkinter import *
from tkinter.filedialog import*

#함수 선언 부분
window = Tk()
window.geometry("400x100")

label1 = Label(window, text = "선택된 파일 이름")
label1.pack()

saveFp = asksaveasfile(parent=window, mode= "w", defaultextension = ".jpg", filetypes = (("jpg 파일", "*.jpg;*.jpeg"), ("모든 파일", "*.*")))

label1.configure(text = saveFp)

saveFp.close() ##필수

-asksaveasfile()->다른 이름으로 저장

-mode "W"는 쓰기

 

 

 

 

Code10-22.py

from tkinter import *
from tkinter.filedialog import *

# 함수 선언 부분
def func_open():
    filename = askopenfilename(parent=window, filetypes=(("GIF 파일", "*.gif"), ("모든 파일", "*.*")))
    photo = PhotoImage(file=filename)
    pLabel.configure(image=photo)
    pLabel.image = photo

def func_exit():
    window.quit()
    window.destroy()

# 메인 코드 부분
window = Tk()
window.geometry("500x500")
window.title("명화 감상하기")

photo = PhotoImage()
pLabel = Label(window, image=photo)
pLabel.pack(expand=1, anchor=CENTER)

mainMenu = Menu(window)
window.config(menu=mainMenu)
fileMenu = Menu(mainMenu)
mainMenu.add_cascade(label="파일", menu=fileMenu)
fileMenu.add_command(label="파일 열기", command=func_open)
fileMenu.add_separator()
fileMenu.add_command(label="프로그램 종료", command=func_exit)

window.mainloop()

 

selfstudy10-5.py

from tkinter import *
from tkinter.filedialog import *

# 함수 선언 부분
def func_open():
    filename = askopenfilename(parent=window, filetypes=(("GIF 파일", "*.gif"), ("모든 파일", "*.*")))
    if filename:
        global photo  
        photo = PhotoImage(file=filename)
        grayscale_image(photo)  
        pLabel.configure(image=photo)
        pLabel.image = photo

def grayscale_image(photo):
    width = photo.width()
    height = photo.height()

    for x in range(width):
        for y in range(height):
            r, g, b = photo.get(x, y) 
            gray = (r + g + b) // 3
            # 픽셀을 회색으로 설정
            photo.put("#%02x%02x%02x" % (gray, gray, gray), (x, y))

def func_exit():
    window.quit()
    window.destroy()

# 메인 코드 부분
window = Tk()
window.geometry("500x500")
window.title("명화 감상하기")

photo = PhotoImage()  
pLabel = Label(window, image=photo)
pLabel.pack(expand=1, anchor=CENTER)

mainMenu = Menu(window)
window.config(menu=mainMenu)
fileMenu = Menu(mainMenu)
mainMenu.add_cascade(label="파일", menu=fileMenu)
fileMenu.add_command(label="파일 열기", command=func_open)
fileMenu.add_separator()
fileMenu.add_command(label="프로그램 종료", command=func_exit)

window.mainloop()

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

객체지향 프로그래밍  (1) 2024.12.05
파일 입출력  (0) 2024.12.05
함수와 모듈  (0) 2024.12.05
문자열  (3) 2024.10.24
리스트, 튜플, 딕셔너리  (0) 2024.10.24

함수 = 자판기!

무엇인가 매개변수를 넣으면 반환값을 돌려준다


code09-01.py

coffee = 0

coffee = int(input("어떤 커피 드릴까요?(1:보통, 2:설탕, 3:블랙)"))

print()
print("#1. 뜨거운 물을 준비한다.")
print("#2. 종이컵을 준비한다.")

if coffee == 1:
    print("#3. 보통커피를 탄다.")
elif coffee == 2:
    print("#3. 설탕커피를 탄다.")
elif coffee == 3:
    print("#3. 블랙커피를 탄다.")
else :
    print("#3. 아무거나 탄다.\n")

print("#4. 물을 붓는다.")
print("#5. 스푼으로 젓는다.")
print()
print("손님~ 커피 여기 있습니다.")

 
code09-02.py

##전역 변수 선언 부분
coffee = 0

## 함수 선언 부분##
def coffee_machine(button):
    print()
    print("#1. (자동으로) 뜨거운 물을 준비한다.")
    print("#2. (자동으로) 종이컵을 준비한다.")

    if coffee == 1:
        print("#3. (자동으로) 보통커피를 탄다.")
    elif coffee == 2:
        print("#3. (자동으로) 설탕커피를 탄다.")
    elif coffee == 3:
        print("#3. (자동으로) 블랙커피를 탄다.")
    else :
        print("#3. (자동으로) 아무거나 탄다.\n")

    print("#4. (자동으로) 물을 붓는다.")
    print("#5. (자동으로) 스푼으로 젓는다.")
    print()

##메인 코드 부분##
coffee = int(input("어떤 커피 드릴까요?(1:보통, 2:설탕, 3:블랙)"))
coffee_machine(coffee)
print("손님~ 커피 여기 있습니다.")

 
code09-03.py

##전역 변수 선언 부분
coffee = 0

## 함수 선언 부분##
def coffee_machine(button):
    print()
    print("#1. (자동으로) 뜨거운 물을 준비한다.")
    print("#2. (자동으로) 종이컵을 준비한다.")

    if coffee == 1:
        print("#3. (자동으로) 보통커피를 탄다.")
    elif coffee == 2:
        print("#3. (자동으로) 설탕커피를 탄다.")
    elif coffee == 3:
        print("#3. (자동으로) 블랙커피를 탄다.")
    else :
        print("#3. (자동으로) 아무거나 탄다.\n")

    print("#4. (자동으로) 물을 붓는다.")
    print("#5. (자동으로) 스푼으로 젓는다.")
    print()

##메인 코드 부분##
coffee = int(input("A손님, 어떤 커피 드릴까요?(1:보통, 2:설탕, 3:블랙)"))
coffee_machine(coffee)
print("A손님~ 커피 여기 있습니다.")

coffee = int(input("B손님, 어떤 커피 드릴까요?(1:보통, 2:설탕, 3:블랙)"))
coffee_machine(coffee)
print("B손님~ 커피 여기 있습니다.")

coffee = int(input("C손님, 어떤 커피 드릴까요?(1:보통, 2:설탕, 3:블랙)"))
coffee_machine(coffee)
print("C손님~ 커피 여기 있습니다.")

 
selfstudy9-1.py

##전역 변수 선언 부분
coffee = 0

## 함수 선언 부분##
def coffee_machine(button):
    print()
    print("#1. (자동으로) 뜨거운 물을 준비한다.")
    print("#2. (자동으로) 종이컵을 준비한다.")

    if coffee == 1:
        print("#3. (자동으로) 아메리카노를 탄다.")
    elif coffee == 2:
        print("#3. (자동으로) 카페라떼를 탄다.")
    elif coffee == 3:
        print("#3. (자동으로) 카푸치노를 탄다.")
    elif coffee == 4:
        print("#3. (자동으로) 에스프레소를 탄다.")
    else :
        print("#3. (자동으로) 아무거나 탄다.\n")

    print("#4. (자동으로) 물을 붓는다.")
    print("#5. (자동으로) 스푼으로 젓는다.")
    print()

##메인 코드 부분##
coffee = int(input("로제씨, 어떤 커피 드릴까요?(1:아메리카노, 2:카페라떼, 3:카푸치노, 4:에스프레소)"))
coffee_machine(coffee)
print("로제씨~ 커피 여기 있습니다.")

coffee = int(input("리사, 어떤 커피 드릴까요?(1:보통, 2:설탕, 3:블랙)"))
coffee_machine(coffee)
print("리사씨~ 커피 여기 있습니다.")

coffee = int(input("지수씨, 어떤 커피 드릴까요?(1:보통, 2:설탕, 3:블랙)"))
coffee_machine(coffee)
print("지수씨~ 커피 여기 있습니다.")

coffee = int(input("제니씨, 어떤 커피 드릴까요?(1:보통, 2:설탕, 3:블랙)"))
coffee_machine(coffee)
print("제니씨~ 커피 여기 있습니다.")



함수의 형식과 활용
반복적으로 코딩해야 할 내용을 함수로 만들면 필요할때마다 사용 가능하고 동일한 동작을 계속 사용하므로 내부 내용이 바뀔 일이 없다.
 
code09-04.py

## 함수 선언 부분 ##
def plus(v1, v2):
    result = 0
    result =v1 + v2
    return result

## 전역 변수 선언 부분 ##
hap = 0

##메인 코드 부분 ##
hap = plus(100, 200)
print("100과 200의 plus() 함수 결과는 %d" %hap)

*def 함수 선언 부분은 바로 실행되지 않는다 

code09-05.py

## 함수 선언 부분 ##
def cal(v1, v2, op):
    result = 0
    
    if op =="+" :
        result = v1 + v2
    elif op == "-" :
        result = v1 - v2
    elif op == "*" :
        result = v1 * v2
    elif op == "/" :
        result = v1 / v2
        
    return result

## 전역 변수 선언 부분 ##
res = 0
var1, var2, oper =0, 0, ""

##메인 코드 부분 ##
oper = input("계산을 입력하세요(+,-,*,/) : ")
var1 = int(input("첫 번째 수를 입력하세요 : "))
var2 = int(input("두 번째 수를 입력하세요 : "))

res = cal(var1, var2, oper)

print("## 계산기 : %d %s %d = %d" %(var1, oper, var2, res))

 
selfstudy9-2.py

## 함수 선언 부분 ##
def cal(v1, v2, op):
    result = 0
    
    if op =="+" :
        result = v1 + v2
    elif op == "-" :
        result = v1 - v2
    elif op == "*" :
        result = v1 * v2
    elif op == "/" :
        result = v1 / v2
    elif op == "**" :
        result = v1 ** v2
        
    return result

## 전역 변수 선언 부분 ##
res = 0
var1, var2, oper =0, 0, ""

##메인 코드 부분 ##
var1 = int(input("첫 번째 수를 입력하세요 : "))
oper = input("계산을 입력하세요(+,-,*,/,**) : ")
var2 = int(input("두 번째 수를 입력하세요 : "))

if var2 == 0:
    print("0으로는 나누면 안 됩니다.ㅠㅠ")

else:
    res = cal(var1, var2, oper)

    print("## 계산기 : %d %s %d = %d" %(var1, oper, var2, res))

 
지역 변수, 전역 변수

지역변수는 함수 내에서만 사용되는 변수
전역 변수는 프로그램 전체에서 사용되는 변수이다
(변수명이 같다면 지역변수가 우선)

code09-06.py

##함수 선언 부분##
def func1():
    a = 10 #지역변수
    print("func1()에서 a값 %d" % a)

def func2():
    print("func2()에서 a값 %d" % a)

##전역변수 선언 부분 
a = 20 #전역변수

##메인코드
func1()
func2()



 
code09-07.py

##함수 선언 부분##
def func1():
    global a # 이 함수 안에서 a는 전역 변수
    a = 10 #지역변수
    print("func1()에서 a값 %d" % a)

def func2():
    print("func2()에서 a값 %d" % a)

##전역변수 선언 부분 
a = 20 #전역변수

##메인코드
func1()
func2()

global 예약어가 사용이 되면 전역변수가 된다.

 

함수의 반환값과 매개변수

함수는 크게 반환값이 있는 함수(ex. return a)vs 반환값이 없는 함수로 나눈다.(return or 없음)

code09-08.py

def func1():
    result = 100
    return result

def func2():
    print("반환값이 없는 함수 실행")

##전역변수 선언 부분 
hap = 0

##메인코드
hap=func1()
print("func1()에서 돌려준 값 ==> %d" %hap)
func2()

*반환값이 없는 함수
-return문이 생략이 되거나 return만 입력
 

code09-09.py

##함수 선언 부분##
def multi(v1, v2):
    retList = []
    res1 = v1 + v2
    res2 = v1 - v2
    retList.append(res1)
    retList.append(res2)
    return retList

##전역변수 선언 부분 
myList = []
hap, sub = 0, 0

##메인코드
myList = multi(100, 200)
hap = myList[0]
sub = myList[1]
print("multi()에서 돌려준 값 ==> %d, %d" % (hap, sub))

*반환값이 여러개인 함수
-2개 이상이 반환값이 될 수 없지만 리스트에 넣은 후 반환하면 ok 

+추가로
def func()
      pass
pass 예약어는 함수를 구현할 대 일단 이름만 만들어 놓고 그 내용은 pass 예약어로 비울 수 있다.




code09-10.py

##함수 선언 부분##
def para2_func(v1, v2):
    result = 0
    result = v1 + v2
    return result

def para3_func(v1, v2, v3):
    result = 0
    result = v1 + v2 + v3
    return result

##전역변수 선언 부분 
hap = 0

##메인코드
hap = para2_func(10, 20)
print("매개변수가 2개인 함수를 호출한 결과 ==> %d" %hap)
hap = para3_func(10, 20, 30)
print("매개변수가 3개인 함수를 호출한 결과 ==> %d" %hap)

 매개변수의 개수를 지정해 전달하는 방법

 
code09-11.py

##함수 선언 부분##
def para_func(v1, v2, v3=0):
    result = 0
    result = v1 + v2 + v3
    return result

##전역변수 선언 부분 
hap = 0

##메인코드
hap = para_func(10, 20)
print("매개변수가 2개인 함수를 호출한 결과 ==> %d" %hap)
hap = para_func(10, 20, 30)
print("매개변수가 3개인 함수를 호출한 결과 ==> %d" %hap)

매개변수에 기본값을 설정해 놓고 전달하는 방법
 

selfstudy9-3.py

##함수 선언 부분##
def para_func(v1, v2, v3=0,v4=0,v5=0,v6=0,v7=0,v8=0,v9=0,v10=0):
    result = 0
    result = v1 + v2 + v3+ v4 + v5 + v6+ v7 + v8 + v9 + v10
    return result

##전역변수 선언 부분 
hap = 0

##메인코드
hap = para_func(10, 20)
print("매개변수가 2개인 함수를 호출한 결과 ==> %d" %hap)
hap = para_func(10, 20, 30)
print("매개변수가 3개인 함수를 호출한 결과 ==> %d" %hap)
hap = para_func(10, 20, 30, 40)
print("매개변수가 4개인 함수를 호출한 결과 ==> %d" %hap)
hap = para_func(10, 20, 30, 40, 50)
print("매개변수가 5개인 함수를 호출한 결과 ==> %d" %hap)
hap = para_func(10, 20, 30, 40, 50, 60)
print("매개변수가 6개인 함수를 호출한 결과 ==> %d" %hap)
hap = para_func(10, 20, 30, 40, 50, 60, 70)
print("매개변수가 7개인 함수를 호출한 결과 ==> %d" %hap)
hap = para_func(10, 20, 30, 40, 50, 60, 70, 80)
print("매개변수가 8개인 함수를 호출한 결과 ==> %d" %hap)
hap = para_func(10, 20, 30, 40, 50, 60, 70, 80, 90)
print("매개변수가 9개인 함수를 호출한 결과 ==> %d" %hap)
hap = para_func(10, 20, 30, 40, 50, 60, 70, 80, 90, 100)
print("매개변수가 10개인 함수를 호출한 결과 ==> %d" %hap)

 
code09-12.py

#함수 선언 부분
def para_func(*para): #*갯수가 정해져있지 않은 매개변수가 튜플 형식으로 넘어와 튜플을 처리하는 방식으로 함수 안에서 사용 가능
    result = 0
    for num in para :
        result = result + num

    return result

##전역변수 선언 부분 
hap = 0

##메인코드
hap = para_func(10, 20)
print("매개변수가 2개인 함수를 호출한 결과 ==> %d" %hap)
hap = para_func(10, 20, 30)
print("매개변수가 3개인 함수를 호출한 결과 ==> %d" %hap)





#딕셔너리
def dic_func(**para): 
    for k in para.keys() :
        print("%s -- > %d명입니다." %(k, para[k]))


dic_func(트와이스 = 9, 소녀시대 = 7, 걸스데이 = 4, 블랙핑크 =4)

 매개변수의 개수를 지정하지 않고 전달하는 방법
-매개변수 앞에*를 붙이면 매개벼누가 튜플 형식으로 넘어와 튜플을 처리하는 방식으로 함수 안에서 사용할 수 있다.
-**를 사용하면 딕셔너리 형식으로 전달->(키=값)형식으로 넣어줘야 함

 
code09-13.py

import random

##함수 선언 부분##
def getNumber():
    return random.randrange(1, 46)

##전역 변수 선언 부분##
lotto = []
num = 0

##메인 코드 부분##
print("** 로또 추첨을 시작합니다. ** \n")

while True:
    num = getNumber()

    if lotto.count(num) == 0:
        lotto.append(num)

    if len(lotto) >=6 :
        break

print("추첨된 로또 번호 ==> ", end = "")
lotto.sort()
for i in range(0,6) :
    print("%d " %lotto[i], end="")

 

모듈

모듈은 함수의 집합
모듈은 표준 모듈, 사용자 모듈, 서드파티모듈이 있다.

표준모듈: 파이썬에서 제공하는모듈
사용자 모듈: 사용자가 만듬
써드 파티 모듈:외부 회사나 단체에서 제공하는 모듈->다양해서 파이썬의 장점

module1.py

##함수 선언 부분##
def func1() :
    print("Module1.py의 func1()이 호출됨.")

def func2() :
    print("Module1.py의 func2()이 호출됨.")

def func3() :
    print("Module1.py의 func3()이 호출됨.")

 
a.py

import Module1

##메인 코드 부분##
Module1.func1()
Module1.func2()
Module1.func3()

 
b.py

from Module1 import func1, func2, func3 #또는 from Module1 import *

#메인 코드 부분##
func1()
func2()
func3()


# def outFunc(v1,v2):
#     def inFunc(num1, num2) :
#         return num1 + num2
#     return inFunc(v1, v2)
# print(outFunc(10, 20))

# hap2 = lambda num1, num2 : num1 + num2
# print(hap2(10, 20))

# hap3 = lambda num1 = 10, num2 = 20 : num1 + num2
# print(hap3())
# print(hap3(100, 200))

# myList = [1,2,3,4,5]
# add10 = lambda num: num + 10
# myList = list(map(add10, myList))
# print(myList)

# myList = list(map(lambda num : num + 10, myList))
# print(myList)

# list1=[1,2,3,4]
# list2=[10, 20, 30, 40]
# hapList = list(map(lambda n1, n2 : n1+n2, list1, list2))
# print(hapList)


# def factorial(num) :
#     if num <=1 :
#         return num
#     else:
#         return num*factorial(num-1)
# print(factorial(4))
# print(factorial(10))

 
myTurtle.py

import random
from tkinter.simpledialog import *

def getString() :
    retStr = ""
    retStr = askstring("문자열 입력", "거북이 쓸 문자열을 입력")
    return retStr

def getRGB():
    r,g,b =0,0,0
    r = random.random()
    g = random.random()
    b = random.random()
    return (r,g,b)

def getXYAS(sw, sh):
    x, y, angle, size = 0,0,0,0
    x = random.randrange( int(-sw/2), int(sw/2))
    y = random.randrange( int(-sh/2), int(sh/2))
    angle = random.randrange(0,360)
    size = random.randrange(10, 50)
    return [x,y,angle, size]

 
 
code09-14.py

from myTurtle import *
import turtle

##전역변수선언부분##
instr = ""
swidth, sheight = 300, 300
tX, tY, tAngle, tSize = [0]*4

#메인코드부분#
turtle.title("거북이 글짜쓰기(모듈버전)")
turtle.shape("Turtle")
turtle.setup(width=swidth + 50, height = sheight + 50)
turtle.screensize(swidth, sheight)
turtle.penup()
turtle.speed(5)

inStr = getString()

for ch in inStr :

    tX, tY, tAngle, tSize = getXYAS(swidth, sheight)
    r,g,b = getRGB()

    turtle.goto(tX, tY)
    turtle.left(tAngle)

    turtle.pencolor((r,g,b))
    turtle.write(ch, font = ("맑은고딕", txtSize, "bold"))

turtle.done

 
패키지

패키지는 여러 모듈을 모아 놓을 것으로 폴더의 형태
from 패키지명.모듈명 import 함수명





내부함수
내부함수는 함수 안에 함수가 있는 형태
def outfunc(v1, v2) :
       def infunc(num1, num2) :
              return num1 + num2
         return infunc(v1,v2)
print(outfunc(10, 20))
결과값 -> 30

람다함수
한줄로 간단하게 함수를 만들어 줌
hap = lambda num1, num2 : num1 + num2
print(hap(10, 20))
결과값->30

map함수
리스트에 함수 수식을 모두 한꺼번에 적용
mpa(함수, 시퀸스(문자열,리스트,딕셔너리))

재귀함수
자신이 자신을 호출
중지하려면
-ctrl + c
-카운트

yield문
return은 결과를 반환하고 함수를 종결하지만 yield문은 함수를 종결하지 않으면서 값을 반환한다.

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

파일 입출력  (0) 2024.12.05
윈도 프로그래밍  (2) 2024.12.05
문자열  (3) 2024.10.24
리스트, 튜플, 딕셔너리  (0) 2024.10.24
반복문  (0) 2024.10.24

가상환경 생성

 

snort 환경을 구성할 Server와, 악성코드 행위 분석용  Client(Victim) 각각 가상환경을 구성하였다.

 

 

네트워크 통신을 원활히 하기 위해 방화벽을 해제하였으며,

 

 

 

ipconfig 명령어로 가상환경의 IP 주소를 확인한 뒤,
ping [IP주소] 명령어로 네트워크 연결을 확인하였다.


Snort 환경 구성 준비물

Snort: 네트워크 패킷 분석 및 침입 탐지 도구

WinPcap: 네트워크 패킷 캡처를 위한 라이브러리 및 드라이버

XAMPP: Apache, MySQL, PHP, Perl 등을 포함한 통합 개발 환경

Base: Snort 이벤트 데이터를 웹 인터페이스로 분석 및 표시하는 도구

ADOdb: Snort 로그 데이터를 MySQL로 저장하고 PHP로 처리하기 위한 라이브러리

Notepad++: Snort 규칙 및 구성 파일을 수정할 수 있는 코드 편집기

* (PHP는 웹사이트를 만들 때 서버에서 작동하는 프로그래밍 언어이다.
주로 데이터베이스와 연동해 동적인 웹 페이지를 생성하는 데 사용된다.)

 


Snort 설치

Snort 2.9.2.3 버전을 설치하였다.(3버전은 리눅스 버전이므로 주의!)

SQL과 연계 설치 여부는 추후 데이터베이스 직접 연결을 위해 "I do not plan to log to database" 옵션을 선택하였다.

설치 완료


WinPcap 설치

최신 버전인 WinPcap 4.1.3을 설치하였다.


XAMPP 설치

MySQL과 호환 가능한 버전으로 설치하였다.(최신 버전 설치 했는데 환경구성에서 호환이 안되는 경우가 생겨서 안전하게 1.7.1버전 사용을 추천!)

XAMPP Control Panel에서 Apache, MySQL 등을 통합 관리할 수 있다.

사용할 모듈들을 체크해서 실행 시켜준다.


Base 설치

Base를 설치 후 C:\xampp\htdocs\base 경로에 압축 해제하여 저장하였다.


ADOdb 설치

ADOdb를 C:\xampp\htdocs\adodb 경로에 압축 해제하여 저장하였다.

(ABODB는 버전인 5.20.12를 사용해야 localhost/base url에서 세팅이 가능하다)


Notepad++ 설치

Snort 규칙 파일 수정 및 구성 파일 편집을 위해 설치하였다.


MySQL 비밀번호 설정

 

1.MySQL 경로로 이동

cd C:\xampp\mysql\bin
 

2.root 사용자로 접속

mysql -u root -p mysql
 

3.비밀번호 설정

update user set password = password('비밀번호') where user = 'root';
 
4.현재 사용중인 MYSQL캐시를 지우고 새로운 설정을 적용
flush privileges;
 

5.MySQL 종료

quit
 

 


MySQL 스키마 생성

 

스키마 파일 복사

C:\snort\schemas의 create_mysql 파일을 C:\xampp\mysql\bin으로 복사하였다.

 

 

 

Snort DB 생성

mysqladmin -u root -p create snort
 

스키마 적용

mysql -D snort -u root -p < create_mysql
 
 
 mysql console 로그인
 mysql -u root -p  입력 후 비밀번호 입력
 
 

snort DB선택

use snort;
 
테이블 확인
show tables;

Base 설정

step0

c:\xampp\htdocs\base\includes 경로에 base_action.inc.php 파일을 notepad++를 열어준다.

 

메일 관련 29번, 30번 라인을 주석 처리하였다.

결과를 메일로 알려주는 29번과 30번 라인을 주석처리하여 비활성화
(받을 메일이 없기 때문에 해당 라인이 활성화되면 오류가 발생)

 

**추가로 localhost\base 들어가면

Deprecated: Function ereg_replace() is deprecated in C:\xampp\htdocs\base\includes\base_state_common.inc.php on line 184

이런 화면이 뜰 수 도 있다.

 

이럴 땐 php 문법이 버전 호환 때문에 생긴거라

base_state_common.inc.php 파일을 notepad++로 들어가서 finally 문법을 catch로 바꿔줘야 한다

예시

수정 전

try {
    $savec = $ADODB_COUNTRECS;
    $ADODB_COUNTRECS = false;

    if ($secs2cache != 0) {
        $rs = $this->CacheExecute($secs2cache, $sql, $inputarr);
    } else {
        $rs = $this->Execute($sql, $inputarr);
    }
} finally {
    $ADODB_COUNTRECS = $savec;
}


수정 후
try {
    $savec = $ADODB_COUNTRECS;
    $ADODB_COUNTRECS = false;

    if ($secs2cache != 0) {
        $rs = $this->CacheExecute($secs2cache, $sql, $inputarr);
    } else {
        $rs = $this->Execute($sql, $inputarr);
    }
} catch (Exception $e) {
    // 예외 발생 시 $ADODB_COUNTRECS 복원
    $ADODB_COUNTRECS = $savec;
    throw $e;
}

// 정상 실행 시 $ADODB_COUNTRECS 복원
$ADODB_COUNTRECS = $savec;

 

웹 인터페이스 설정

http://localhost/base에 접속하여 Snort DB 및 경로 정보를 설정하였다.

(XAMPP에서 Apache와 MySQL을 켜야 접속이 된다.)

 

step1

Pick a Language : 한국어가 없어 여어로 설정

Path to ADODB : adodb5  아까  저장해둔 C:\xampp\htdocs\adodb 경로로 설정

 

step2

Pick a Database type :
MySQL DB를 사용할 것이므로 MySQL 선택

Database Name : snort
이전에 명령프롬프트에서 설정한 DB명 ‘snort’

Database Host : localhost
현재 접속한 host 주소

Database Port :
DB 접속 시 어떤 포트로 접속할 것인지 결정
입력하지 않아도 무방

Database User Name, Password :
MySQL 계정 정보 입력

밑에 Archive Database는 사용하지 않을 것이므로 생략

 

step3

Use Authentication System : 인증 시스템 사용 여부 (체크)

Admin User Name : 로그인할 때 사용할 아이디

Password : 로그인할 때 사용할 비밀번호

Full name : base에서 사용할 닉네임


step4

 

‘Create BASE AG’ 버튼 클릭

 

 

'DONE'
'Successfully created user'
문구가 떴다면 성공적으로 Base 설정 완료

 

 

step5

설정을 모두 완료하고 마지막 단계 Step 5로 넘어가면 로그인 창 생성

Step 3에서 설정한 계정

Login : base_admin

Password : 비밀번호

입력하면 위에 화면이 뜨면 로그인 성공


Snort.conf 파일 설정

 

 

 

불필요한 라인 주석 처리

IDS 모드에서 사용하지 않는 라인을 주석 처리하였다.

rules 파일 작성

C:\snort\rules 경로에 사용 규칙 파일을 생성하였다.

MySQL 연계 설정

 

C:\Snort\etc\ 경로에서 snort.conf 파일을 Notepad++을 통해 열어준다.

 

변수 설정 변경

ipvar와 portvar를 모두 var로 변경하였다.

var: JavaScript 언어에서 ‘변수’ 설정의 역할 (C언어의 int와 비슷한 역할)

ipvar: IP 주소 또는 IP 주소의 목록/범위를 나타내는 목적으로 사용

portvar: 포트 번호 또는 포트 번호의 목록/범위를 나타내는 목적으로 사용

 

경로 수정

리눅스 초기 경로를 윈도우 경로인 C:\snort\ 경로로 변경하였다.

 

 

247, 250, 253번 라인의 경로도 초기 경로 설정값을 윈도우 경로로 변경 후, C:\snort\lib 경로에 접속해보면 dynamicpreprocessor파일과 dynamicengine 파일은 있지만 dynamicrulese 파일은 없기 때문에 이 파일을 직접 생성

 

265 ~ 269번 라인은 Snort IDS 모드에서는 사용할 수 없기 때문에
맨 앞에 # 을 입력해 주석 처리

 

510, 511번 라인 또한 윈도우 형식으로 변경 ( / → \ ) 후,


cmd를 통해 C:\snort\rules 경로에 해당 이름의 rules 파일 생성

 

 

MySQL연계설정

533, 534번 라인을 참고하여
output database: alert, mysql, user=root password=(비밀번호) dbname=snort host=localhost
output database: log, mysql, user=root password=(비밀번호) dbname=snort host=localhost
위 문장을 535, 536번에 이어서 작성

 

541, 542번 라인도 초기 경로 설정값을 윈도우 경로로 변경
(C:\snort\etc)

553번 라인에 사용할 rules 파일 입력 후, C:\Snort\rules 경로에 사용하고자 하는 rules 파일 생성

 

그 밑의 라인은 사용하지 않을 예정이므로 모두 주석 처리

 

 

sc.rules


Snort IDS 테스트

Snort.conf 검증

 

사용할 rules파일인 sc.rules파일을 열어 테스트 룰을 입력한다.

alert icmp any any -> any any (msg:"ICMP_TEST"; sid:10000001;)

 

이 Snort 규칙은 ICMP 프로토콜을 사용하는 모든 트래픽을 탐지하는 역할을 한다.

출발지와 목적지 IP 및 포트에 제한을 두지 않으며, 탐지된 패킷에 "ICMP_TEST"라는 메시지를 출력하고 고유 식별 번호(sid)로 10000001을 사용한다.

이 규칙은 주로 Ping 요청/응답 같은 ICMP 트래픽을 모니터링할 때 활용된다.

 

 

파일 위치로 이동 -> cd C:\Snort\bin

NIC 번호 확인 명령어를 입력 -> snort.exe –W

NIC 번호는 **네트워크 인터페이스 카드(Network Interface Card)**를 식별하는 번호이다.
한 시스템에 여러 네트워크 인터페이스가 있을 경우 Snort와 같은 도구가 모니터링할 네트워크 인터페이스를 지정하기 위해 사용한다.

 

snort.exe -T -c c:\snort\etc\snort.conf -l c:\snort\log -i 1
: Snort.conf 파일 검증 테스트 진행

‘Snort successfully validated the configuration!’
문구가 확인되면 설정이 잘 진행되었다는 의미

 

‘snort.exe -c c:\snort\etc\snort.conf -l c:\snort\log -i 1’
명령어로 Snort 실행한 화

(-c : snort 설정 파일 위치 지정)
(-l : 로그 파일 저장 위치 지정)
(-i : 모니터링할 NIC 번호 지정)
(NIC : 네트워크 인터페이스 카드)

 

‘Commencing Packet Processing (pid = )’ 문구를 보아 Snort가 정상적으로 실행 완료된 것을 확인

 

 

Server 가상환경의 IP주소를 확인하고, Client(Victim) 가상환경에서 Server 환경으로 ping을 보내 정상적으로 수신하는지 확인

 

 


http://localhost/base 도메인에 접속하면 전 슬라이드에서 보낸 Ping 패킷이 대한 로그가 ICMP 프로토콜 형태로 탐지된 것을 확인할 수 있음.

 

 

이렇게 Snort 환경 설정 완료.

 

 

참고 자료

https://velog.io/@pingu_9/%EB%B3%B4%EC%95%88%EA%B4%80%EC%A0%9C-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B81#25-base-%EC%84%A4%EC%B9%98

https://maker5587.tistory.com/25

https://velog.io/@secloud/17.-Snort-%ED%99%98%EA%B2%BD-%EA%B5%AC%EC%84%B1#xampp-%EC%84%A4%EC%B9%98

 

 

ppt

[19주차]snort 환경 구성.pptx
4.57MB

'Security > 보안관제' 카테고리의 다른 글

악성코드 샘플 분석3(하)  (0) 2025.01.04
악성코드 샘플 분석3(상)  (0) 2024.12.27
SNORT  (2) 2024.11.22
악성코드 샘플 분석2  (0) 2024.11.10
악성코드 샘플 분석  (0) 2024.11.03

+ Recent posts