2022년 5월 7일 토요일

오즈비 (Odds Ratio = 승산비)에서 로지스틱으로

1. 오즈비 

사건이 발생할 확률이 발생하지 않을 확률에 비해 몇배 더 높은가를 설명하는 개념

 이미지 출처 : https://m.blog.naver.com/y4769/221851780608

2. 오즈비 계산 예

A : 97명 - 코로나 환자와 접촉 후, 코로나에 감염됨
B : 307명 - 코로나 환자와 접촉 후, 코로나에 감염되지 않음
C : 200명 - 코로나 환자와 접촉하지 않았지만, 코로나에 감염됨
D : 1409명 - 코로나 환자와 접촉하지 않았고, 코로나에 감염되지 않음

Odds Ratio(OR) = 136673 / 61400 = 2.2로 계산된다.

따라서, 코로나 환자와 접촉한 사람은 접촉하지 않은 사람보다 코로나 감염이 될 가능성이 2.2배 높다고 할 수 있다.

3. 로짓(logit) 변환: 오즈비에 log 함수 적용한 것으로 로짓을 대상으로 회귀분석을 적용한 것이 로지스틱 회귀분석이 된다.

logit = log( p / 1-p )

2022년 5월 6일 금요일

오렌지3에서 Sqlite 데이터베이스 읽어오기

 Sqlite 데이터베이스는 데이터베이스 서버가 없는 파일형태의 데이터베이스입니다. 하나의 데이터베이스에는 여러개의 테이블이 있고 각각의 테이블은 레코드로 구성되어 있습니다.

오렌지3에서 Sqlite데이터베이스에 자료를 입력하는 경우는 별로 없을 것이고, 누군가(시스템, 기계, 여론조사 디비등등)가 만들어 놓은 자료를 접근하여 읽어오기만 하면될것입니다. (나중에 기회되면 쓰는 것도 다루어 보죠)

1. 먼저 Sqlite 데이터 베이스를 (이곳에서 다운로드) 에서 다운받아 컴퓨터의 적당한 곳에 저장해 둡니다.

2. 파이썬스크립트위젯과 데이터테이블위젯을 아래와 같이 오렌지 캔바스에 배치합니다.


2. 파이썬스크립트를 더블크릭하고 아래코드를 붙여넣기하고 [RUN] 버튼을 선택합니다.

import sqlite3
import Orange.data.pandas_compat as p

conn = sqlite3.connect('exam.sqlite', isolation_level=None)
iSql = 'select * from table2 where date >= "2010-01-01" order by date'
idf = p.pd.read_sql(iSql, conn)
out_data = p.table_from_frame(idf)
 
3. 데이터테이블위젯을 더블크릭하여 확인합니다.

3. 이제 스크립트를 설명합니다.
  • 1행: 당연히 sqlite 관련 객체를 불러오기위하여 import 하여야 겠지요.
  • 2행: pandas를 이용해 데이터베이스 내용을 읽어와야 하기때문에 오렌지3 설치될때 같이 설치된 pandas_compat를 import 해옵니다.
  • 3행: 데이타베이스와의 연결을 위한 객체를 생성합니다. (첫 인수로는 Sql 파일이 있는곳과 파일이름, commit 단계)
  • 4행: SQL 명령어
  • 4행: pandas의 read_sql을 이용하여 SQL 명령어를 연결객체에 전달합니다. 그결과가 idf에 DataFrame 형태로 보관됩니다.
  • 5행: DataFrame을 위젯의 출력으로 변환합니다.

4. SQL 명령어를 간단히 설명합니다.
  • select * from은 무조건이라고 생각하면 됩니다. 뒤에 조건에서 지정한 모든(*) 자료를 읽어오라는 것입니다.
  • exam.sqlite 라는 것이 데이타베이스입니다. 엑셀로 따지면 파일이름이겠지요.
  • table1은 엑셀에는 시트가 여럿 있듯이 데이타베이스에도 테이블이 여러개 있으며 그중 table2 에서 읽어오라는 것입니다.
  • where는 그다음의 조건에 맞는 것을 읽어오라는 것이고
  • date >= "2010-01-01"은 엑셀로 따지면 컬럼이름과 같은 의미의 date 라는 필드(컬럼)에서 "2010-01-01" 이후 자료를 지정한 것입니다.
  • order by date는 자료를 읽어 가져올때 date 라는 필드(컬럼)의 오름차순 정렬을 의미합니다.

5. SQL 명령부분은 "select * from table1" 만하고 오렌지의 다른위젯을 이용해 데이터를 취사 선택 정렬할 수 있습니다.  또한 읽기전용이기에 conn의 "isolation_level=None" 부분도 생략할 수 있습니다.








오렌지3로 주성분분석 (PCA)

 파이썬을 활용한 데이터·AI 분석 사례 (건강보험심사평가원 발행) 페이퍼를 보면서 오렌지3를 익히고 있습니다.

오렌지3 만으로도 이러한 분석이 가능한 걸 알면 의료분야 많은 교수님들이 좋아 할 것 같습니다. 저는 의료분야는 문외한이라 페이퍼에 나온 것을 오렌지로 구현해본 것 뿐입니다.

1. 주성분분석(Principal Component Analysis)

여러 특성(feature)가운데 대표 특성을 찾아 분석하는 방식으로, 대표 특성의 선별은 자료의 차원을 고차원에서 하위 차원으로 축소하는 (차원축소)기법을 활용한다.

2. 분석연습

위스콘신 암센터 569명의 유방암 진료 환자 샘플 데이터를 PCA에 활용하였다. 암 진단에 필요한 속성 정보와 양성(Benign)/악성(malignant) 진단 결과로 분류된 환자 데이터이다. 해당 데이터 세트를 검토하여 유방암 진단에 설명력이 높은 주성분들을 찾아본다.

3. 일단 오렌지를 실행하고 > 위젯을 아래와 같이 배치합니다. 


주된 루트는 파이썬스트립트 > 프리프로세스 > 주성분분석(PCA)입니다. 

4. 파이썬스크립트를 더블크릭하고 내용을 아래와 같이 수정하고 [RUN] 버튼을 눌러 실행합니다.

from sklearn.datasets import load_breast_cancer
import numpy as np
from Orange.data import Table, Domain, ContinuousVariable, DiscreteVariable

cancer = load_breast_cancer()

ifeature = list(cancer.feature_names)
jfeature = [istr.replace(' ', '_') for istr in ifeature]
iclass = DiscreteVariable('target',cancer.target_names)
domain = Domain([ContinuousVariable(istr) for istr in jfeature], iclass)

out_data = Table.from_numpy(domain, cancer.data, cancer.target)

domain 관련하여 약간의 코딩이 들어 갔습니다. 에디트도메인위젯을 이용하면 쉽게할 수 있습니다.

5. 오렌지를 설치하면 자동으로 깔리는 sklearn에 있는 자료를 불러와 오렌지3의 테이블 형식으로 변경하는 것입니다.

6. 이제는 오렌지3의 위젯을 더블크릭하여 확인하는 일만 남았습니다. 이런것을 이짧은 코딩으로 가능하다니 놀랍지 않나요? 불어온 자료를 눈으로 확인합니다.


6. Feature Statistics를 더블크릭하여 확인합니다. 양성/악성이 특정 Feature에의해 구분이 가능하군요.


7. 다음으로 데이터 표준화 또는 정규화 작업이 필요하다. 속성마다 데이터값의 범위가 다르므로 이를
주성분 선별 전에 전처리해야 각 속성의 영향도를 같은 선상에서 비교할 수 있다. Preprocess 위젯을 더블크릭하여 아래와 같이 표준화를 합니다.

8. 표준화된 Data TAble (1)을 더블크릭하여 데이터를 확인합니다.

9. PCA 위젯을 더블크릭하고 [Components = 6] 으로 설정합니다. 페이퍼와 일치 시키기위해서


10. Distribution (1)을 더블크릭하여 주성분의 적중여부를 확인합니다.




Orange3 Preprocess 위젯에서 Standardize 와 Normalize

 1. Orange3 Preprocess 위젯에서 Normalize Features 의 Standardize 와 Normalize 의 차이를 알고 계신가요. 용어가 참 햇갈리게 사용됩니다.


2. 데이터 표준화와 정규화의 차이
데이터전처리를 하기 위해 흔히 표준화와 정규화라는 방법을 많이 사용하게 된다. 혼동하기 쉬운 용어이나
의미와 사용목적의 차이가 있으므로 적절한 전처리 방법을 선택해 분석해야 한다.


3. 참고로 VSCode에서도 오렌지의 작업을 할 수 있으며, 
import Orange
from Orange.preprocess import Normalize
health = Orange.data.Table('housing.tab')
normalizer = Normalize(norm_type=Normalize.NormalizeBySD)
normalized_data = normalizer(health)
print("Before Normalization: ",health[2])
print("After Normalization: ",normalized_data[2])

Before Normalization: [0.02729, 0.0, 7.07, 0, 0.4690, 7.185, 61.1, 4.9671, 2, 242, 17.8, 392.83, 4.03 | 34.7] After Normalization: [-0.417342, -0.4877, -0.59338, -0.273, -0.74026, 1.28271, -0.2658, 0.557160, -0.868, -0.9873, -0.303, 0.396427, -1.20873 | 34.7]
import Orange
from Orange.preprocess import Normalize
health = Orange.data.Table('housing.tab')
normalizer = Normalize(norm_type=Normalize.NormalizeBySpan)
normalized_data = normalizer(health)
print("Before Normalization: ",health[2])
print("After Normalization: ",normalized_data[2])

Before Normalization: [0.02729, 0.0, 7.07, 0, 0.4690, 7.185, 61.1, 4.9671, 2, 242, 17.8, 392.83, 4.03 | 34.7] After Normalization: [0.000235698, 0.000, 0.242302, 0, 0.172840, 0.694386, 0.59938, 0.348962, 0.0435, 0.10496, 0.5532, 0.9897373, 0.063466 | 34.7]

4. 같은 방법으로 오렌지의 파이썬스크립트를 이용해 처리 할 수 있습니다.


파일 불러오는 부분은 #(Remark)로 막아야 하는데 파일위젯에서 불러왔으므로......

5. 당연히 같은 결과를 얻을 수 있습니다.




Orange3 경고 FutureWarning: pandas.Int64Index

 맥에서 오렌지3를 실행할때 가상환경으로 이동한후 

$ orange-canvas 

또는

$ orange-canvas &

하여 백그라운드로 실행하는데

(orange3) jglee@iMac Orange3 % orange-canvas

/Users/jglee/opt/miniconda3/envs/orange3/lib/python3.8/site-packages/statsmodels/tsa/base/tsa_model.py:7: FutureWarning: pandas.Int64Index is deprecated and will be removed from pandas in a future version. Use pandas.Index with the appropriate dtype instead.

  from pandas import (to_datetime, Int64Index, DatetimeIndex, Period,

/Users/jglee/opt/miniconda3/envs/orange3/lib/python3.8/site-packages/statsmodels/tsa/base/tsa_model.py:7: FutureWarning: pandas.Float64Index is deprecated and will be removed from pandas in a future version. Use pandas.Index with the appropriate dtype instead.

  from pandas import (to_datetime, Int64Index, DatetimeIndex, Period,

(orange3) jglee@iMac Orange3 % code   /Users/jglee/opt/miniconda3/envs/orange3/lib/python3.8/site-packages/statsmodels/tsa/base/tsa_model.py

과 같은 경고 메시지가 나옵니다.

nano, vim, VSCode 등 에디터로 tsa_model.py 를 불러들여 Int64Index 와 Float64Index를 Index로 바꾸어 주면 됩니다.

바꾸어주고 실행하면 깔끔합니다.

화면이 지저분해서지 실행하는데는 전혀 지장이 없습니다.


2022년 5월 5일 목요일

카이제곱 검정의 적합도 검정(예제)

 카제곱 검정의 독립성 검정은 이곳에서 살펴 보았는데 적합성 검정은 오렌지에서는 찾기 힘들어 파이썬스크립트를 사용해야만 할 것 같음. 아래 예제는 유의수준 5%임.

1.   귀무가설: H0 : 6가지의 상황에서 기대값이 같을 것이다.

      대립가설(연구가설): H1 : 어느 하나는 다르다.

import scipy.stats as ss
xo = [16, 18, 16, 14, 12, 12]
ss.chisquare(f_obs= xo)

Power_divergenceResult(statistic=2.0, pvalue=0.8491450360846096)

귀무가설을 기각 할 수 없다. 어느 하나의 상황도 다른 것들과 다르다고 볼 수 없다.

2. 귀무가설: H0 : 6가지의 상황에서 기대값이 같을 것이이다.

     대립가설(연구가설): H1 : 기대 값과 다른 어느하나가 있다.

import scipy.stats as ss

xo = [16, 18, 16, 14, 12, 12]
xe = [16, 16, 16, 16, 16, 8]
ss.chisquare(f_obs= xo, f_exp= xe)

Power_divergenceResult(statistic=3.5, pvalue=0.6233876277495822)

귀무가설을 기각 할 수 없다. 어느 하나의 상황도 기대값에 벗어 났다고 볼 수 없다.

3. 

import scipy.stats as ss
xo = [324, 78, 261]
xe = [371, 80, 212]
ss.chisquare(f_obs = xo, f_exp= xe)

Power_divergenceResult(statistic=17.329649595687332, pvalue=0.00017254977751013492)

귀무가설을 기각한다. 3개의 상황중 적어도 하나는 기대값에 벗어 났다.

4. 학습할 경우 주의할 사항은 관측값의 합계와 기대값의 합계는 같아야 합니다. (당연한데 햇갈립니다)

5. 독립성검정은 아래와 같은 방법도 가능합니다.

import pandas as pd
import scipy.stats as ss

x = [[269, 83, 215], [155, 57, 181]]
df= pd.DataFrame(x)
ss.chi2_contingency(df)

(7.094264414804222, 0.028807134195296135, 2, array([[250.425 , 82.6875, 233.8875], [173.575 , 57.3125, 162.1125]]))

귀무가설을 기각한다. 1의 환경(남자)과 1의 환경(여자)의 상품 1 ,2, 3의 소비형태가 차이가 있다.

2022년 5월 2일 월요일

연관규칙분석(Association Rule Analysis)

연관분석

  • 대량의 트랜잭션 정보로부터 개별 데이터(변수) 사이에서 연관규칙(x면 y가 발생)을 찾는 것
  • 가령 슈퍼마켓의 구매내역에서 특정 물건의 판매 발생 빈도를 기반으로 ‘A물건을 구매하는 사람들은 B물건을 구매하는 경향이 있다.’라는 규칙을 찾을 수 있다. 
  • 다른 말로 장바구니 분석(Market Basket Analysis)이라 한다. 

신뢰도(Confidence)
  • 항목 A를 포함한 거래 중에서 항목 A와 항목 B가 같이 포함될 확률
  • 즉 우유를 구매했을 때 식빵이 장바구니로 함께 들어갈 확률이 바로 신뢰도인 것이다. 

지지도(Support)
  • 전체 거래 중 항목 A와 B를 동시에 포함하는 거래의 비율이다. 
  • 장을 본 목록을 확인했을 때 우유와 식빵이 꼭 함께 있을 확률이다.

향상도(Lift)
  • A가 주어지지 않은 상태에서 B의 확률에 대하여 A가 주어졌을 때 B의 확률 증가비율
  • 만일 A에대해 B가 등장할 경우와 A에 대해 C가 등장할 경우의 두 신뢰도가 같다면 어떻게 해야 할까? 
  • 대개 이럴때 향상도 지표가 활용된다. 
  • A에 대해 B가 등장 가능성이 높은지 C가 등장 가능성이 더 높은지를 확인하는 지표로 향상도가 있다.


1. 오렌지에서 연관분석 하기

2. 데이터 보기
3. 결과 보기

4. 건강보험심사평가원에서 나온 파이썬을 활용한 데이터.AI분석사례를 오렌지로 구현해보았습니다. 그런데 파이썬으로 구현할때와는 조금씩 다르네요...

5. 달걀과 양파 두 품목 모두를 구매할 확률(지지도)의 가장 큰값은 0.6이고, 달걀을 무매 할때 양파를 구매할 가능성은 100%로 보이네요. 저도 잘 이해를 못하겠어요.... 저는 통계 전문가가 아니어서 신뢰도, 지지도, 향상도가 돌아서면 감감 합니다.

 

2022년 5월 1일 일요일

Mac 에서 Qt Designer 와 VSCode를 연동해봅니다.

 저 같은 경우는 miniconda로 가상환경을 설치하였기에 아래와 같이 하여 VSCode를 시작하였습니다. (% brew install --cask visual-studio-code 으로 설치)


1. PYQT Intergration 익스텐션을 설치합니다. (VSCode 가 파이썬을 작성할 수 있는 환경이라 가정합니다)


2. 설정화면으로 이동합니다.


3. Extension > Qt for Python > Edit in settings.json을 선택하여 json 파일을 수정합니다.


4. 저같은 경우는 아래와 같습니다. 수정이 끝났으면 저장합니다.(중요!)
"python.defaultInterpreterPath": "/Users/jglee/opt/miniconda3/envs/orange3/bin/python",
"terminal.integrated.inheritEnv": false,
"editor.hover.enabled": false,
"editor.hover.sticky": false,
"editor.inlayHints.enabled": false,
"qtForPython.uic.path": "/Users/jglee/opt/miniconda3/envs/orange3/bin/pyside6-uic",
"pyqt-integration.qtdesigner.path": "/Applications/Qt Designer.app/Contents/MacOS/Designer",
"qtForPython.designer.path": null

만약 PyQt5 과 pyside6 가설치되어 있지 않으면 해당 가상환경상태로 이동한다음 
$pip insatll PyQt5
$pip install pyside6
맥의 파인더에서 응용프로그램 > Qt Designer > 마우스 우측 크릭 > 패키지 내용보기 > Contents > MacOS 하여보면 Designer 경로를 할수 있습니다.

5. 이것이 정상으로 설정되면 


test.ui 에서 마우스 우측크릭을 하면 (2)에서와 같이 미리보기, Qt Designer 불러내기, .ui 를 .py 로 컴파일하여 프로그램을 쉽게  할 수 있습니다. 참고로  컴파일된 내용의 일부를 보여드립니다.
from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(376, 274)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.testButton = QtWidgets.QPushButton(self.centralwidget)
self.testButton.setGeometry(QtCore.QRect(120, 70, 113, 32))
self.testButton.setObjectName("testButton")
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 376, 24))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)

self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)

def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.testButton.setText(_translate("MainWindow", "PushButton"))

원래 이것은 디자이너에서 볼 수 있어야 하는데 경량 디자이너에서는 실행이안됩니다.(인터넷에 관련 질문은 많으나 그렇다할 해결방법을 알려주지 않더군요)

6. (5)번의 아랫부분에 아래 코드를 추가하고 관련 모듈을 추가하면 코딩이 끝납니다. 이러한 방식으로 하면 코드 자동완성기능이 되어서 코딩이 쉬워집니다.

self.te 하면 self.testButton이하를 아주 쉽게 자동완성 할 수 있습니다.

전체코드 중복부분 생략함

import sys
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QApplication, QMainWindow

class Ui_MainWindow():
def setupUi(self, MainWindow):
................

class WindowClass(QMainWindow, Ui_MainWindow):
def __init__(self):
super().__init__()
self.setupUi(self)
self.testButton.clicked.connect(self.btnClick)
def btnClick(self):
self.testButton.setText('test')
print("버튼이 클릭되었습니다.")
if __name__ == "__main__":
app = QApplication(sys.argv)
myWindow = WindowClass()
myWindow.show()
app.exec_()

Mac에서 QtDesigner로 윈도우(창)을 만들고 실행해보기(헬로우 월드)

 맥에서입니다. Qt Designer 경량버전 설치

앞에서 Qt Designer경량버전을 설치하였습니다. 런처패드로가서 실행합니다.

1. Main Window 로 지정하고 > Create 버튼을 선택합니다.

2. 왼쪽에서 pushButton 위젯을 드래그하여 (2)와같이 위치시키고 > (3)과 같이 이름을 testButton으로 바꾸어줍니다(이 이름은 기억해야 합니다) > 그리고 test.ui 라는 이름으로 저장해둡니다. 저장위치를 기억해야 합니다.


3. 같은 위치에 VSCode 나 텍스트 편집기등으로 아래와 같이 작성하여 test.py라는 이름으로 저장하고 실행합니다.

import sys
from PyQt5 import uic
from PyQt5.QtWidgets import QApplication, QMainWindow

form_class = uic.loadUiType("./test.ui")[0]

class WindowClass(QMainWindow, form_class):
def __init__(self):
super().__init__()
self.setupUi(self)
self.testButton.clicked.connect(self.btnClick)
def btnClick(self):
self.testButton.setText('test')
print("버튼이 클릭되었습니다.")


if __name__ == "__main__":
app = QApplication(sys.argv)
myWindow = WindowClass()
myWindow.show()
app.exec_()

4. 윈도우가 하나 나타나면 버튼을 크릭해봅니다. 아래와 같이 버튼의 캡션이 "test"로 바뀌고 콘솔창에 "버튼일 클릭되었습니다." 라고 표시됩니다.


5. 델파이 보다는 번잡하군요. 그렇게 생각해보면 델파이는 정말 대단해요....


Mac에서 QtDesigner 가 실행이되지 않을 때..

 파이 썬으로 PyQt5를 이용하여 윈도우를 만들어 화면에 띄울때 아래와 같이 일일이 코딩을 해야 합니다.

import sys
from PyQt5.QtWidgets import *
class MyWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setupUI()
def setupUI(self):
self.setWindowTitle('ButtonLabelWindow')
self.setGeometry(100,100,300,100)
self.label = QLabel("Message:", self)
self.label.move(20,20)
self.label.resize(200,20)
btnSave = QPushButton('저장',self)
btnSave.move(20,50)
btnSave.clicked.connect(self.btnSave_clicked)
btnCancel = QPushButton('취소',self)
btnCancel.move(120,50)
btnCancel.clicked.connect(self.btnCancel_clicked)
def btnSave_clicked(self):
self.label.setText('저장 되었습니다.')
def btnCancel_clicked(self):
self.label.setText('취소 되었습니다.')
if __name__=='__main__':
app = QApplication(sys.argv)
window = MyWindow()
window.show()
app.exec_()
GUI 환경에서 할 수 있게하는 프로그램이 Designer인데 아쉽게도 Mac 환경에서는 돌아가지 않습니다. (2022. 5.1 현재) 이를 해결해야하는 방법은 Designer에서 유료화된 QtDesignor나 업그레이드된 QtCreator를 사용해야하는 데 워낙시스템이 무겁고 맥환경에서는 설정이 너무 어렵습니다.

또다른 방법으로는 아나콘다-네비게이터를 사용하는 방법인데 네비게이터를 사용해본 결과 편리한 점 보다 갑갑한 점이 너무 많아 미니콘다를 사용하고 있기에....

그러던중 이를 해결해 줄수 있는 웹을 발견하였습니다. 필요하시는 분은 다운 받아 설치해보십시요.


이곳을 방문하여 관련 파일을 다운 받아 설치하시면 됩니다. 홈페이지 소개 문장을 번역기로 돌려서 몇자 올려봅니다.

많은 사람들이 기가바이트의 다른 소프트웨어를 다운로드하지 않고도 Qt Designer를 사용하기를 원합니다. 다음은 Windows 및 Mac용 Qt Designer의 소규모 독립 실행형 설치 프로그램입니다.

Qt Designer는 Qt GUI 프레임워크의 위젯으로 그래픽 사용자 인터페이스를 빠르게 구축하기 위한 도구입니다. 버튼, 텍스트 필드, 콤보 상자 등과 같은 구성 요소를 배치하기 위한 간단한 드래그 앤 드롭 인터페이스를 제공합니다. 

아! 그런데 Qt Designer를 VSCode와 연동을 하려는데 자꾸에러가 떠서 나중에 해결되면 소개하겠습니다. 파이참에서는 될듯도 하는데....

델파이의 부활(Antigravity와의 만남)?

 델파이 프로그램을 사용하여 개인적으로 필요한 프로그램을 생성해 왔는데, 얼마전부터 파이썬으로 옮겨갔다.  그런데 Google 의 Antigravity를 만나고 나서 델파이에 대한 미련을 버리지 못해  제미나이가 Delphi이에 대한 학습도 엄청 했을...