Windows Mutex for Python

Python 2025. 2. 26. 11:28 |
반응형

파이썬에서 윈도우 뮤텍스를 사용해 보자.

 

아래 링크에서 namedmutex.py를 다운받고 파이썬 프로젝트에 포함시킨다.

namedmutex

namedmutex.py
0.00MB

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import namedmutex
#from time import sleep
 
# with namedmutex.NamedMutex('MyMutex'):
#     while True:
#         sleep(1)
#         print("Running")
 
mutex = namedmutex.NamedMutex('MyMutex')
if not mutex:
    print("Mutex not created.")
    exit(-1)
 
if not mutex.acquire(2):
    print("Mutex not acquired.")
    mutex.close()
    exit(-1)
 
input("Waiting...")
 
mutex.release()
mutex.close()
 

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
using System;
using System.Threading;
 
public class Program
{
    public static void Main()
    {
        Mutex mutex = new Mutex(false"MyMutex");
        if (!mutex.WaitOne(2000))
        {
            Console.WriteLine("Signal not received.");
            mutex.Close();
            return;
        }
 
        Console.WriteLine("Waiting...");
        Console.ReadLine();
 
        mutex.ReleaseMutex();
        mutex.Close();
    }
}
 

 

위 파이썬 프로그램, C# 프로그램 중 중복을 포함하여 아무거나 두 개(두 번) 실행시켜 보면 MyMutex의 상황에 따라 실행 가능 여부를 확인 할 수 있다.

 

이번엔 뮤텍스를 사용해 프로그램의 중복 실행을 방지하는 코드를 살펴보자.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import namedmutex
 
mutex = namedmutex.NamedMutex('MyMutex')
if not mutex:
    print("Mutex not created.")
    exit(-1)
 
if not mutex.acquire(0):
    print("Program is running already.")
    mutex.close()
    exit(-1)
 
input("Waiting...")
 
mutex.release()
mutex.close()
 

 

위 프로그램을 실행한 상태에서 또  실행하면 두 번째 실행한 프로그램은 메세지가 출력되고 종료된다.

 

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

C와 Python 프로그램간 이미지 데이터를 공유해 보자.

 

1) 파이썬 프로그램 데이터를 C 프로그램에 공유

mmap

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import time
import mmap
import cv2
 
frame = cv2.imread("image.jpg", cv2.IMREAD_COLOR)
h, w, c = frame.shape
buffer_size = h * w * c
 
mm = mmap.mmap(-1, buffer_size, "Local\\MySharedMemory")
 
try:
    mm.write(frame.tobytes())
 
    while True:
        time.sleep(1000)  # Sleep to prevent busy waiting.
finally:
    mm.close()
 

 

 

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
#include <opencv2/opencv.hpp>
#include <Windows.h>
 
int main() {
    int height = 495;
    int width = 396;
    int channels = 3;
    int buffersize = height * width * channels;
 
    byte* buffer = new byte[buffersize];
    memset(buffer, 0, buffersize);
 
    HANDLE hFMap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, buffersize, L"MySharedMemory");
    if (hFMap == NULL)
        return -1;
 
    TCHAR* PtrInFile = (TCHAR*)MapViewOfFile(hFMap, FILE_MAP_ALL_ACCESS, 00, buffersize);
    if (PtrInFile == NULL)
        return -1;
 
    memcpy(buffer, PtrInFile, buffersize);
 
    cv::Mat image = cv::Mat(height, width, CV_8UC3, buffer);
    if (image.empty())
        return -1;
 
    // 사용할 Mat이 이미 존재한다면 아래처럼 memcpy()를 사용할 수도 있다.
    //cv::Mat image(height, width, CV_8UC3); // 이미 존재하는 Mat
    //memcpy(image.data, buffer, buffersize); // buffer 사용하지 않고 메모리에서 image.data로 직접 복사해도 된다.
 
    cv::imshow("image", image);
    cv::waitKey(0);
        
    UnmapViewOfFile(PtrInFile);
    CloseHandle(hFMap);
    delete[] buffer;
 
    return 0;
}
 

 

 

파이썬 프로그램을 먼저 실행하고 C 프로그램을 실행한다.

 

 

2) C 프로그램 데이터를 파이썬 프로그램에 공유

 

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
#include <opencv2/opencv.hpp>
#include <Windows.h>
 
int main() {
    cv::Mat image = cv::imread("image.jpg");
    if (image.empty())
        return -1;
 
    int height = image.rows;
    int width = image.cols;
    int channels = image.channels();
    int buffersize = height * width * channels;
 
    HANDLE hFMap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, buffersize, L"MySharedMemory");
    if (hFMap == NULL)
        return -1;
 
    TCHAR* PtrInFile = (TCHAR*)MapViewOfFile(hFMap, FILE_MAP_ALL_ACCESS, 00, buffersize);
    if (PtrInFile == NULL)
        return -1;
 
    memcpy(PtrInFile, image.data, buffersize);
    // 버퍼를 사용하지 않고 바로 메모리에 데이터 복사.
        
    int a;
    std::cin >> a;
    // 대기
 
    UnmapViewOfFile(PtrInFile);
    CloseHandle(hFMap);
    
    return 0;
}
 

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import mmap
import numpy as np
import cv2
 
height = 495
width = 396
channels = 3
buffer_size = height * width * channels
 
mm = mmap.mmap(-1, buffer_size, "Local\\MySharedMemory")
 
try:    
    buffer = mm.read(buffer_size)
    image_arr = np.frombuffer(buffer, np.ubyte)
    image = image_arr.reshape(height, width, channels)
    
    cv2.imshow("image", image)
    cv2.waitKey(0)
finally:
    mm.close()
    cv2.destroyAllWindows()
 

 

결과는 같다.

 

※ 참고

2025.02.16 - [OpenCV] - C# and Python OpenCV Image Data Share (Memory Mapped File)

 

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

C#과 Python 프로그램간 이미지 데이터를 공유해 보자.

 

1) Python 프로그램 데이터를 C# 프로그램에 공유.

mmap

 

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
import time
import mmap
import cv2
 
frame = cv2.imread("image.jpg", cv2.IMREAD_COLOR)
h, w, c = frame.shape
buffer_size = h * w * c
 
# 3개의 4바이트(12바이트) 데이터를 위한 추가 공간 확보
#buffer_size = h * w * c + 12
 
# Open a memory-mapped file.
mm = mmap.mmap(-1, buffer_size, "Local\\MySharedMemory")
 
try:
    # 만약 3개의 4바이트 데이터를 저장하고 싶다면 아래와
    # 같이 한다.
    #mm.write(h.to_bytes(4))
    #mm.write(w.to_bytes(4))
    #mm.write(c.to_bytes(4))
 
    mm.write(frame.tobytes())
    
    # Keep the Python script running for demonstration.
    while True:
        time.sleep(1000)  # Sleep to prevent busy waiting.
finally:
    mm.close()
 

 

 

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
using OpenCvSharp;
using System.IO.MemoryMappedFiles;
using System.Runtime.InteropServices;
 
public class Program
{
    public static void Main()
    {
        int width = 396;
        int height = 495;
        int channels = 3;
 
        using (MemoryMappedFile mmf = MemoryMappedFile.OpenExisting("MySharedMemory"))
        {
            using (MemoryMappedViewAccessor accessor = mmf.CreateViewAccessor())
            {
                byte[] buffer = new byte[width * height * channels];
                accessor.ReadArray(0, buffer, 0, buffer.Length);
 
                // 만약 buffer 앞 부분에 3개의 4바이트 int 데이터가 저장되어 있다면 아래와 같이 읽는다.
                // (물론 위에서 buffer[] 생성시 12바이트의 추가 공간 확보가 필요하다)
                //int h = ((buffer[0] << 24) +  (buffer[1] << 16) + (buffer[2] << 8) + (buffer[3]));
                //Console.WriteLine(h);
                //int w = ((buffer[4] << 24) + (buffer[5] << 16) + (buffer[6] << 8) + (buffer[7]));
                //Console.WriteLine(w);
                //int c = ((buffer[8] << 24) + (buffer[9] << 16) + (buffer[10] << 8) + (buffer[11]));
                //Console.WriteLine(c);
 
                // When buffer[] represents encoded image data (ex. JPEG, PNG, etc.), you can use
                // FromImageData or ImDecode.
                //buffer = System.IO.File.ReadAllBytes("image.jpg");
                //Mat mat = Mat.FromImageData(buffer, ImreadModes.Color);                
                //Mat mat = Cv2.ImDecode(buffer, ImreadModes.Color);
 
                // When buffer[] represens pixel data (BGRBGR...) , you need to hard-code copying operation.
                //Mat mat = new Mat(height, width, MatType.CV_8UC3);
                //Mat.Indexer<Vec3b> indexer = mat.GetGenericIndexer<Vec3b>();
                //for (int y = 0; y < height; y++)
                //{
                //    for (int x = 0; x < width; x++)
                //    {
                //        int pos = y * width * channels + x * channels;
                //        byte blue = buffer[pos + 0];
                //        byte green = buffer[pos + 1];
                //        byte red = buffer[pos + 2];
                //        Vec3b newValue = new Vec3b(blue, green, red);
                //        indexer[y, x] = newValue;
                //    }
                //}
 
                // If buffer[]'s step length is equal to the Mat's, there is a more effective way.
                Mat mat = new Mat(height, width, MatType.CV_8UC3);
                int length = height * width * channels;
                Marshal.Copy(buffer, 0, mat.Data, length);
 
                Cv2.ImShow("image", mat);
                Cv2.WaitKey(0);
                Cv2.DestroyAllWindows();
            }
        }
    }
}
 

 

 

Python 프로그램을 먼저 실행하고 C# 프로그램을 실행한다.

 

2) C# 프로그램 데이터를 Python 프로그램에 공유.

 

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
using System;
using System.IO.MemoryMappedFiles;
using System.Runtime.InteropServices;
using OpenCvSharp;
 
public class Program
{
    public static void Main()
    {   
        Mat image = Cv2.ImRead("image.jpg", ImreadModes.Color);
        int width = image.Width;
        int height = image.Height;
        int channels = image.Channels();
        int buffer_size = width * height * channels;
 
        using (MemoryMappedFile mmf = MemoryMappedFile.CreateNew("MySharedMemory", buffer_size))
        {
            using (MemoryMappedViewAccessor accessor = mmf.CreateViewAccessor())
            {
                byte[] buffer = new byte[buffer_size];
                Marshal.Copy(image.Data, buffer, 0, buffer_size);
                accessor.WriteArray<byte>(0, buffer, 0, buffer_size);
            }
            
            Console.WriteLine("waiting...");
            Console.ReadLine();
        }        
    }
}
 

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import mmap
import numpy as np
import cv2
 
height = 495
width = 396
channels = 3
buffer_size = height * width * channels
 
mm = mmap.mmap(-1, buffer_size, "Local\\MySharedMemory")
 
try:    
    buffer = mm.read(buffer_size)
    image_arr = np.frombuffer(buffer, np.ubyte)
    image = image_arr.reshape(height, width, channels)
    
    cv2.imshow("image", image)
    cv2.waitKey(0)
finally:
    mm.close()
    cv2.destroyAllWindows()
 

 

결과는 같다.

 

※ 참고

2025.02.23 - [OpenCV] - C and Python OpenCV Image Data Share (Memory Mapped File)

 

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

PyQt를 이용해 OpenCV 이미지를 출력해 보자.

 

디자이너에서 Dialog에 Label을 하나 배치하고 사이즈를 충분히 크게 한다. (test.ui)

 

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
import sys
import cv2
from PyQt5 import QtWidgets
from PyQt5 import QtGui
from PyQt5 import uic
 
myui = uic.loadUiType("test.ui")
 
class MyApp(QtWidgets.QWidget, myui[0]):
    def __init__(self):
        super().__init__()
        self.setupUi(self)
 
        # 1) QtWidgets.QGraphicsView()에 이미지 출력하기
        # pixmap = QtGui.QPixmap()
        # pixmap.load("palvin.jpg")
        # scene = QtWidgets.QGraphicsScene()
        # scene.addPixmap(pixmap)
        # self.graphicsView.setScene(scene)
 
        # 2) QtWidgets.QGraphicsView()에 OpenCV 이미지 출력하기
        # img = cv2.imread("palvin.jpg")
        # img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        # h, w, c = img.shape
        # qimg = QtGui.QImage(img.data, w, h, w*c, QtGui.QImage.Format_RGB888)
        # pixmap = QtGui.QPixmap.fromImage(qimg)
        # scene = QtWidgets.QGraphicsScene()
        # scene.addPixmap(pixmap)
        # self.graphicsView.setScene(scene)
 
        # QtWidgets.Label에 OpenCV 이미지 출력하기
        img = cv2.imread("palvin.jpg")
        img = cv2.resize(img, (self.label.size().width(), self.label.size().height()))
        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        h, w, c = img.shape
        qimg = QtGui.QImage(img.data, w, h, w*c, QtGui.QImage.Format_RGB888)
        pixmap = QtGui.QPixmap.fromImage(qimg)
        self.label.setPixmap(pixmap)
 
if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    myWindow = MyApp()
    myWindow.show()
   app.exec_()
 

 

소스를 입력하고 실행한다.

 

Label 사이즈에 맞게 이미지가 조절되었다.

 

이번엔 GraphicsView를 사용해 보자. 위 소스에서 1번이나 2번 주석을 해제한다.

1, 2번 주석부분의 소스는 이미지 크기를 조절하지 않는다.

 

Label은 삭제하고 Graphics View를 배치하고 크기를 조정한다.

 

이미지가 Graphics View보다 크지만 스크롤바가 표시된다.

 

Widget 없이 Dialog에 직접 이미지를 출력할 수 도 있다. Dialog만 남기고 모두 삭제한다.

 

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
import sys
import cv2
from PyQt5 import QtWidgets
from PyQt5 import QtGui
from PyQt5 import uic
 
myui = uic.loadUiType("test.ui")
 
class MyApp(QtWidgets.QWidget, myui[0]):
    def __init__(self):
        super().__init__()
        self.setupUi(self)
 
        self.img = cv2.imread("palvin.jpg")        
        self.img = cv2.cvtColor(self.img, cv2.COLOR_BGR2RGB)
        h, w, c = self.img.shape
        h, w = int(h/6), int(w/6)        
        self.img = cv2.resize(self.img, (w, h))
        self.qimg = QtGui.QImage(self.img.data, w, h, w*c, QtGui.QImage.Format_RGB888)
    
    def paintEvent(self, e):
        qp = QtGui.QPainter(self)
        self.drawCVImage(qp)
 
    def drawCVImage(self, qp):
        qp.drawImage(1010self.qimg)
        
if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    myWindow = MyApp()
    myWindow.show()
   app.exec_()
 

 

소스를 입력하고 실행한다.

 

Dialog에 직접 이미지가 출력된다.

 

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

C#에서 파이썬 스크립트를 실행해 보자.

 

1
2
3
4
5
import sys
 
print(sys.argv[0])
if len(sys.argv) > 1:
    print(sys.argv[1])
 

 

우선 위와 같은 파이썬 스크립트(script.py)를 하나 작성하고 저장한다

 

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
using System;
using System.Diagnostics;
class CSTest
{
    public static void Main()
    {
        Process process = new Process();
        process.StartInfo.FileName = "python.exe";
        process.StartInfo.Arguments = "script.py abc";
        process.StartInfo.UseShellExecute = false;
        process.StartInfo.RedirectStandardOutput = true;
        process.StartInfo.RedirectStandardError = true;
        process.StartInfo.CreateNoWindow = true;
 
        process.Start();
        process.WaitForExit();
 
        string output = process.StandardOutput.ReadToEnd();
        string error = process.StandardError.ReadToEnd();
 
        Console.WriteLine("■ Output:");
        Console.WriteLine(output);
        Console.WriteLine("■ Error:");
        Console.WriteLine(error);
    }
}
 

 

C# 코드를 작성하고 빌드한다.

 

실행하면 파이썬 스크립트의 결과가 출력된다.

 

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
using System;
using System.Diagnostics;
 
class CSTest
{
    public static void Main()
    {
        Process process = new Process();
        process.StartInfo.FileName = "cmd.exe";
        process.StartInfo.UseShellExecute = false;
        process.StartInfo.RedirectStandardOutput = true;
        process.StartInfo.RedirectStandardError = true;
        process.StartInfo.RedirectStandardInput = true;
        process.StartInfo.CreateNoWindow = true;
 
        process.Start();
        process.StandardInput.WriteLine("dir/w");
        process.StandardInput.WriteLine("time");
        process.StandardInput.Flush();
        process.StandardInput.Close();
        process.WaitForExit();
 
        string output = process.StandardOutput.ReadToEnd();
        string error = process.StandardError.ReadToEnd();
 
        Console.WriteLine("■ Output:");
        Console.WriteLine(output);
        Console.WriteLine("■ Error:");
        Console.WriteLine(error);
    }
}
 

 

파이썬 스크립트를 가상환경에서 실행해야 하거나 복잡한 명령을 차례대로 실행해야 하는 경우 위 코드처럼 cmd를 먼저 실행하고 다른 명령을 순서대로 실행한다.

 

 

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

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

 

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
:
반응형

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

 

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
:
반응형

중력이 적용된 캐릭터를 만들어 보자.

 

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
import pygame
 
pygame.init()
pygame.display.set_caption("Super fun game development")
screen = pygame.display.set_mode((640480), vsync=1)
clock = pygame.time.Clock()
FPS = 60
running = True
 
# 플레이어 클래스 with Gravity
class Player(pygame.sprite.Sprite):
    def __init__(self, position):
        pygame.sprite.Sprite.__init__(self)
 
        self.direction = -1
        self.speed = 4
        self.image = pygame.image.load("player.png").convert()
        self.image.set_colorkey(self.image.get_at((00)))
        self.size = (self.image.get_width()*1.5self.image.get_height()*1.5)
        self.image = pygame.transform.scale(self.image, self.size)
        self.rect = self.image.get_rect(center=position)
        self.isGround = False
        self.jumpForce = 0.0
        self.gravity = 5.0
 
    def flip_image(self):
        self.image = pygame.transform.flip(self.image, TrueFalse)
 
    def update(self):
        global 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
 
        keys = pygame.key.get_pressed()
        if keys[pygame.K_LEFT]:
            if self.direction > 0:
                self.flip_image()
                self.direction = -1
            self.rect.move_ip(-self.speed, 0)
        if keys[pygame.K_RIGHT]:
            if self.direction < 0:
                self.flip_image()
                self.direction = 1
            self.rect.move_ip(self.speed, 0)
        if keys[pygame.K_UP]:
            if self.isGround:
                self.jumpForce = -17
 
        if not self.isGround:
            self.rect.centery += self.gravity + self.jumpForce
            self.gravity += 0.3
        else:
            self.rect.centery += self.jumpForce
            self.gravity = 5.0
 
        if self.jumpForce < 0:
            self.jumpForce += 0.10
        elif self.jumpForce >= 0:
            self.jumpForce = 0.0
 
# 버블 클래스
class Bubble(pygame.sprite.Sprite):
    def __init__(self, position):
        pygame.sprite.Sprite.__init__(self)
 
        self.image = pygame.image.load("bubble.png").convert()
        self.image.set_colorkey(self.image.get_at((00)))
        self.size = (self.image.get_width()*6self.image.get_height()*6)
        self.image = pygame.transform.scale(self.image, self.size)
        self.rect = self.image.get_rect(center=position)
        self.collided = False
 
    def update(self):
        if self.collided == True:
            self.rect.top -= 1
 
# 그라운드 클래스
class Ground(pygame.sprite.Sprite):
    def __init__(self, position):
        pygame.sprite.Sprite.__init__(self)
 
        self.image = pygame.image.load("ground.png").convert()
        self.rect = self.image.get_rect(bottomleft=position)
         
    def update(self):
        pass
 
def main():
    player = Player((screen.get_width()/2, screen.get_height()/2))
    player_sprite = pygame.sprite.Group(player)
    # 플레이어 스프라이트 그룹
 
    bubbles = [
        Bubble((40, screen.get_height()/2)),
        Bubble((160, screen.get_height()/2)),
        Bubble((480, screen.get_height()/2)),
        Bubble((600, screen.get_height()/2))]
    bubble_sprites = pygame.sprite.Group(bubbles)
    # 버블 스프라이트 그룹
 
    grounds = [
        Ground((0480)),
        Ground((440480))]
    ground_sprites = pygame.sprite.Group(grounds)
 
    all_sprites = pygame.sprite.Group()
    all_sprites.add(player_sprite)
    all_sprites.add(bubble_sprites)
    all_sprites.add(ground_sprites)
 
    while running:
 
        #player_sprite.update()
        #bubble_sprites.update()
        all_sprites.update()
 
        collision = pygame.sprite.spritecollide(player, bubble_sprites, False)
        for bubble in collision:
            bubble.collided = True
        # 플레이어와 버블의 충돌을 감지하고 충돌한 버블의 collided 값을 True로 바꾼다.
 
        collision = pygame.sprite.spritecollide(player, ground_sprites, False)
        if len(collision) != 0:
            player.isGround = True
            player.jumpForce = 0.0
            player.rect.bottom = collision[0].rect.top
        else:
            player.isGround = False
 
        screen.fill("black")
        #player_sprite.draw(screen)
        #bubble_sprites.draw(screen)
        #ground_sprites.draw(screen)
        all_sprites.draw(screen)
 
        pygame.display.flip()
        clock.tick(FPS)
 
    pygame.quit()
 
if __name__ == '__main__':
  main()
 

 

코드를 입력하고 실행한다.

 

캐릭터에 중력이 적용되어 움직인다.

 

반응형
Posted by J-sean
: