미분 방정식 differential equation

- 현실의 물리 현상을 미분을 통해 모형화 한 방정식

- 상미분 방정식 ode ordinary de : 변수가 한개인 미방

- 편미분 방정식 pde partial de : 변수가 여러개인 미방

- 모델링 : 공학, 물리학, 화학 등 여러 분야의 실제 현상을 수학적으로 계산할 수 있도록 표현한 모델

 

 

* 목표 : 현실 문제에서상미분 방정식을 유도(모델링)하고, 방정식을 풀고 그래프 시각화하여 해석하자

 

1계 상미분 방정식

- 2차, 3차등 고차 도함수가 아닌 1차/1계 도함수만을 가지고 있는 미분방정식

 

 

공학 문제와 모델링

- 공학 문제를 계산을 통해 풀려면 수학 모델로 만들며 이를 모델링이라 함

- 모델링에 미방을 사용하는 이유 ? -> 다양한 물리 현상들이 도함수(미분)을 포함하고 있음(ex:속도, 가속도)

 

 

상미분방정식과 편미분 방정식

- 상미방 : 하나의 변수 <-> 편미방 : 여러 변수

 

미분 방정식 활용 예시

- 낙하, 스프링에서 변위, RLC 회로 전류, 진자 운동

 

 

 

 

상미분방정식의 양형태, 음형태

- 양형태 explicit form : 모든 항을 좌변으로 옮김

- 음형태 implicit from : 도함수만 좌변으로 옮김

 

 

 

 

- 해 : 어느 함수 h(x)가 열린 구간에서 정의/미분 가능하며, 이 함수 h(x)를 만족하는 y

- 해곡선 : 해들의 곡선

- 열린 구간 : a < x < b에서 양 끝 a와 b를 포함하지 않는 구간

 

 

 

 

상미분 방정식과 해

- y' = cos x인 (음형태) 상미분방정식이 있을때, ode의 해는 y = sin x + C

- 일반해 general solution : 임의의 상수 C를 가지고 있는 해

- 특수해 particular solution :  임의의 상수 C를 특정값으로 할때의 해

 

 

 

특수해와 초기값

- 초기조건 : 특정 입력값에 대한 출력 -> 일반해에 대입해 임의의 변수 c 값을 구할 수 있다.

 => 초기조건을 통해, 해당 초기조건의 특수해를 구한다.(초기값 문제)

 

 

 

초기값 문제 예시

- y' = 3y, y(0) = 5.7일 때 특수해를 구해보자

 * y' = 3y : y를 미분했더니 y가 나온다 y는 지수함수의 형태다.

 * 구한 일반해에 위 초기조건을 대입하여 C를 구하

=> 특수해 y = 5.7 e^3x

 

 

해석적 방법과 수치적 방법

- 해석적 방법 : 직접 계산하여 정확한 해를 구함

- 수치적 방법 : 근사화를 통해 해를 구함

 

1계 ode의 기하학적 의미

- y' = f(x, y)를 기하학적으로 해석해보자

- 점 (x0, y0)을 지나는 위 ode의 해곡선은 y'(x0) = f(x0, y0)을 만족해야한다.

 -> 그래픽 or 수치해석적 방법으로 ode의 근사해를 얻을 수 있다.

 

 

 

상미분 방정식의 방향장 시각화

- y' = y + x라는 상미분 방정식이 주어질 때, (0, 1), (0, 0), (0, -1) 세 점을 지난다면

 -> 3개의 해곡선을 가지며, 세 해곡선과 해당 ode의 방향장은 다음과 같다.

* 뒤에 오일러방법 계산하다가 자꾸 값이 이상하게 나왔는데 일반해부터 잘못 구한거같다

 

오일러 방법 - 간단한 수치해석적 방법

- ode와 초기값이 주어질 때, x1 = x0 + h라면

  => y1 = y0 + h * y' = y0 + h * f(x0, x0)

- 간격 h가 작을수록 오차는 줄어든다.

- h = 0.2로 놓고 구한 근사값과 실제 특이해를 비교하면 오차가 점점 커지는걸볼수있다.

 

요즘 시퀀스를 공부하게 되면서

 

전동 드릴/드라이버 구경하다가

 

전기 회로에 사용할건 아니지만 신기하게 생긴 툴앤툴의 와우슬림을 찾았습니다.

 

 

 

팬 사이즈의 전동 드라이버라니 수동 드라이버만 쓰다가 왠건가 싶었죠

 

이거 말고도 샤오미나 다른 회사 제품들도 찾아봤지만

 

와우 슬림이 가성비 갑이기도하고, 다른 사은품도 준다고 하길래 구입했습니다.

 

 

 

 

배송온 와우슬림

 

 

딱 볼펜사이즈입니다.

 

 

 

보관 가방이 없는건 아쉽지만

 

제품 상자를 그대로 써도 괜찬을거같아요.

 

USB -C 케이블도 있고

 

 

 

 

 

 

실제 사용해본 영상입니다.

 

나중에 전자 제품 다룰때 쓰기 딱 좋아보이네요.

 

 

 

 

Tcl(tool command language)/Tk, tkinter

- Tcl :  웹, 데스트탑 어플, 네트워크, 테스팅 등 다양한 용도로 동적 프로그래밍 하기 좋은 언어

- Tk : GUI 라이브러리 제공하는 툴킷

- tkinter : Tcl/Tk 파이썬 레퍼로 tkinter 패키지로 gui 프로그래밍

 

 

1. tkinter window 관리 예제

- 윈도우 만들고, 크기 고정하고, X 누르면 메시지박스, iconify 버튼으로 아이콘화, quit버튼으로 종료

import tkinter
from tkinter import *
from tkinter import messagebox

global window

window = Tk()
window.title("window = Tk()")
window.geometry("300x300+100+100")
window.resizable(width=False, height = False)

def ask_quit():
    result = messagebox.askquestion("Msg", "quit?")
    if result == "yes":
        window.destroy()

label = Label(window, text="Buttons")
label.pack() # pack()윈도우에 배치
iconBtn = Button(window, text="iconify", command=window.iconify) #iconify 아이콘화
iconBtn.pack()
quitBtn = Button(window, text="quit", command=window.destroy)
quitBtn.pack()

window.protocol("WM_DELETE_WINDOW", ask_quit)
window.mainloop()

 

 

tkinter의 widget(window gadget) 클래스 

- tkinter의 위젯으로 frame, canvas가 있다.

- 하나의 윈도우에는 여러 프레임을 넣을 수 있다.

- 각 프레임에는 여러 캔버스를 넣을 수 있다.

- 각 캔버스에는 여러 라벨과 버튼 등의 위젯을 넣을 수 있다.

 

위젯 종류

- entry : 문자열 입력 공간

- scale : 슬라이드로 설정

- menu : 팝업 팝다운 메뉴

- 등

 

https://m.blog.naver.com/sisosw/221408280038

 

 

 

2. 윈도우 안에 프레임과 캔버스 그리기

import tkinter
from tkinter import *

window = Tk()
window.title("window - tk()")
window.geometry("600x600+200+100")
window.resizable(width=False, height=False)



frame1 = Frame(window, bg="light green", cursor="heart", bd=5, padx=10, pady=10, relief=GROOVE) #relief 프레임 기본 스타일
#relief : flat(기본), raised(버튼올린모양), sunken(버튼눌린모양), groove, ridge 등(대문자)
frame1.grid(row=0,column=0)
frame2 = Frame(window, bg="yellow", cursor="man", bd=5, padx=10, pady=10, relief=GROOVE)
frame2.grid(row=1,column=0)
frame3 = Frame(window, bg="yellow", cursor="plus", bd=5, padx=10, pady=10, relief=GROOVE)
frame3.grid(row=2, column=0)


canvas_11 = Canvas(frame1, bg="lime", width=100, height=100)
canvas_11.grid(row=0, column=0, fill=None, padx=10, pady=10)
canvas_12 = Canvas(frame1, bg="orange", width=150, height=100)
canvas_12.grid(row=0, column=1, fill=None, padx=10, pady=10)
canvas_13 = Canvas(frame1, bg="grey", width=100, height=100)
canvas_13.grid(row=1, column=1, fill=None, padx=10, pady=10)


canvas_21 = Canvas(frame2, bg="magenta", width=200, height=50)
canvas_21.grid(row=0, column=0, fill=None, padx=10, pady=10)
canvas_22 = Canvas(frame2, bg="brown", width=200, height=50)
canvas_22.grid(row=0, column=1, fill=None, padx=10, pady=10)
canvas_23 = Canvas(frame2, bg="sky blue", width=200, height=50)
canvas_23.grid(row=1, column=0, fill=None, padx=10, pady=10)

canvas_31 = Canvas(frame3, bg="light green", width=400, height=50)
canvas_31.grid(row=0, column=0, fill=None, padx=10, pady=10)
window.mainloop()

 

위젯 배치 layout

- 압축 배치 pack() : pack(fill=BOTH)  # fill= X, Y, BOTH  

- 격자 배치 grid() : grid(row=2, column=1)

- 절대 위치 배치 place() : place(x=200, y=200)

 

 

 

3. 압축 배치 연습

 

from tkinter import *

window =Tk()
window.title("testing pack layout")
window.geometry("400x300+100+200")



label1 = Label(window, text="label 1", bg="red", fg="white").pack(fill=X, padx=10, pady=10)
label2 = Label(window, text="label 2", bg="green", fg="black").pack(fill=X, padx=10, pady=10)
label3 = Label(window, text="label 3", bg="yellow", fg="white").pack(fill=X, padx=10, pady=10)

label4 = Label(window, text="label 4", bg="red", fg="black").pack(fill=X,padx=10, pady=10, side=LEFT)
label5 = Label(window, text="label 5", bg="green", fg="black").pack(fill=X, padx=10, pady=10, side=LEFT)
label6 = Label(window, text="label 6", bg="blue", fg="black").pack(fill=X, padx=10, pady=10, side=LEFT)

listbox = Listbox(window)
listbox.pack(fill=BOTH, expand=1)
L = [100, 200, 300, 400, 500]
for i in range(len(L)):
    listbox.insert(END, str(L[i]))

mainloop()

 

 

grid 함수

- column = 열, row = 행

- columnspan = 위젯이 차지하는 열 칸 수, rowspan = 위젯이 차지할 행칸 수

- in : 위젯이 놓일 위젯, 디폴트는 부모 위젯

- sticky : 위젯을 어떻게 붙일건지 디폴트는 중앙, NSEW는 셀 경계 딱붙인다.

 

entry 위젯 주요 함수

- focus() : 키보드 입력 가능하게 함

- bind() : 특정 이벤트시 실행 함수 바인드

 

 

 

 

4. 그리드 레이아웃과 엔트리 바인드

- window.bind()와 Button(command=())로 엔터키를 누르거나("<Return>"), 버튼누를시 fetch()함수 호출

 -> 엔터누르거나 fetch 버튼 클릭 시 fetch 함수대로 입력 데이터가 잘 출력된다.

from tkinter import *

def fetch(cells):
    print("- input data -")
    for i, e in enumerate(cells):
        print("  {0}:{1}".format(fields[i], e.get()))

def make_form(fields):
    cells = []
    for r, field in enumerate(fields):
        label = Label(window, width=10, text= field)
        entry = Entry(window)
        label.grid(row=r, column=0, sticky=NSEW)
        entry.grid(row=r, column=1, sticky=NSEW)
        cells.append(entry)
    return cells

if __name__ == "__main__":
    window = Tk()
    window.title("Input Dialog with label and entry")
    fields = ("Name", "Age", "Address")
    cells = make_form(fields)
    window.bind("<Return>", (lambda event, e=cells: fetch(e)))
    #엔터키 눌릴떼 람다식 호출 바인드
    #cells를 e에 담고 fetch 호출
    # 주의 : bind 함수 호출시 lambda 식 앞단에 인수를 2개해야한다.
    Button(window, text="Fetch", bg="green",
           command=(lambda e=cells:fetch(e))).grid(row=3, column=0, sticky=NSEW)
    # 버튼 눌릴때도 fetch(e) 호
    Button(window, text="Quit", bg="Red", command=window.destroy).grid(row=3, column=1, sticky=NSEW)
    print("grid size : ", window.grid_size())
    window.grid_columnconfigure(1, weight=1)
    window.grid_rowconfigure(0, weight=1)
    window.mainloop()

 

 

캔버스 객체의 함수들

- after(delay_ms, callback=None, *args) : 딜레이 타임 후 콜백함수 호출

- bind(sequence=None, func=None, add=None)  : 시퀀스 이벤트에 func 바인딩

- bind_all(csequence=None, func=None, add=None) : 모든 위젯에 func 바인딩

- bind_class(className, sequence=None, func=None, addd=None) : 해당 클래스 모든 위젯에 이벤트 func 바인딩

- create_image/line/oval/polygon/rectangle/text/window

- pos = canvas.coords(객체이름, pos) : 해당 객체 위치

- destroy() : 위젯과 객체제거

- mainloop() : 반복 시작

- quit() 반복 중지

- move(item, dx, dy) : 해당 아이템 객체를 이동

- update() 디스플레이 갱신

 

 

 

Event

- 버튼 : <Button-1>(마우스 왼쪽버튼 클릭), <Button-2> (마우스 휠 클릭), <button-3> (마우스 우클릭)

- 모션 : <Motion>(마우스 움직일때), <B1-Motion> 마우스 좌클릭채 움직일때, ...

- 위젯 동작 : <Configure> 위젯 모양 변경시, <Enter> 위젯안으로 마우스 들어갈때, <Leave> 위젯에서 나올때

- etc ...

 

 

 

 

5. 프레임, 캔버스 크기변경 이벤트 시 함수 호출

- 모든 위젯 크기 변경시 onsize 호출

- 그 중 위젯이 프레임일때 현재 크기반영해 라벨 변경

from tkinter import *

def onSize(event):
    if event.widget == frame: # 이벤트 호출된 위젯이 프레임인경우
        frame.update() # 라벨 변경전 갱신
        label_fr.configure(text="frame size: {}x{}".format(frame.winfo_width(), frame.winfo_height()))
        canvas.update()
        label_cnv.configure(text="canvas size: {}x{}".format(canvas.winfo_width(), canvas.winfo_height()))
    
    
if __name__ == "__main__":
    global label_Fr, label_cnv, frame, canvas
    window =Tk()
    window.title("finding frame and canvas size at resizing events")
    frame = Frame(window, bg="light green", bd=10, padx=50, pady=50, relief=GROOVE)
    frame.pack(expand=YES, fill=BOTH)
    canvas = Canvas(frame, bg="white", width=600, height=400)
    canvas.pack(expand=YES, fill=BOTH, padx=10, pady=10) #frame, canvas 양방향 조절 가능
    frame.update()
    label_fr = Label(canvas, text="frame size: {} x {}".format(frame.winfo_width(), frame.winfo_height()))
    label_fr.grid(row=0, column=0, sticky=N)
    canvas.update()
    label_cnv = Label(canvas, text="canvas size: {} x {}".format(canvas.winfo_width(), canvas.winfo_height()))
    label_cnv.grid(row=1, column=0, sticky=S)
    
    # <Configure> : 위젯모양변경시 이벤트 -> onSize() 호출
    # bind_all(컨피겨, func) -> 모든 위젯 크게 변경시 onsize() 호출 
    window.bind_all("<Configure>", onSize)
    window.mainloop()

 

 

 

 

+ 깃 로컬 저장소를 원격 저장소에 올리기

1. git init으로 깃 저장소 초기화

2. git add . 모든 파일 스태징

3. 커밋

 

4. git remote add origint 원격저장소 주소

5. git remote -v로 연결되었는지 확인

6. git push -u origit master 로컬 저장소 브랜치를 원격 저장소 master로 푸시(u는 지역과 원격 연결을 위해 한번만)

 

 

7. 깃헙에 잘올라갔다.

+ Recent posts