재미로 하는 찬의아빠의 일상,리뷰 블로그
TODAY TOTAL
12-21 18:39
반응형
프로그래밍/개발 팁 공유 (8)
[개발팁] 실무에 GPT 활용하기 : 실무를 넘어 일상의 효율화까지
반응형

서문

 

안녕하세요! 저는 주로 C# 개발을 하며 하루를 보내는 평범한 개발자입니다. 요즘 들어 업무 속에서 가장 많이 체감하는 기술 혁신은 바로 GPT 같은 생성형 AI의 등장입니다. 하지만 놀랍게도, 저는 GPT를 실무 코드를 작성하는 데 주로 사용하지는 않습니다.

대신, GPT는 제 업무의 '잡무'를 수월하게 해주는 조력자 역할을 톡톡히 하고 있습니다. 예를 들어 문서를 정리하거나, 반복적인 텍스트 작업을 줄이고, 머리를 식히고 싶은 순간 아이디어를 빠르게 제시해주는 등 작은 부분에서 큰 도움을 받고 있습니다.

흥미로운 점은 이런 AI 도구가 비개발자 분들에게도 아주 쉽게 적용될 수 있다는 것입니다. 그래서 이번 글에서는 GPT를 활용해 실생활이나 업무에서 작은 잡무를 해결하는 방법을 소개해보려 합니다. 개발자뿐만 아니라 누구라도 따라할 수 있는 팁들을 다룰 예정이니, 가볍게 읽어보시고 오늘부터 바로 활용해보세요!

그럼, GPT와 함께 조금 더 스마트한 하루를 만들어 볼까요?

 

본문

 

바로GPT 에게 시켜보겠습니다.

 

요구사항은 아래와 같습니다.

  • 사용자가 입력한 경로의 파일이 있는지
  • 파일의 버전 정보 출력
  • 주기적으로 갱신
  • 다음 동작시에도 이전 목록 보여주기
  • UI 프로그래밍

입니다.

 

결과

 

순식간에 117 줄 짜리 파이썬 프로그램이 완성되었습니다.

왼편이 제가 질문한 내용이고, 오른편이 그 결과물입니다.

질문은 별거 없죠?

 

이젠 Visual studio code 에 넣고 실행해 보겠습니다.

 

 

이런 UI 를 가지고 있고, Add File 을 통해 경로를 추가할 수 있고,

 

 

파일이 없는 경우에는

 

 

파일이 없어 버전 확인을 할수 없는 상태를 사용자에게 표시해 줍니다.

 

정말 놀랍지 않나요??!!

 

마무리 : GPT 를 활용한 간단한 파이썬 자동화의 힘

 

이번에 살펴본 간단한 파이썬 프로그램은 놀라운 정확도와 함께 업무 효율을 극대화하는 결과를 보여주었습니다. 특히 GPT를 활용해 반복작업을 손쉽게 자동화하는 과정은, 복잡한 개발 지식이 없어도 누구나 시도할 수 있다는 점에서 매우 매력적이죠.

그러나 여기서 가장 중요한 포인트는 GPT에게 어떻게 명령하느냐입니다. 명확하고 구체적인 지시를 통해 GPT의 잠재력을 극대화할 수 있습니다.

 

  • 정확하게 요구사항을 설명하기: 무엇을 원하고, 어떤 결과를 기대하는지 명확하게 전달해야 합니다.
  • 단계별로 명령하기: GPT는 한 번에 모든 것을 처리하는 것도 가능하지만, 단계별로 나눠서 작업을 지시하면 더 정확한 결과를 얻을 수 있습니다.
  • 검증하고 보완하기: GPT의 답변은 놀랍지만 언제나 최종 검토와 보완이 필요합니다. 이 과정을 통해 완성도 높은 결과물을 얻을 수 있습니다.

결국 GPT의 사용법은 복잡하지 않습니다. 핵심은 어떻게 적절하게 활용할지를 고민하고 작은 작업부터 실험해보는 것입니다. 단순 반복작업 하나만 해결해도 그 시간과 에너지를 더 중요한 업무에 투자할 수 있으니까요.

 

이제 여러분도 GPT를 활용해 업무의 잡무를 줄이고, 진짜 중요한 일에 집중해보세요. 놀라운 업무 효율이 바로 여러분의 손에 달려있습니다!

 

진짜 마무리

 

이 포스팅의 대부분의 글은 GPT 를 통하여 작성되었습니다.

 

GPT 의 위대함에, 그리고 그걸 만든 인류에 찬사를 보냅니다.

반응형
  Comments,     Trackbacks
[python3 & 2] 쓰레드 thread 에서 반환값 return value 얻는 방법은?
반응형

thread는 프로그램에 여러 로직 간에 동시성을 갖게 해주는 아주 중요한 요소입니다.

 

보통의 프로그램은 하나의 로직으로만 수행되지 않고 여러 로직이 동시적으로 수행되어 지게 됩니다.

 

오늘 포스팅에서는 쓰레드 thread 에서 반환값 return value 를 얻는 방법에 대하여 포스팅 하려고 합니다.


방법1.  전역번수 사용

일반적으로 쓰레드를 시작하게 되면 반환값은 없이 해당 쓰레드는 로직을 마치면 자동으로 종료되게 됩니다.

그 전에 원하는 값을 공통으로 접근 할 수 있는 변수에 저장할 수 있다면 반환값이 있는 함수처럼 사용할 수 있게 됩니다.

 

from threading import Lock
from threading import Thread

#전역변수
data_list = []
lock_for_data_list = Lock()

def some_fuction():
	#전역변수를 함수 내에서 사용하기 위하여 내부 선언
	global data_list
	data = None
    
	#some logic...
    
	#다른 쓰레드에서 접근을 막기 위한 lock
	lock_for_data_list.acquire()
	data_list.append(data)
	lock_for_data_list.release()
    
def main():
	global data_list
    
	t = Thread(target=some_function)
	t.start()
    
	t.join()
	print(data_list)
    
	return
    
if __name__ == '__main__':
	main()

위 코드에는 세가지 중요한 지점이 있습니다.

첫번째는 정보를 공유할 전역 변수 입니다. 함수 바깥쪽에 사용할 변수를 선언한 뒤, 사용할 함수 안에서 global 키워드와 함께 내부 선언을 해주시면 사용할 준비가 되게 됩니다.

 

두번째는 전역변수 공유 시, dead lock 등 오류를 발생을 방지하기 위한 Lock 입니다. 동시에 같은 데이터에 접근하게 될 경우, 프로그램에 치명적인 오류가 발생하거나 데이터가 부정확해지는 일이 발생할 수 있으므로, 한번에 한 쓰레드에서만 접근할 수 있도록 Lock() 을 사용하여 구역을 묶어 두는것이 일반적입니다.

 

세번째는 쓰레드 Thread 종료 시까지 기다릴 수 있도록 하는 join() 입니다. join() 사용 시, 해당 쓰레드의 함수가 종료될 때까지 기다리게됩니다. 

 

위 세가지 내용이 모두 위의 코드에 쓰였으니 참고 하시면 좋겠습니다.

 

방법2. Thread 클래스를 상속받아 값을 반환하는 클래스

간단하게 코드부터 소개하고 사용법을 공유하겠습니다.(python3)

from threading import Thread

class ThreadWithReturnValue(Thread):
    
    def __init__(self, group=None, target=None, name=None,
                 args=(), kwargs={}, Verbose=None):
        Thread.__init__(self, group, target, name, args, kwargs)
        self._return = None

    def run(self):
        if self._target is not None:
            self._return = self._target(*self._args,
                                                **self._kwargs)
    def join(self, *args):
        Thread.join(self, *args)
        return self._return

위에 작성된 ThreadWithReturnValue 클래스는 Thread 클래스를 상속받아 init 과 run, join 함수를 재정의 하였습니다. (출처 :

class ThreadWithReturnValue(Thread):
    def __init__(self, group=None, target=None, name=None,
                 args=(), kwargs={}, Verbose=None):
        Thread.__init__(self, group, target, name, args, kwargs, Verbose)
        self._return = None
    def run(self):
        if self._Thread__target is not None:
            self._return = self._Thread__target(*self._Thread__args,
                                                **self._Thread__kwargs)
    def join(self):
        Thread.join(self)
        return self._return

 

사용방법은 일반적인 thread 의 사용법과 모두 동일하지만 join 에 반환값이 발생하게 된다.

def foo(bar):
    print 'hello {0}'.format(bar)
    return "foo"

twrv = ThreadWithReturnValue(target=foo, args=('world!',))

twrv.start()
print twrv.join()   # prints foo

위 소개한 두가지 방법을 개념만 잘 잡고 있다면 thread 를 사용하는 것이 어렵지 않게 될 것입니다.

 

더 좋은 방법이 있다면 소개해 주시면 감사드리겠습니다^^

 

이상 포스팅 마치겠습니다.

 

찾아와 주신 모든 분들께 감사드립니다(_ _)

반응형
  Comments,     Trackbacks
[python3] 경과시간 확인 방법 & 잡설...
반응형

프로그래밍을 하다보면 로직이 얼마나 오랜 시간이 걸렸는지 또한 중요한 요인이 된다.

 

cpu 자원과 사용자의 인내력이 무한대라면 좋겠지만 그렇지 않기 때문에 무심코 지나칠 수 없기도 하다.


원래는 c# 개발자이나 이제 1년간의 달콤한 휴직기간 또한 끝나가던 차에 

hello world 프린트 하는 것도 잊어 버릴것 같아 사이드 프로젝트로 파이썬을 이용해서 크롤링 crawling 을 해보고 있었습니다.

 

python 을 처음 해봤는데 언어 자체는 간단명료하고 사용자 친화적이란 느낌을 많이 받았습니다.

ide 는 vs code 를 사용해서 그런지 visual studio 를 사용하던 기억이 있어 디버깅은 아직 익숙치가 않습니다.

 

크롤링 crawling 을 처음 해보면서 python 에는 강력한 외부 라이브러리들이 참 많다는 생각이 들었습니다.

selenium, beautifulsoup, openpyxl 등 사용하기 너무 편리한 라이브러리들이 너무 손쉽게 사용될 수 있었습니다.(라이선스는..?)

 

결론적으로는 원하는 데이터를 잘 획득할 수 있었고 그 과정에서 알게된 내용들을 잘 정리해서 공유 하고자 합니다.


경과 시간 확인 방법

time 모듈을 import 한 후, time() 함수를 이용하여 양 return 값 사이의 차를 출력하면 손쉽게 경과시간(단위: 초)을 얻을 수 있습니다.

from time import time

start = time()
#some function...
end = time()

print('총 ' + str(end - start) + '초 소요')

결과값↘️

뭔데 442초나 걸렸는지는 나중에도 설명하겠지만 대략 16배정도 시간 단축 시킨것 같습니다.

노트북에서 이정도지 데스크탑에서 실행했으면 더 줄일 수 있을 것 같습니다.^^;;


이만 간단 포스팅 마치겠습니다.

찾아오신 모든 분들꼐 감사드립니다.

반응형
  Comments,     Trackbacks
M1 Mac 에서 flutter 설치 시, flutter doctor --android-licenses 오류 종류 및 해결 방법
반응형

저와 같이 m1 mac 에서 flutter 설치 중 아래와 같은 오류 발생 시 참고 하시기 바랍니다.

 

1. 

username@machinename ~ % flutter doctor --android-licenses

The operation couldn’t be completed. Unable to locate a Java Runtime.

Please visit http://www.java.com for information on installing Java.

The operation couldn’t be completed. Unable to locate a Java Runtime.

Please visit http://www.java.com for information on installing Java.

 

해결 방법 : java 설치

 

2.

username@machinename ~ % flutter doctor --android-licenses

Exception in thread "main" java.lang.UnsupportedClassVersionError: com/android/prefs/AndroidLocationsProvider has been compiled by a more recent version of the Java Runtime (class file version 55.0), this version of the Java Runtime only recognizes class file versions up to 52.0

at java.lang.ClassLoader.defineClass1(Native Method)

at java.lang.ClassLoader.defineClass(ClassLoader.java:756)

at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)

at java.net.URLClassLoader.defineClass(URLClassLoader.java:473)

at java.net.URLClassLoader.access$100(URLClassLoader.java:74)

at java.net.URLClassLoader$1.run(URLClassLoader.java:369)

at java.net.URLClassLoader$1.run(URLClassLoader.java:363)

at java.security.AccessController.doPrivileged(Native Method)

at java.net.URLClassLoader.findClass(URLClassLoader.java:362)

at java.lang.ClassLoader.loadClass(ClassLoader.java:418)

at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:355)

at java.lang.ClassLoader.loadClass(ClassLoader.java:351)

at java.lang.Class.getDeclaredMethods0(Native Method)

at java.lang.Class.privateGetDeclaredMethods(Class.java:2701)

at java.lang.Class.privateGetMethodRecursive(Class.java:3048)

at java.lang.Class.getMethod0(Class.java:3018)

at java.lang.Class.getMethod(Class.java:1784)

at sun.launcher.LauncherHelper.validateMainClass(LauncherHelper.java:669)

at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:651)

 

해결 방법 : java 8(52) 말고 java 11(55) 설치 하세요

참고 문서 : https://www.inflearn.com/questions/53693/jar-을-실행할때-에러가-발생해요

 

jar 을 실행할때 에러가 발생해요 - 인프런 | 질문 & 답변

jar 을 실행할때 에러가 발생해요  이 에러를 어떻게 고치는지 알려주시면 감사여  C:\my_java\hello-spring\build\libs>java -jar hello-spring-0.0.1-SNAPSHOT.jar Exception in t...

www.inflearn.com

3. 

 

username@machinename ~ % flutter doctor

Doctor summary (to see all details, run flutter doctor -v):

[✓] Flutter (Channel stable, 3.7.2, on macOS 13.0.1 22A400 darwin-arm64, locale ko-KR)

[✓] Android toolchain - develop for Android devices (Android SDK version 33.0.2)

[✓] Xcode - develop for iOS and macOS (Xcode 14.2)

[✗] Chrome - develop for the web (Cannot find Chrome executable at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome)

    ! Cannot find Chrome. Try setting CHROME_EXECUTABLE to a Chrome executable.

[!] Android Studio (version 2022.1)

    Unable to find bundled Java version.

[✓] Connected device (1 available)

[✓] HTTP Host Availability

 

해결방법 : 아래 순서대로 진행

1️⃣ 안드로이드 스튜디오 우클릭 - 패키지 내용 보기

 

 

 

 

2️⃣ Contents 폴더 진입

 

 

 

 

 

3️⃣jre 폴더 생성

 

 

 

 

 

 

4️⃣ jbr 폴더 진입

 

 

 

 

 

 

5️⃣ jbr 폴더 내 Contents 폴더 복사

 

 

 

 

 

 

 

6️⃣ 생성한 jre 폴더에 복사한 Contents 폴더 붙여넣기

 

 

 

 

 

 

참고 문서 : https://github.com/flutter/flutter/issues/118502

 

Unable to find bundled Java version · Issue #118502 · flutter/flutter

Steps to Reproduce flutter doctor -v [!] Android Studio (version 2022.1) • Android Studio at /Applications/Android Studio.app/Contents • Flutter plugin can be installed from: 🔨 https://plugins.jetb...

github.com

 

반응형
  Comments,     Trackbacks
[C#][.NET framework] Directory.GetFiles() 로 여러 확장자 필터링 하기
반응형

지난번 포스팅에서 폴더 내 파일 목록을 가져오는 방법에 대해 공유 했다면

 

이번엔 복수개의 확장자로 필터링 하는 방법에 대해 포스팅 하려고 한다.



var files = Directory.EnumerateFiles("C:\\path", "*.*", SearchOption.AllDirectories)
            .Where(s => s.ToLower().EndsWith(".mp3") || s.ToLower().EndsWith(".jpg"));

위 코드와 같이 *.* 로 전체 검색 후, 경로의 마지막이 필터링 원하는 확장자인지 LINQ 를 통해 추출할 수 있다.

 

※기존엔 Directory.GetFiles() 함수를 사용했다면, 해당 함수에 '메모리 이슈'가 있다고 하여 Directory.EnumerateFiles 함수 사용을 권장한다.

 

참조 : https://stackoverflow.com/questions/163162/can-you-call-directory-getfiles-with-multiple-filters

반응형
  Comments,     Trackbacks
[C#][.Net Framework] 폴더 내 파일 목록 가져오기
반응형

이것도 역시 아이폰 사진 정리 프로그램 개발 중 알게된 팁을 공유하고자 한다.



폴더 내 파일 목록을 가져오는 방법은 'Directory.GetFiles()' 함수를 이용하면 간단하다.

 

//하위 디렉토리 포함하여 확장자가 mov 인 파일(*.mov) 목록만 조회하기
string[] path = Directory.GetFiles(SrcPath, "*.mov", SearchOption.AllDirectories);

//해당 디렉토리에서만 모든 파일(*.*) 목록 조회하기
string[] path = Directory.GetFiles(SrcPath, "*.*", SearchOption.TopDirectoryOnly);

파일 갯수에 대한 제한은 찾을수가 없었지만, 필자가 테스트 해본바로 27,000개 파일 배열도 사용 가능했다.

 

이상 간단한 팁 마치겠습니다.

반응형
  Comments,     Trackbacks