HTTP로 서버에 요청하고 응답 값을 다시 dictionary로 변환하려는데 아래와 같이 제대로 변환이 안되는 문제가 발생하였다. raise JSONDecodeError("Expecting value", s, err.value) from None json.decoder.JSONDecodeError: Expecting value: line 1 column 11 (char 10) 리턴된 문자열은 다음과 같았다. "{\"status\":False}" Json.loads 함수로 Dictionary로 변환하려는데 형 변환이 제대로 안되어서 발생하는 문제로 해당 값에서 false로만 변경되면 문제가 해결된다. 이것을 해결하기 위해 아래와 같이 코드를 구성하였다. def convertBoolToLowerString(s): result = '' strings = s.split(',') for item in strings: items = item.split(':') if len(items) == 2: val = items[1].strip() if val == 'False' or val == 'True': val = val.lower() items[1] = val item = items[0] + ':' +items[1] # print(item) result = result + item + ',' if len(result) > 1: return resu...
파이썬(Python) PyQt가 테스트 및 검증 프로그램 짜기 참 좋은 것 같다. 최근 PyQt라는 것 공부하면서 실제 개발 중인 제품의 테스트 및 검증용으로 작업하고 있다. 이러면서 파... blog.naver.com 17년도에 PyQT5를 이용해 테스트 프로그램을 제작한 적이 있다. 당시에도 몇 가지 아쉬운 점을 제외하곤 상당히 만족스러웠던 기억이 있다 하지만 이 이후로 PyQT보단 쭈욱 C#을 이용한 것 같다. 뭐 특별한 이유가 있었던 것은 아니고 그냥 윈도우 어플은 C#이 가장 안정적이라는 생각 때문이었던 것 같다. PySide6는 일부 클래스명이 좀 다른 것 외에는 전반적으로 PyQT5와 사용상 큰 차이점은 느끼지 못했다. 아마도 쓰는 게 고만고만해서 그런 것이 아닐까 싶기도 하고 요 며칠 사용해 보니 오히려 작업성은 C#보다도 나은 것 같다는 생각이 든다. 고만고만한 것만 쓰고 C#도 고만고만한 윈폼만을 고집하고 있어서 그런 것이 아닐까 싶기도 하다.... 고만고만... 그리고 17년도만 해도 PyInstaller의 라이브러리 종속 문제들로 EXE 파일 만들어 배포할 때 엄청 고생했던 기억이 있는데 지금은 이것마저도 좋아져 상당한 매력을 느끼게 된 것 같다! 쓰고이!!! Electron으로 생산용 테스트 프로그램을 만들고 난 소감. 우선 Electron 프로젝트는 약 4년 전 오프라인 스터디를 잠깐 참여 한 적이 있는데 그...
위와 같이 커스텀 팝업 윈도우를 만들고 해당 윈도우를 실행 후 '저장' 혹은 '저장 안 함' 버튼을 눌러 종료할 되었을 때 부모 윈도우가 확인하는 방법이다. 우선 아래의 코드는 위에 보이는 커스텀 팝업 윈도우 코드이다. 클래스명은 Popup from PySide6.QtCore import Qt, QCoreApplication from PySide6.QtWidgets import QDialog from ui.popup import Ui_popup class Popup(QDialog, Ui_popup): def __init__(self, *args, obj=None, **kwargs): super(Popup, self).__init__(*args, **kwargs) self.setWindowFlags(Qt.FramelessWindowHint) self.ui = Ui_popup() self.ui.setupUi(self) ''' 이건 나중에 다시 얘기하기로 하고 패스! if obj is not None and isinstance(obj, PopupArgs): self.ui.lbl_title.setText(obj.title) self.ui.lbl_msg.setText(obj.msg) self.ui.btn_yes.setText(obj.yes) self.ui.btn_no.setText(obj.no) ''' self.result = False # ...
다음은 PySide6에서 윈도우 타이틀 바(Title Bar)를 없애는 코드이다. from PySide6.QtCore import Qt # <- setWindowFlag에 사용할 상수용 클래스 임포트 from PySide6.QtWidgets import QMainWindow from ui.systeminfowindow import Ui_SystemInfoWindow class SystemInfoWindow(QMainWindow, Ui_SystemInfoWindow): def __init__(self, *args, obj=None, **kwargs): super(SystemInfoWindow, self).__init__(*args, **kwargs) self.setWindowFlag(Qt.FramelessWindowHint) # <- 이 녀석이 타이틀 삭제하는 코드 self.ui = Ui_SystemInfoWindow() self.ui.setupUi(self) self.ui.btn_close.clicked.connect(self.btnClose) def btnClose(self): self.close() setWindowFlag에 FramelessWindowHint 속성을 주면 된다. 굿!
우분투에서 zip 파일을 압축 해제하려는데 아래와 같은 에러가 발생하였다. 조금 검색해 보니 몇 가지 원인이 보이는데 현재 내 상황에선 다른 OS에서 압축한 것이 압축 해제하면서 문자열 처리 등에 문제가 발생한 것으로 보였다. 해결 방법은 linux 용으로 재 압축해 압축 해제하는 방법이다. # 오류 수정 $ zip -FF 210211.zip --out 210211-2.zip -fz # 압축 해제 $ unzip 210211-2.zip 이렇게 해도 안되면 아래와 같이 파이썬 라이브러리를 이용하는 것도 좋을 것 같다. import sys from zipfile import PyZipFile for zip_file in sys.argv[1:]: pzf = PyZipFile(zip_file) pzf.extractall() 위 코드를 unz.py로 저장한다고 가정하고 아래와 같이 실행하면 된다. $ python unz.py 210211.zip https://askubuntu.com/questions/86849/how-to-unzip-a-zip-file-from-the-terminal How to unzip a zip file from the Terminal? Just downloaded a .zip file from the internet. I want to use the terminal to unzip the file. What is the...
파이썬에서 바이트 배열을 쉽게 비교하는 방법이다. in_data = bytes([0xFF, 0xFF, 0xFF]) # 배열 0xff, 0xff, 0xff in2_data = bytes([0xFF, 0xF1, 0xFF]) # 배열 0xff, 0xf1, 0xff fill_hex = bytes([0xFF, 0xFF, 0xFF]) # 배열 0xff, 0xff, 0xff print(in_data.hex() == fill_hex.hex()) # True print(in2_data.hex() == fill_hex.hex()) # False bytes 클래스는 hex() 함수를 제공한다. hex 함수는 바이트 배열을 16진수 문자열로 변환해 주는 함수인데 이것을 써서 그냥 문자열 대 문자열로 비교하면 나름 간단하게 비교를 할 수가 있다. 추가 NeuroWhAI 님께서 댓글로 알려주신 것처럼 굳이 문자열 변환 없이도 바로 비교가 가능하다. in_data = bytes([0xFF, 0x11, 0xFF]) in2_data = bytes([0xFF, 0xF1, 0xFF]) fill_hex = bytes([0xFF, 0x11, 0xFF]) print(in_data == fill_hex) print(in2_data == fill_hex) 이렇게 그냥 비교했어도 되었는데 복잡하게 돌아갔던 것 같다;;; 이렇게 쉬울 수가....
파이썬에서 위와 같은 gif를 아래와 같이 씬(frame)마다 분리시켜 저장하는 코드를 다뤄보자. 소스 코드 from PIL import Image def gif2jpg(filePath: str, trans_color: tuple): # 확장자 확인 if filePath[-3:] != 'gif': print(f'it is not gif file, {filePath[-3:]}') return # 확장자만 제거 '.gif' fileName = filePath[:-4] with Image.open(filePath) as im: # 씬 개수 확인 print(f'frame count: {im.n_frames}') for i in range(im.n_frames): # 해당 이미지 위치로 이동 im.seek(i) # RBGA로 변환 image = im.convert("RGBA") newData = [] # newData에 투명색을 제거하면서 복사 for item in image.getdata(): # 투명색이라면 if item[3] == 0: # 지정 색으로 변경 newData.append(trans_color) else: newData.append(tuple(item[:3])) # RGB 빈 이미지 생성 newImage = Image.new("RGB", im.size) # newImage에 newData 추가 newImage.putdata(n...
파이썬 배경 이미지 제거하기!! https://github.com/danielgatis/rembg GitHub - danielgatis/rembg: Rembg is a tool to remove images background. Rembg is a tool to remove images background. Contribute to danielgatis/rembg development by creating an account on GitHub. github.com 파이썬에서 rembg라는 패키지를 이용해 손쉽게 배경 이미지를 제거할 수 있다. 1. rembg 설치하기(CPU 버전) 먼저 아래의 명령으로 파이썬 패키지를 설치하자. GPU를 사용하는 버전도 있는데 그것은 위 링크에서 확인하길 바란다. CPU 버전 만으로도 충분히 잘 돌아간다. > pip install rembg 2. 테스트 이미지 준비하기 테스트를 위해 아래의 이미지를 다운로드하자. https://ko.wikipedia.org/wiki/%EB%A0%88%EB%82%98_%28%EC%9D%B4%EB%AF%B8%EC%A7%80%29#/media/%ED%8C%8C%EC%9D%BC:Lenna.png 첨부파일은 위 이미지의 원본이다. 첨부파일 Lenna.png 파일 다운로드 3. 소스코드 소스코드는 몇 줄 되지 않는다. 위에서 다운로드 한 이미지를 아래의 소스코드와 같은 곳에 두...
파이썬 - CRC-8/MAXIM 구현하기 그리고 C 언어로 구현 CRC도 다양한 종류가 있는데 다음은 CRC-8/MAXIM 을 구현한 것이다. 사용 방법은 다음과 같다. ... blog.naver.com 이전에 CRC-8/MAXIM 을 구현해 봤고 이번엔 CRC-16/MODBUS를 파이썬과 C로 작성해 봤다. crc16_table = [0x0000, 0xc0c1, 0xc181, 0x0140, 0xc301, 0x03c0, 0x0280, 0xc241, 0xc601, 0x06c0, 0x0780, 0xc741, 0x0500, 0xc5c1, 0xc481, 0x0440, 0xcc01, 0x0cc0, 0x0d80, 0xcd41, 0x0f00, 0xcfc1, 0xce81, 0x0e40, 0x0a00, 0xcac1, 0xcb81, 0x0b40, 0xc901, 0x09c0, 0x0880, 0xc841, 0xd801, 0x18c0, 0x1980, 0xd941, 0x1b00, 0xdbc1, 0xda81, 0x1a40, 0x1e00, 0xdec1, 0xdf81, 0x1f40, 0xdd01, 0x1dc0, 0x1c80, 0xdc41, 0x1400, 0xd4c1, 0xd581, 0x1540, 0xd701, 0x17c0, 0x1680, 0xd641, 0xd201, 0x12c0, 0x1380, 0xd341, 0x1100, 0xd1c1, 0xd081, 0x1040,...
CRC도 다양한 종류가 있는데 다음은 CRC-8/MAXIM 을 구현한 것이다. crc8_table = bytes([0x00, 0x31, 0x62, 0x53, 0xc4, 0xf5, 0xa6, 0x97, 0xb9, 0x88, 0xdb, 0xea, 0x7d, 0x4c, 0x1f, 0x2e, 0x43, 0x72, 0x21, 0x10, 0x87, 0xb6, 0xe5, 0xd4, 0xfa, 0xcb, 0x98, 0xa9, 0x3e, 0x0f, 0x5c, 0x6d, 0x86, 0xb7, 0xe4, 0xd5, 0x42, 0x73, 0x20, 0x11, 0x3f, 0x0e, 0x5d, 0x6c, 0xfb, 0xca, 0x99, 0xa8, 0xc5, 0xf4, 0xa7, 0x96, 0x01, 0x30, 0x63, 0x52, 0x7c, 0x4d, 0x1e, 0x2f, 0xb8, 0x89, 0xda, 0xeb, 0x3d, 0x0c, 0x5f, 0x6e, 0xf9, 0xc8, 0x9b, 0xaa, 0x84, 0xb5, 0xe6, 0xd7, 0x40, 0x71, 0x22, 0x13, 0x7e, 0x4f, 0x1c, 0x2d, 0xba, 0x8b, 0xd8, 0xe9, 0xc7, 0xf6, 0xa5, 0x94, 0x03, 0x32, 0x61, 0x50, 0xbb, 0x8a, 0xd9, 0xe8, 0x7f, 0x4e, 0x1d, 0x2c, 0x02, 0x33, ...
라즈베리파이(RaspberryPi) 제단에서 만든 MCU인 RP2040으로 제작된 RP2040-Zero라는 보드에 마이크로 파이썬으로 개발하는 방법을 다뤄볼 것이다. 관련 내용은 아래의 링크를 기반으로 작성되 었고 라즈베리파이 피고(RaspberryPi Pico)도 동일하게 동작한다. https://www.raspberrypi.com/documentation/microcontrollers/ - 목차 - 1. RP2040-Zero 마이크로 파이썬용 펌웨어 올리기 2. 마이크로 파이썬 펌웨어 확인 3. Thonny IDE 다운로드 4. Thonny 설치하기 5. Thonny 실행 확인 6. hello pi 출력하기 7. WS2812B LED 동작 예제 코드 8. 마이크로 파이썬 코드 RP2040-Zero 저장해 자동 시작하기 9. 라즈베리 파이 피코 RP2040-Zero 구입하기 1. RP2040-Zero 마이크로 파이썬용 펌웨어 올리기 먼저 RP2040에서 마이크로 파이썬을 사용하려면 마이크로 파이썬을 사용하기 위한 펌웨어가 보드에 올라가야 한다. 해당 펌웨어는 아래의 링크에서 최신 버전을 내려받을 수 있다. https://micropython.org/download/rp2-pico/rp2-pico-latest.uf2 만일 링크 접속이 안될 때는 일단 아래의 파일을 내려받자. 첨부파일 rp2-pico-20221110-unstable-v...
+ 여기서 설명하는 코드는 AWS SDK 설치 및 환경 설정이 완료되어 있다고 가정하고 진행한다.+ 애플리케이션마다 다르지만 현재 진행하는 프로젝트는 IoT 기기를 생산 시 AWS IoT 인증키를 미리 등록해 출하하는 방식으로 구성되어 있다. 이때 대량의 키를 생성해 AWS IoT Core에 등록하고 이 키 정보를 IoT 디바이스에도 넣어야 하므로 파일로 내려받아야 한다. 아래의 코드는 이러한 작업을 일괄적으로 해주는 코드이다. 파이썬에서 boto3(AWS SDK)를 이용하였다. import json import boto3 import datetime client = boto3.client('iot') # AWS ROOT CA1 rootCA1 = "\"-----BEGIN CERTIFICATE-----\nMIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsF\nADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6\nb24gUm9vdCBDQSAxMB4XDTE1MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTEL\nMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv\nb3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADgg...
파이썬에서 비동기 처리 방식 중에 하나인 코루틴(coroutine)을 사용할 때 asyncio라는 라이브러리를 이용한다. 해당 라이브러리는 파이썬 3.4부터 추가되어 별도의 설치 없이 사용이 가능하다. 아래의 링크는 ayncio에서 큐(queue)를 이용하는 예제이다. Queues — Python 3.10.2 documentation Queues Source code: Lib/asyncio/queues.py asyncio queues are designed to be similar to classes of the queue module. Although asyncio queues are not thread-safe, they are designed to be used specifically in async/await code. Note that methods of asyncio queues don’t have a timeout parameter; use asy... docs.python.org 그리고 다음 코드는 위 링크의 에제를 내가 이해한 대로 주석을 추가한 것이다. 실제 코드가 하는 일은 0.05에서 1.0 사이의 랜덤 값을 20개 생성해 큐에 넣어두고 worker라는 테스크를 3개 만들어 각각의 테스크는 루프를 돌면서 큐의 값(0.05-1.0)을 하나씩 받아 그 시간만큼 대기하는 아주 간단한 예제이다. 즉, 3개의 처리(wor...
파이썬 OpenCV에서 카메라 해상도를 변경하는 방법을 알아보자. 우선 카메라의 설정 확인 및 변경은 get, set 함수를 사용한다. 코드가 어렵지 않으니 바로 코드를 살펴보자. # opencv 라이브러리 import cv2 # 카메라 열기 cap = cv2.VideoCapture(0) # 현재 카메라 해상도 얻기 width = cap.get(cv2.CAP_PROP_FRAME_WIDTH) height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT) print('default resolution width {} height {}'.format(width, height)) # 1280x720 해상도로 변경 시도 print('set resolution width {} height {}'.format(1280, 720)) cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1280) cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 720) # 변경된 해상도 가져오기 width = cap.get(cv2.CAP_PROP_FRAME_WIDTH) height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT) print('changed resolution width {} height {}'.format(width, height)) # 600x400 해상도로 변경 시도 print('set re...
파이썬 웹 소켓(Websocket)을 연결하고 일정 시간이 지나면 자동 연결 해제되는 증상이 발생하였다. 그래서 연결 시점과 연결 해제 시점에 시간을 출력해 봤더니 약 20초 정도 있다가 무조건 연결이 해제되는 것이었다. 이와 관련된 문제 해결은 connection 시 ping_interval 옵션을 None으로 주면 해결되다는 것이다. 1006 Connection closed abnormally error with python 3.7 websockets I'm having the same problem as this github issue with python websockets: https://github.com/aaugustin/websockets/issues/367 The proposed solution isn't working for me though. The error I'm getting... stackoverflow.com ws = await websockets.connect(url, ping_interval=None) ping_interval은 주기적으로 상대방에게 ping을 보내 연결을 유지할 때 사용하는 것이라고 한다. 다만, 이 기능은 서버에서도 지원을 해야 하므로 서버에서 해당 기능을 지원하지 않는 경우 이와 같이 timeout이 발생해 연결을 해제하는 문제가 생기는 것이다. 따라서 범용으로 사용할 때는 위와 ...
websockets licence version pyversions wheel tests docs websockets is a library for building WebSocket servers and clients in Python with a focus on correctness, simplicity, robustness, and performance. Built ... websockets.readthedocs.io 파이썬에서 websocket을 다뤄보자. 여기서는 websocket 서버를 실행 후 client가 서버에 접속해 데이터를 주고받고 종료하는 아주 간단한 코드를 다룰 것이다. 1. 패키지 설치 파이썬에선 websockets라는 패키지를 지원하고 있고 3.x만 공식 지원한다고 한다. 설치 방법은 다음과 같이 pip를 이용한다. $ pip3 install websockets 쏘~ 이지 이지!! 2. 서버 코드 및 설명 # websocket은 코루틴을 사용하므로 asyncio 패키지 추가 import asyncio # websockets 패키지 추가 import websockets # 클라이언트가 연결되면 실행되는 함수 async def echo(ws): # 클라이언트가 연결되서 끊어질때 까지 무한 루프 while True: try: # 클라이언트가 보내올 메시지를 받기 위해 대기 msg = await ws.recv() #...
아래의 코드는 리눅스(Linux) 기반에서 키보드 입력을 받을 때 대기(Non Blocking) 없이 키 처리를 하는 코드이다. import sys import select import tty import termios def is_key_pushed(): # select 함수를 이용해 sys.stdin에 데이터가 들어오면 True # 데이터가 없으면 False, select 마지막 인자로 0으로 줘서 바로 리턴되가 한 것 return select.select([sys.stdin], [], [], 0) == ([sys.stdin], [], []) # stdin 설정을 임시 저장한다. old_settings = termios.tcgetattr(sys.stdin) try: # enter 없이 바로바로 반응하게 cbreak on! tty.setcbreak(sys.stdin.fileno()) while True: # 키 확인 if is_key_pushed(): # 1바이트 읽기 c = sys.stdin.read(1) # 출력 print('key: ', c) # 키보드 q가 눌리면 종료 if c == 'q': print('byebye') break finally: # stdin을 프로그램 실행 전 설정으로 되돌림 termios.tcsetattr(sys.stdin, termios.TCSADRAIN, old_settings) 코드는 그리 복잡하지...
파이썬에서 게임패드 데이터를 읽을 때 inputs이라는 패키지를 이용하면 된다. 1. 패키지 설치 > pip install inputs 2. 간단 테스트 코드 from inputs import get_gamepad #inputs 패키지에서 get_gamepad만 임포트 def main(): # 무한 루프! while 1: # gamepad 이벤트 받기 events = get_gamepad() # 이벤트들을 루프로 돌림 for event in events: # type, code, state를 출력 print(event.ev_type, event.code, event.state) if __name__ == "__main__": main() 출력값은 다음과 같다. 위 값은 파이썬 코드를 실행하고 게임패드의 왼쪽 조이스틱을 위아래로 움직여 본 것이다. 우리가 주요하게 볼 부분은 Absolute ABS_Y 100이다. Absolute는 event.ev_type이고 ABS_Y는 event.code이고 마지막 정수 event.state 변수인 것이다. 3. 추가 테스트 아래의 코드는 gamepad의 왼쪽 조이스틱 값만 출력하는 코드이다. import signal import sys import inputs ''' 키보드로 ctrl + c를 눌러 프로그램 종료하기 위한 함수 ''' def signal_handler(signal, frame): p...
# zipfile 라이브러리 import zipfile # aws 라이브러리 import boto3 # s3 정보를 file 핸들과 같이 제어하기 위한 io 라이브러리 import io # 압축 해제 후 원본 파일 삭제 설정 is_delete_zip_file = False # S3 경로가 아래와 같다면 # s3://aws-storage-cloud/tmp_storage_trash/ble_0.24.zip # 버킷 bucket = 'aws-storage-cloud' # 경로 s3_file_path = 'tmp_storage_trash/' # 최종 파일 명 zip_file = 'ble_0.24.zip' # 위 변수들을 기반으로 키 만듬 key = s3_file_path + zip_file # 압축 해제 위치 # 압축 파일 위치에 압축파일명으로 폴더 생성 후 그곳에 압축 해제 하기 위함 out_path = s3_file_path + zip_file.split('.zip')[0] + '/' def lambda_handler(event, context): # s3 client s3 = boto3.client('s3') try: # 압축해제 후 s3에 저장한 객체들 - 개수 확인용 saved_file_count = 0 # 버킷과 키정보로 객체 얻기 obj = s3.get_object(Bucket=bucket, Key=key) # 얻은 데이터를 fi...
아래의 코드는 파이썬을 이용해 STM32의 LCD 클럭의 레지스터 설정값을 찾는 코드이다. hci = 25.0 # 기준 클럭 (mhz) target_clk = 10 # 설정 클럭 (mhz) divm3_val_start = 1 divm3_val_end = 63 divn3_val_start = 4 divn3_val_end = 512 divr3_val_start = 1 divr3_val_end = 128 # divn3 허용 주파수 divn3_freq_range_start = 150 divn3_freq_range_end = 960 for divm3 in range(divm3_val_start, divm3_val_end): divm3_out = hci / divm3 for divn3 in range(divn3_val_start, divn3_val_end): divn3_out = divm3_out * divn3 if divn3_out >= divn3_freq_range_start and divn3_out <= divn3_freq_range_end: for divr3 in range(divr3_val_start, divr3_val_end): clk_out = divn3_out / divr3 if target_clk == clk_out: print('divm3:{} divn3:{} divr3:{}'.format(divm3, divn3, divr3)...