반응형

[오픈소스 기반 데이터 분석] [딥러닝] 과목들은 기출이 없으므로 기말 대비 예상 문제를 만들어 확인해 보자.

 

 

[오픈소스 기반 데이터 분석]

방송대 오픈소스데이터분석 기말대비예상문제.pdf
0.19MB

Version: 251204

 

Pandas [Ver.251206].py
0.01MB

Pandas 사용법 간단 정리(아래 Pandas 예상 문제 소스 코드)

 

방송대 오픈소스데이터분석(Pandas) 기말대비예상문제.pdf
0.09MB

Version: 251204-1

 

 

[딥러닝]

방송대 딥러닝 기말대비예상문제.pdf
0.55MB

Version: 251209

 

 

반응형
Posted by J-sean
:
반응형

Visual Studio를 사용하다 터미널(콘솔) 창을 열어야 할 경우가 있다. Window+R - cmd 명령을 실행해 작업 경로로 이동해도 되지만 Visual Studio에서 바로 작업 경로 터미널 창을 열 수 있다.

 

View - Terminal (단축키: Ctrl+`)

 

Developer PowerShell 창이 열린다.

 

PowerShell 창에서 작업해도 되지만 원한다면 Deveoper Command Prompt로 바꿀 수 있다.

 

Options - Terminal 을 확인해 보면 Developer PowerShell이 기본으로 설정되어 있다.

 

Developer Command Prompt를 기본으로 설정한다. (Set as Default)

 

View - Terminal (단축키: Ctrl+`) 을 선택하면 Developer Command Prompt가 열린다.

 

Tools - Command Line - Developer Command Prompt / Developer PowerShell 을 선택해도 원하는 창을 바로 열 수 있다.

 

차이가 있다면 Visual Studio에서 열리는게 아닌, 독립된 창으로 열린다.

 

반응형
Posted by J-sean
:
반응형

서울 열린 데이터 광장의 공공 데이터(에코 마일리지 에너지 사용량 통계 정보)를 수집하고 분석해 보자.

 

인증키는 쉽게 발급 받을 수 있으니 알아서 하자.

 

 주의 할 점은 Open API 사용 정보에 요청인자 목록이 자세히 적혀 있어 파이썬 requests.get(url, param) 과 같은 명령으로 데이터를 불러 올 수 있을거 같지만 제대로 실행되지 않는다. url에 필요한 모든 요청인자를 넣어서 데이터를 불러와야 한다.

 

1-1. Python을 사용해 2015.01~2024.12 기간의 개인 현년 전기, 가스, 수도, 지역난방 에너지 사용량 데이터를 수집해 보자.

import requests

year_months = []  # 마지막 출력에 사용하기 위해 전역변수로 선언

def get_year_months():
    for year in range(2015, 2024+1):
        for month in range(1, 12+1):
            year_months.append(f"{year}/{month:02d}")
    return year_months

start_index = 1
end_index = 7
url1 = "http://openapi.seoul.go.kr:8088/"
url2 = f"/json/energyUseDataSummaryInfo/{start_index}/{end_index}/"
api_key = "your_api_key"

count = 0
missing = 0
responses = []

for year_month in get_year_months():
    response = requests.get(url1 + api_key + url2 + year_month)
    if response.status_code == 200:
        found = False

        for i in range(end_index):
            if response.json()['energyUseDataSummaryInfo']['row'][i]['MM_TYPE'] == '개인':
                data = []
                data.append(response.json()[
                            'energyUseDataSummaryInfo']['row'][i]['EUS'])
                data.append(response.json()[
                            'energyUseDataSummaryInfo']['row'][i]['GUS'])
                data.append(response.json()[
                            'energyUseDataSummaryInfo']['row'][i]['WUS'])
                data.append(response.json()[
                            'energyUseDataSummaryInfo']['row'][i]['HUS'])

                responses.append(data)
                found = True
                count += 1
                break

        if not found:
            missing += 1
            print(
                f"\n{response.json()['energyUseDataSummaryInfo']['row'][i]['YEAR']}/{response.json()['energyUseDataSummaryInfo']['row'][i]['MON']}: No 개인 data found.")
    else:
        print(
            f"Failed to retrieve data.\nStatus code: {response.status_code}\nReason: {response.reason}")

print(f"■ Total months with 개인 data: {count}")
print(f"■ Total months without 개인 data: {missing}\n")
for ym, row in zip(year_months, responses):
    print(f"{ym}: {row}")

 

2016년 12월 이후의 데이터는 생략

 

 

API로 받고 JSON으로 변환한 데이터 형태는 아래 '더보기'를 클릭하면 확인 할 수 있다.

더보기

{'energyUseDataSummaryInfo': {'list_total_count': 7, 'RESULT': {'CODE': 'INFO-000', 'MESSAGE': '정상 처리되었습니다'}, 'row': [{'YEAR': '2015', 'MON': '01', 'MM_TYPE': '개인', 'CNT': '767791', 'EUS': '193784708', 'EUS1': '194781915', 'EUS2': '204969429', 'ECO2_1': '-6090964', 'ECO2_2': '-2582568.736', 'GUS': '59133720', 'GUS1': '57163993', 'GUS2': '68297619', 'GCO2_1': '-3597086', 'GCO2_2': '-8057472.64', 'WUS': '12819757.886', 'WUS1': '12723680.426', 'WUS2': '12899476.73', 'WCO2_1': '8179.308', 'WCO2_2': '2715.530256', 'HUS': '22740838.937', 'HUS1': '23400055.303', 'HUS2': '27090493.875', 'HCO2_1': '-2504435.652', 'HCO2_2': '-33660084.213069', 'REG_DATE': '2015-06-04 17:03:55.0'}, {'YEAR': '2015', 'MON': '01', 'MM_TYPE': '학교', 'CNT': '1382', 'EUS': '134955565', 'EUS1': '128707423', 'EUS2': '145561511', 'ECO2_1': '-2178902', 'ECO2_2': '-923854.448', 'GUS': '9107197', 'GUS1': '8410968', 'GUS2': '10745416', 'GCO2_1': '-470995', 'GCO2_2': '-1055028.8', 'WUS': '2075819.2', 'WUS1': '2097433.8', 'WUS2': '2133200.8', 'WCO2_1': '-39498.1', 'WCO2_2': '-13113.3692', 'HUS': '0', 'HUS1': '0', 'HUS2': '0', 'HCO2_1': '0', 'HCO2_2': '0', 'REG_DATE': '2015-06-04 17:03:55.0'}, {'YEAR': '2015', 'MON': '01', 'MM_TYPE': '종교단체', 'CNT': '32', 'EUS': '372270', 'EUS1': '363376', 'EUS2': '411363', 'ECO2_1': '-15099.5', 'ECO2_2': '-6402.188', 'GUS': '53331', 'GUS1': '45727', 'GUS2': '63312', 'GCO2_1': '-1188.5', 'GCO2_2': '-2662.24', 'WUS': '5945', 'WUS1': '4548', 'WUS2': '4519', 'WCO2_1': '1411.5', 'WCO2_2': '468.618', 'HUS': '0', 'HUS1': '0', 'HUS2': '0', 'HCO2_1': '0', 'HCO2_2': '0', 'REG_DATE': '2015-06-04 17:03:55.0'}, {'YEAR': '2015', 'MON': '01', 'MM_TYPE': '소상공인', 'CNT': '2058', 'EUS': '10249618', 'EUS1': '9927610', 'EUS2': '11039593', 'ECO2_1': '-233983.5', 'ECO2_2': '-99209.004', 'GUS': '536119', 'GUS1': '523810', 'GUS2': '642921', 'GCO2_1': '-47246.5', 'GCO2_2': '-105832.16', 'WUS': '147273', 'WUS1': '146480.6', 'WUS2': '147325.6', 'WCO2_1': '369.9', 'WCO2_2': '122.8068', 'HUS': '0', 'HUS1': '0', 'HUS2': '0', 'HCO2_1': '0', 'HCO2_2': '0', 'REG_DATE': '2015-06-04 17:03:55.0'}, {'YEAR': '2015', 'MON': '01', 'MM_TYPE': '공동주택관리소', 'CNT': '1747', 'EUS': '327102096', 'EUS1': '329852334', 'EUS2': '351694752', 'ECO2_1': '-13671447', 'ECO2_2': '-5796693.528', 'GUS': '22834274', 'GUS1': '21141017', 'GUS2': '25338506', 'GCO2_1': '-405487.5', 'GCO2_2': '-908292', 'WUS': '12844807.5', 'WUS1': '12763070', 'WUS2': '12979835.8', 'WCO2_1': '-26645.4', 'WCO2_2': '-8846.2728', 'HUS': '0', 'HUS1': '0', 'HUS2': '0', 'HCO2_1': '0', 'HCO2_2': '0', 'REG_DATE': '2015-06-04 17:03:55.0'}, {'YEAR': '2015', 'MON': '01', 'MM_TYPE': '기업', 'CNT': '16751', 'EUS': '583090528', 'EUS1': '586779350', 'EUS2': '632471031', 'ECO2_1': '-26534662.5', 'ECO2_2': '-11250696.9', 'GUS': '37835680', 'GUS1': '35765271', 'GUS2': '47713673', 'GCO2_1': '-3903792', 'GCO2_2': '-8744494.08', 'WUS': '6581017', 'WUS1': '6591203.4', 'WUS2': '6684708.2', 'WCO2_1': '-56938.8', 'WCO2_2': '-18903.6816', 'HUS': '0', 'HUS1': '0', 'HUS2': '0', 'HCO2_1': '0', 'HCO2_2': '0', 'REG_DATE': '2015-06-04 17:03:55.0'}, {'YEAR': '2015', 'MON': '01', 'MM_TYPE': '공공기관', 'CNT': '2981', 'EUS': '247059373', 'EUS1': '242471579', 'EUS2': '261884067', 'ECO2_1': '-5118450', 'ECO2_2': '-2170222.8', 'GUS': '11524542', 'GUS1': '10057837', 'GUS2': '13760048', 'GCO2_1': '-384400.5', 'GCO2_2': '-861057.12', 'WUS': '1522465.2', 'WUS1': '1495786.6', 'WUS2': '1522178.8', 'WCO2_1': '13482.5', 'WCO2_2': '4476.19', 'HUS': '0', 'HUS1': '0', 'HUS2': '0', 'HCO2_1': '0', 'HCO2_2': '0', 'REG_DATE': '2015-06-04 17:03:55.0'}]}}

 

문제와는 다르지만 Pandas를 쓰면 조금 더 간단히 필터링 할 수 있다. 아래 '더보기'를 클릭하면 확인 할 수 있다.

더보기
import requests
import pandas as pd

def get_year_months():
	year_months = []
	for year in range(2015, 2024+1):
		for month in range(1, 12+1):
			year_months.append(f"{year}/{month:02d}")
	return year_months

start_index = 1
end_index = 7
url1 = "http://openapi.seoul.go.kr:8088/"
url2 = f"/json/energyUseDataSummaryInfo/{start_index}/{end_index}/"
api_key = "your_api_key"

df = pd.DataFrame()

for year_month in get_year_months():
	response = requests.get(url1 + api_key + url2 + year_month)
	if response.status_code == 200:
		data = pd.DataFrame(response.json()['energyUseDataSummaryInfo']['row'])
		data = data[data['MM_TYPE'] == '개인']
		df = pd.concat([df, data], ignore_index=True)

	else:
		print(
			f"Failed to retrieve data.\nStatus code: {response.status_code}\nReason: {response.reason}")

df = df[['YEAR', 'MON', 'EUS', 'GUS', 'WUS', 'HUS']]
print(df)

  

 

2-1. 수집한 JSON 형태의 데이터를 Pandas DataFrame으로 변환하자.

 

import requests
import pandas as pd

def get_year_months():	
	year_months = []
	for year in range(2015, 2024+1):
		for month in range(1, 12+1):
			year_months.append(f"{year}/{month:02d}")
	return year_months

start_index = 1
end_index = 7
url1 = "http://openapi.seoul.go.kr:8088/"
url2 = f"/json/energyUseDataSummaryInfo/{start_index}/{end_index}/"
api_key = "your_api_key"

df = pd.DataFrame()

for year_month in get_year_months():
	response = requests.get(url1 + api_key + url2 + year_month)
	if response.status_code == 200:
		for i in range(end_index):
			if response.json()['energyUseDataSummaryInfo']['row'][i]['MM_TYPE'] == '개인':
				data = pd.DataFrame([response.json()['energyUseDataSummaryInfo']['row'][i]])
				df = pd.concat([df, data], ignore_index=True)
				break

	else:
		print(f"Failed to retrieve data.\nStatus code: {response.status_code}\nReason: {response.reason}")

df.info()

 

 

2-2. 연도별, 계절별 분석을 위해 계절(season) 칼럼을 추가하자.

 

import requests
import pandas as pd

def get_year_months():
	year_months = []
	for year in range(2015, 2024+1):
		for month in range(1, 12+1):
			year_months.append(f"{year}/{month:02d}")
	return year_months

start_index = 1
end_index = 7
url1 = "http://openapi.seoul.go.kr:8088/"
url2 = f"/json/energyUseDataSummaryInfo/{start_index}/{end_index}/"
api_key = "your_api_key"

df = pd.DataFrame()

for year_month in get_year_months():
	response = requests.get(url1 + api_key + url2 + year_month)
	if response.status_code == 200:
		for i in range(end_index):
			if response.json()['energyUseDataSummaryInfo']['row'][i]['MM_TYPE'] == '개인':
				data = pd.DataFrame(
					[response.json()['energyUseDataSummaryInfo']['row'][i]])
				df = pd.concat([df, data], ignore_index=True)
				break
	else:
		print(f"Failed to retrieve data.\nStatus code: {response.status_code}\nReason: {response.reason}")

df['SEASON'] = df['MON'].apply(lambda x: '겨울' if x in ['01', '02', '12'] else (
	'봄' if x in ['03', '04', '05'] else ('여름' if x in ['06', '07', '08'] else '가을')))

print(df)

 

 

 

3-1. 연도별 에너지 총사용량(전기+가스+수도+지역난방) 변화량을 선 그래프로 시각화 하자.

 

import requests
import pandas as pd
import matplotlib.pyplot as plt

def get_year_months():
	year_months = []
	for year in range(2015, 2024+1):
		for month in range(1, 12+1):
			year_months.append(f"{year}/{month:02d}")
	return year_months

start_index = 1
end_index = 7
url1 = "http://openapi.seoul.go.kr:8088/"
url2 = f"/json/energyUseDataSummaryInfo/{start_index}/{end_index}/"
api_key = "your_api_key"

df = pd.DataFrame()

for year_month in get_year_months():
	response = requests.get(url1 + api_key + url2 + year_month)
	if response.status_code == 200:
		for i in range(end_index):
			if response.json()['energyUseDataSummaryInfo']['row'][i]['MM_TYPE'] == '개인':
				data = pd.DataFrame(
					[response.json()['energyUseDataSummaryInfo']['row'][i]])
				df = pd.concat([df, data], ignore_index=True)
				break
	else:
		print(f"Failed to retrieve data.\nStatus code: {response.status_code}\nReason: {response.reason}")

df['SEASON'] = df['MON'].apply(lambda x: '겨울' if x in ['01', '02', '12'] else (
	'봄' if x in ['03', '04', '05'] else ('여름' if x in ['06', '07', '08'] else '가을')))

df = df.astype({'EUS': 'float', 'GUS': 'float','WUS': 'float', 'HUS': 'float'})

year_group = df.groupby('YEAR')[['EUS', 'GUS', 'WUS', 'HUS']].sum().reset_index()
year_group['에너지 총사용량'] = year_group[['EUS', 'GUS', 'WUS', 'HUS']].sum(axis=1)

plt.rc('font', family='GULIM')
plt.plot(year_group['YEAR'], year_group['에너지 총사용량'], marker='o', color='red')
plt.xlabel('연도')
plt.ylabel('에너지 사용 총액')
plt.title('연도별 에너지 사용 총액 변화')
plt.show()

 

 

3-2. 계절별 가스 사용량 평균을 막대 그래프로 시각화 하고 각 막대의 수치를 표시하자.

 

import requests
import pandas as pd
import matplotlib.pyplot as plt

def get_year_months():
	year_months = []
	for year in range(2015, 2024+1):
		for month in range(1, 12+1):
			year_months.append(f"{year}/{month:02d}")
	return year_months

start_index = 1
end_index = 7
url1 = "http://openapi.seoul.go.kr:8088/"
url2 = f"/json/energyUseDataSummaryInfo/{start_index}/{end_index}/"
api_key = "your_api_key"

df = pd.DataFrame()

for year_month in get_year_months():
	response = requests.get(url1 + api_key + url2 + year_month)
	if response.status_code == 200:
		for i in range(end_index):
			if response.json()['energyUseDataSummaryInfo']['row'][i]['MM_TYPE'] == '개인':
				data = pd.DataFrame(
					[response.json()['energyUseDataSummaryInfo']['row'][i]])
				df = pd.concat([df, data], ignore_index=True)
				break
	else:
		print(f"Failed to retrieve data.\nStatus code: {response.status_code}\nReason: {response.reason}")

df['SEASON'] = df['MON'].apply(lambda x: '겨울' if x in ['01', '02', '12'] else (
	'봄' if x in ['03', '04', '05'] else ('여름' if x in ['06', '07', '08'] else '가을')))

df = df.astype({'GUS': 'float'})
season_group = df.groupby('SEASON')['GUS'].mean().reset_index()

plt.rc('font', family='GULIM')
plt.bar(season_group['SEASON'], season_group['GUS'])
plt.xlabel('계절')
plt.ylabel('가스 사용량 평균')
plt.title('계절별 가스 사용량 평균')
plt.bar_label(plt.gca().containers[0])
plt.show()

 

 

 

4. 연도별 에너지 사용량 변화에서 나타나는 주요 트랜드를 찾아 분석하고 그 원인을 추론해 보자.

 

import requests
import pandas as pd
import matplotlib.pyplot as plt

def get_year_months():
	year_months = []
	for year in range(2015, 2024+1):
		for month in range(1, 12+1):
			year_months.append(f"{year}/{month:02d}")
	return year_months

start_index = 1
end_index = 7
url1 = "http://openapi.seoul.go.kr:8088/"
url2 = f"/json/energyUseDataSummaryInfo/{start_index}/{end_index}/"
api_key = "your_api_key"

df = pd.DataFrame()

for year_month in get_year_months():
	response = requests.get(url1 + api_key + url2 + year_month)
	if response.status_code == 200:
		for i in range(end_index):
			if response.json()['energyUseDataSummaryInfo']['row'][i]['MM_TYPE'] == '개인':
				data = pd.DataFrame(
					[response.json()['energyUseDataSummaryInfo']['row'][i]])
				df = pd.concat([df, data], ignore_index=True)
				break
	else:
		print(f"Failed to retrieve data.\nStatus code: {response.status_code}\nReason: {response.reason}")

df = df.astype({'EUS': 'float', 'GUS': 'float','WUS': 'float', 'HUS': 'float'})

year_group = df.groupby('YEAR')[['EUS', 'GUS', 'WUS', 'HUS']].sum().reset_index()
year_group['에너지 총사용량'] = year_group[['EUS', 'GUS', 'WUS', 'HUS']].sum(axis=1)

plt.rc('font', family='GULIM')
plt.bar(year_group['YEAR'], year_group['에너지 총사용량'], color='blue', alpha=0.5, label='총사용량')
plt.plot(year_group['YEAR'], year_group['EUS'], color='red', marker='o', label='전기')
plt.plot(year_group['YEAR'], year_group['GUS'], color='green', marker='o', label='가스')
plt.plot(year_group['YEAR'], year_group['WUS'], color='orange', marker='o', label='수도')
plt.plot(year_group['YEAR'], year_group['HUS'], color='purple', marker='o', label='난방')

plt.legend(loc='upper left')
plt.xlabel('연도')
plt.ylabel('에너지 사용량 X 1e9')
plt.ylim(0, 5000000000)

plt.grid(True, axis='y', alpha=0.5)
plt.title('연도별 에너지 사용량 변화')
plt.show()

 

 

 연도별 에너지 사용량 변화 원인을 추론하고 트렌드를 찾기 조금 더 자세한 그래프를 그려 보았다. 기후변화나 에너지 요금 등의 다양한 요인들로 인해...

이하 생략.

 

반응형
Posted by J-sean
:
반응형

비주얼 스튜디오에서 코드를 자동 완성 시켜주는 기능을 사용해 보자.

 

 

 

 

 

 

 

※ 참고

Visual Studio IntelliCode

 

반응형
Posted by J-sean
:
반응형

Visual Studio Debugging Breakpoint

 

Use the right type of breakpoint

 

 

Log to Output window

 

 

반응형
Posted by J-sean
:
반응형

 PDF파일을 인쇄하다 보면 종종 몇 페이지 되지도 않는 작은 문서인데 한 페이지 인쇄에 몇 분씩 걸리는 경우가 있다.

 하루 종일 걸리는 PDF 파일 인쇄를 해결해 보자.

 

1MB도 되지 않는 작은 문서다. 하지만 인쇄하면 한 페이지에 5분씩 걸리는거 같은 느낌이다.

 

프린터 상태를 확인해 보면 파일 크기가 23.5MB로 늘어나 있는걸 볼 수 있다.

 

프린트를 중지하고 '인쇄' - '고급' 을 클릭한다.

 

'이미지로 인쇄'를 선택하고 확인을 클릭한다.

 

 이제 다시 프린트하면 빠르게 진행된다.

 

반응형
Posted by J-sean
:
반응형

기본 정렬 알고리즘 세 가지(퀵, 머지, 힙)를 파이게임(Pygame)으로 시각화 해 보자.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
import os
import random
os.environ['PYGAME_HIDE_SUPPORT_PROMPT'= '1'
import pygame
from math import ceil, floor
 
pygame.init()
pygame.display.set_caption("Sorting Visualization")
screensize = (640580)
screen = pygame.display.set_mode(screensize)
clock = pygame.time.Clock()
framerate = 10
running = True
 
font = pygame.font.Font(None30)
text = font.render("Sorting Visualization\n\n" +
                   "*q: Quick Sorting [ O(nlogn) ]\n" +
                   "*m: Merge Sorting [ O(nlogn) ]\n" +
                   "*h: Heap Sorting [ O(nlogn) ]\n" +
                   "\n*g: Random Data Generation"True"gray")
text_pos = text.get_rect()
text_pos.center = (screen.get_width()/2, text_pos.height/2)
 
data_size = 64
data = list()
data_color = list()
 
def DataGenerator():
    global data
    global data_color
    
    data = [random.randint(10400for i in range(data_size)]
    data_color = [(random.randint(0255), random.randint(0255), random.randint(0255))
                  for i in range(data_size)]
    
DataGenerator()
 
def Visualize():
    screen.fill("black")
    screen.blit(text, text_pos)
    for i in range(data_size):
        pygame.draw.rect(screen, data_color[i], (i*10, screensize[1]-data[i], 10, data[i]))
    pygame.display.flip()
    clock.tick(framerate)
 
def Finalize():
    screen.fill("white")
    pygame.display.flip()
    clock.tick(framerate)
 
def EventHandler():
    for event in pygame.event.get():
        if event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
            return -1
        elif event.type == pygame.QUIT:
            exit()
 
def QuickSort(start, end):
    if start >= end:
        return
    pivot = start
    left = start + 1
    right = end
    
    while left <= right:
        if EventHandler() == -1:
            return
        
        while left <= end and data[left] <= data[pivot]:
            left += 1
        while right > start and data[right] >= data[pivot]:
            right -= 1            
        if left > right:
            data[right], data[pivot] = data[pivot], data[right]
            data_color[right], data_color[pivot] = data_color[pivot], data_color[right]
        else:
            data[left], data[right] = data[right], data[left]
            data_color[left], data_color[right] = data_color[right], data_color[left]
            
        Visualize()
            
    QuickSort(start, right-1)
    QuickSort(right+1, end)
 
def MergeSort_1(data_list, color_list):
    if len(data_list) < 2:        
        return data_list, color_list
    
    mid = len(data_list) // 2
    low_data_list, low_color_list = MergeSort_1(data_list[:mid], color_list[:mid])
    high_data_list, high_color_list = MergeSort_1(data_list[mid:], color_list[mid:])
    
    merged_data_list = list()
    merged_color_list = list()
    l = h = 0
    while l < len(low_data_list) and h < len(high_data_list):
        if low_data_list[l] < high_data_list[h]:
            merged_data_list.append(low_data_list[l])
            merged_color_list.append(low_color_list[l])
            l += 1
        else:
            merged_data_list.append(high_data_list[h])
            merged_color_list.append(high_color_list[h])
            h += 1
            
    merged_data_list += low_data_list[l:]
    merged_color_list += low_color_list[l:]
    
    merged_data_list += high_data_list[h:]
    merged_color_list += high_color_list[h:]
    
    return merged_data_list, merged_color_list
 
def MergeSort_2():
    def sort(low, high):
        if EventHandler() == -1:
            return
        
        if high - low < 2:
            return
        
        mid = (low + high) // 2
        sort(low, mid)
        sort(mid, high)
        merge(low, mid, high)
 
    def merge(low, mid, high):
        data_temp = list()
        color_temp = list()
        l, h = low, mid
        
        while l < mid and h < high:
            if data[l] < data[h]:
                data_temp.append(data[l])
                color_temp.append(data_color[l])
                l += 1
            else:
                data_temp.append(data[h])
                color_temp.append(data_color[h])
                h += 1
                
        while l < mid:
            data_temp.append(data[l])
            color_temp.append(data_color[l])
            l += 1
            
        while h < high:
            data_temp.append(data[h])
            color_temp.append(data_color[h])
            h += 1
            
        for i in range(low, high):
            data[i] = data_temp[i - low]
            data_color[i] = color_temp[i - low]
            
            Visualize()            
 
    sort(0, data_size)
 
def HeapSort():
    for i in range(len(data)):
        par = ceil(i/2- 1
        while par >= 0 and data[par] < data[i]:
            data[par], data[i] = data[i], data[par]
            data_color[par], data_color[i] = data_color[i], data_color[par]
            i = par
            par = floor((i-1)/2)
 
    for i in range(len(data)-10-1):
        data[0], data[i] = data[i], data[0]
        data_color[0], data_color[i] = data_color[i], data_color[0]
 
        cur = 0
        lch = 1
        rch = 2
        
        while True:
            if EventHandler() == -1:
                return
        
            if rch < i and data[lch] < data[rch]:
                lch = rch
                
            if lch < i and data[lch] > data[cur]:
                data[lch], data[cur] = data[cur], data[lch]
                data_color[lch], data_color[cur] = data_color[cur], data_color[lch]
                
                Visualize()
                
                cur = lch
                lch = cur * 2 + 1
                rch = cur * 2 + 2
            else:
                lch = i # break와 같은 효과
                
            if not lch < i:
                break
            
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
            running = False
        elif event.type == pygame.KEYDOWN and event.key == pygame.K_q:
            QuickSort(0, data_size - 1)
            Finalize()
        elif event.type == pygame.KEYDOWN and event.key == pygame.K_m:
            MergeSort_2()
            Finalize()
        elif event.type == pygame.KEYDOWN and event.key == pygame.K_n:
            data, data_color = MergeSort_1(data, data_color)
            Finalize()
        elif event.type == pygame.KEYDOWN and event.key == pygame.K_h:
            HeapSort()
            Finalize()
        elif event.type == pygame.KEYDOWN and event.key == pygame.K_g:
            DataGenerator()
            
   Visualize()
 

 

코드를 작성하고 실행한다.

 

 

※ 참고

2024.03.09 - [Python] - [Pygame] Sorting Algorithms in Python 파이썬 정렬 알고리즘 1

 

알고리즘_05_강의록.pdf
3.91MB
알고리즘_04_강의록.pdf
1.86MB

 

 

 

반응형
Posted by J-sean
:
반응형

기본 정렬 알고리즘 네 가지(선택, 버블, 삽입, 셸)를 파이게임(Pygame)으로 시각화 해 보자.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
import os
import random
os.environ['PYGAME_HIDE_SUPPORT_PROMPT'= '1'
import pygame
 
pygame.init()
pygame.display.set_caption("Sorting Visualization")
screensize = (640580)
screen = pygame.display.set_mode(screensize)
clock = pygame.time.Clock()
framerate = 10
running = True
 
font = pygame.font.Font(None30)
text = font.render("Sorting Visualization\n\n" +
                   "*s: Selection Sorting [ O(n^2) ]\n" +
                   "*b: Bubble Sorting [ O(n^2) ]\n" +
                   "*i: Insertion Sorting [ O(n^2) ]\n" +
                   "*h: Shell Sorting [ O(n^2) ]\n" +
                   "\n*g: Random Data Generation"True"gray")
text_pos = text.get_rect()
text_pos.center = (screen.get_width()/2, text_pos.height/2)
 
data_size = 64
data = list()
data_color = list()
 
def DataGenerator():
    global data
    global data_color
    
    data = [random.randint(10400for i in range(data_size)]
    data_color = [(random.randint(0255), random.randint(0255), random.randint(0255))
                  for i in range(data_size)]
    
DataGenerator()
 
def Visualize():
    screen.fill("black")
    screen.blit(text, text_pos)
    for i in range(data_size):
        pygame.draw.rect(screen, data_color[i], (i*10, screensize[1]-data[i], 10, data[i]))
    pygame.display.flip()
    clock.tick(framerate)
 
def Finalize():
    screen.fill("white")
    pygame.display.flip()
    clock.tick(framerate)
 
def EventHandler():
    # 이벤트 처리하는 코드가 없으면 정렬시 프로그램이 freeze된다.
    for event in pygame.event.get():            
        if event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
            return -1 # 정렬 중지.
        elif event.type == pygame.QUIT:
            exit() # 프로그램 종료.
 
def SelectSort():
    for i in range(data_size-1):        
        if EventHandler() == -1:
            return
        
        min = i
        for j in range(i+1, data_size, 1):
            if data[min] > data[j]:
                min = j
        data[i], data[min] = data[min], data[i]        
        data_color[i], data_color[min] = data_color[min], data_color[i]
 
        Visualize()
    Finalize()
 
def BubbleSort(): 
    for i in range(data_size-1):
        if EventHandler() == -1:
            return
        
        sorted = True
        for j in range(data_size-1-i):
            if data[j] > data[j+1]:
                data[j], data[j+1= data[j+1], data[j]
                data_color[j], data_color[j+1= data_color[j+1], data_color[j]
                sorted = False
        if sorted == True:
            break
        
        Visualize()
    Finalize()
 
def InsertSort(): 
    for i in range(1, data_size, 1):
        if EventHandler() == -1:
            return
        
        val = data[i]
        colval = data_color[i]
        for j in range(i, 0-1):
            if data[j-1> val:
                data[j] = data[j-1]
                data_color[j] = data_color[j-1]
                j = j-1
            else:
                break
        data[j] = val
        data_color[j] = colval
        
        Visualize()
    Finalize()
    
def ShellSort():
    # 점화식 리스트 만들기
    recurrence = [1]
    while(True):
        next = recurrence[-1]*3+1
        if next < data_size:
            recurrence.append(next)
        else:
            recurrence.reverse()
            break
        
    for D in recurrence:
        for i in range(D, data_size, 1):
            if EventHandler() == -1:
                return
 
            val = data[i]
            colval = data_color[i]
            j = i
            while True:
                if j>=and data[j-D]>val:
                    data[j] = data[j-D]
                    data_color[j] = data_color[j-D]
                    j = j-D
                else:
                    break
            data[j] = val
            data_color[j] = colval
 
            Visualize()
    Finalize()
                
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
            running = False
        elif event.type == pygame.KEYDOWN and event.key == pygame.K_s:
            SelectSort()
        elif event.type == pygame.KEYDOWN and event.key == pygame.K_b:
            BubbleSort()
        elif event.type == pygame.KEYDOWN and event.key == pygame.K_i:
            InsertSort()
        elif event.type == pygame.KEYDOWN and event.key == pygame.K_h:
            ShellSort()
        elif event.type == pygame.KEYDOWN and event.key == pygame.K_g:
            DataGenerator()
            
   Visualize()
 

 

코드를 작성하고 실행한다.

 

 

※ 참고

2024.03.22 - [Python] - [Pygame] Sorting Algorithms in Python 파이썬 정렬 알고리즘 2

 

알고리즘_03_강의록.pdf
1.02MB
알고리즘_04_강의록.pdf
1.86MB

 

 

반응형
Posted by J-sean
: