반응형

주말에 인생 첫 마라톤 하프를 완주했다. 1시간 57분 기록이 나왔다.

 

연습량에 비해 기록이 너무 좋게 나와서 오히려 더 아쉽다

 

한 달간 총 5km 씩 총 10번 뛰었고, 10km 마라톤 대회를 참여했다. 5km 를 달릴 때는 30~40분 정도 뛰었다. 

 

10분씩 점진적으로 운동량을 늘려서 100분 까지 뛰어보는 훈련을 했더라면 결과는 더 좋았을 것 같다.

 

아쉬움이 크지만, 그래도 완주를 했다는 사실이 그 동안 채우지 못했던 성취감을 만족시켰다. 

 

인생사가 모두 마라톤과 비슷하다. 미리 꾸준히 준비한다면, 목표한 바를 얻을 수 있다.

 

알면서도 실천하기 힘든 게 문제지.. 

 

 

반응형
반응형

1.문제 소개

 

2.코드



def solution():
    n = int(input().strip())
    for i in range(n):
        a ,b  = map(int,input().split(" "))
        x = a
        number_rules = []
        number_rules += [x%10]
        
        # 1의 자리 숫자의 규칙을 찾기 위한 루프
        for i in range(10):
            x = x * a
            x = x % 10
            number_rules += [x%10]


        # 중복을 제거하고 순서를 보장하기 위한 리스트로 전처리
        distinct_rules = []
        for v in number_rules:
            if v not in distinct_rules:
                distinct_rules.append(v)


        # 결과의 위치를 구하기
        idx = b % len(distinct_rules) -1

        # 0번의 경우 10번 컴퓨터를 의미하므로 정답 출력 보정
        if distinct_rules[idx] == 0:
            answer = 10
        else:
            answer = distinct_rules[idx]
        print(answer)



if __name__ == '__main__':
    solution()

 

3.코멘트

  • 브론즈 문제임에도 단순하게 푼다면 시간 제한에 걸릴 수 있다.
  • a**b 의 범위가 10억 대 범위라서, 반복문으로 구현했다가는 시간제한에 걸린다. 
  • 컴퓨터 번호 이하의 숫자를 pow 연산 범위 안에서 발생하는 규칙을 구한 다음, 정답 인덱스를 구해서 출력했다.
반응형
반응형

 

1.문제 소개

 

2.코드

# Main Idea
# 1) 입력 테스트 케이스의 데이트 문자열 타입을 처리하기 편한 초 단위로 변환
# 2) 점수를 낸 로그를 반복문으로 돌면서, 점수를 낸 직전 스코어의 승자 팀이 있는 경우 1팀과 2팀의 이긴 시간을 누적 저장
# 3) 마지막에는 승팀의 존재 여부를 확인하고, 이긴 시간을 추가 보정

# 입력 데이터 파싱
def set_test_case():
    n = int(input())
    score_log = []
    for i in range(n):
        input_str= input().split(" ")
        team = int(input_str[0])
        score_time_str = input_str[1].split(":")
        minutes = int(score_time_str[0])
        seconds = int(score_time_str[1])

        total_seconds = minutes * 60 + seconds
        score_log += [[team,total_seconds]]

    return score_log
def get_winner(a_score,b_score):
    return 0 if a_score > b_score else 1

def get_format_answer(seconds):
    minutes = seconds //60
    seconds = seconds % 60
    return f"{minutes:02d}:{seconds:02d}"
def solution():
    score_log  = set_test_case()
    current_score = [0,0] # 1, 2팀의 누적 점수
    last_winner = -1
    answer = [0,0] # 1,2 팀의 정답출력을 위한 리스트

    for idx,t in enumerate(score_log):

        # 이전 스코어가 동점이 아닌경우 계산
        if current_score[0] != current_score[1] :
            last_winner = get_winner(current_score[0], current_score[1])
            answer[last_winner] += t[1]-score_log[idx-1][1]

        # 누적 점수 저장
        if t[0] == 1:
            current_score[0] +=1
        else:
            current_score[1] +=1

    if current_score[0] != current_score[1]:
        last_winner = get_winner(current_score[0], current_score[1])
        answer[last_winner] += 60*48 - score_log[-1][1]

    print(get_format_answer(answer[0]))
    print(get_format_answer(answer[1]))

if __name__=='__main__':
    solution()

3.코멘트

  • 승팀을 구하기 위해 점수를 누계하는 순서가 중요했다. 
  • 최근 러닝을 하고 있는데 뛰다가 멈추면 다시 뛰기 힘들다. 알고리즘 스터디도 마찬가지였다. 안 하면 까먹는다. 
 
 
반응형
반응형

최근 커뮤니티에서 Ollama 라는 로컬에 LLM 을 쉽게 번들링 해주는 도구를 알게 되서, 호기심에 설치해봤다. 

 

쉽게 얘기해서 ChatGPT 와 같은 언어 모델을 내 컴퓨터에 로컬로 설치해서 사용하는 것이다.

 

장점이라고 한다면 오프라인으로 오픈소스 LLM(대규모 언어 모델)을 무료로 사용할 수 있고, 데이터 유출이 되지 않기 때문에 보안성이 높을 것이다. 

단점은 뭐 상용 모델보다는 답변의 퀄리티, 속도, 최신화된 정보의 답변을 받을 수 없다는 것들이 있을 수 있겠다.

 

ollama 를 설치하는 것만으로도 LLM 을 사용할 수 있다. 하지만 나는 웹 기반의 UI 가 익숙하므로 오픈 소스 open-webui 를 이용해 설치해봤다.

 

ollama 는 여기 https://github.com/ollama/ollama open-webui 는 여기에 자세한 가이드가 나와있다.

https://github.com/open-webui/open-webui

 

GitHub - open-webui/open-webui: User-friendly WebUI for LLMs (Formerly Ollama WebUI)

User-friendly WebUI for LLMs (Formerly Ollama WebUI) - open-webui/open-webui

github.com

 

관심있어 하는 분들이 있을 것 같아, 퀵스타트 구축을 포스팅해보겠다.

 

 

1. 사전 준비

  • Docker 가 설치된 환경
  • Mac , Linux 기반 환경

2. Set Up 


# set dir for volume mount
mkdir data
mkdir open-webui

# image pull and docker run
docker run -d -p 3000:8080 -v data:/root/.ollama -v open-webui:/app/backend/data --name open-webui --restart always ghcr.io/open-webui/open-webui:ollama

실행 과정
컨테이너가 실행을 확인

 

http://localhost:3000 접속

 

3. Model Import

모델 추가 및 다운로딩 과정

 

여러 특징에 맞게 학습된 모델들이 있을 것이다. 목적에 맞게 모델을 선택하면 되고, 중요한 것은 컴퓨터 사양이 받쳐줘야 한다. ( 내 경우에는 일부 모델이 실행되지 않았다.. 노트북 사고 싶다.. ) 

 

4. Test

간단하게 버블 정렬을 구현한 파이썬 코드를 보여달라고 해봤다.

 

배치 크기나 토큰 크기도 조절이 가능하다.

 

 

5.마무리

오픈 소스다 보니 사용자들이 학습한 모델을 올릴 수 있고, 공유할 수 가 있다. 컴퓨터 사양이 좋거나 GPU 가 있으면, 이미지 생성도 가능하다. 

 

https://openwebui.com/#open-webui-community

 

 

오늘은 여기까지.. 

 

끝.

 

 

 

 

 
 
반응형
반응형
 

회사에서 AWS SA 분들과 함께 진행했던 프로젝트가 있었다. 4개월 넘게 함께 진행하면서, 재미도 있었지만, 솔직히 너무 많이 힘들었었는데 다행이 효과와 개선점이 있었다.   

 

나는 그 프로젝트의 경험을 소중히 생각한다.

어떻게 보면 AWS는 내게는 월클이라.. 수준 높은 전문가들과 일을 함께 해보니 그들이 협업하는 태도, 전문 기술과 배경지식들, 그리고 이슈를 해결하는 방식들이 나를 놀라게 했다.

그리고 나도 그런 순간들을 함께 경험하면서 조금은 성장했다고 생각한다. 

 

7월즈음에 SA IH님이 AWS innovate 행사에 노미네이트 해보자고 제안해 주셔서, 일단 오케이 했는데 운이 좋게 발표 할 수 있게 됐다. (음.. IH님은 정말 .. 교수님 같은 인자한 느낌을 주는 좋은 분이다.)

 

발표는 프로젝트 진행에 큰 도움을 주셨던 YH님과 함께 하게 됐는데, YH님은 내가 스스로 해결하기 힘든 이슈가 있을 때, 먼저 찾게 되는 개발자이자 쿠버네티스 전문가다. 

 

준비 시간이 매주 짧았었는데, JH님과 YH님 덕분에 제 시간에 마무리 할 수 있었다.

(음.. JH님은 우리 회사 담당 SA 분이시면서, 개발과 PM 을 정말 잘 하시는 분이다. )

 

사실 컨퍼런스에서 발표해 보는 건 내 여러 목표 중 하나였다. 이번이 온라인 발표긴 해도, 다음에 혹시 있을 오프라인 발표에 필요한 경험과 준비를 했다고 생각하자.

 

발표 주제는 빅데이터 플랫폼의 워크로드를 쿠버네티스로 이전한 내용 중 EMR on EKS 부분들을 다뤘다. (더 담고 싶은 내용은 많았지만..)

 

서비스 소개와 기능과 같은 일반적인 내용보다는 실무적인 팁의 내용을 많이 담으려고 노력했다. 

 

비슷한 작업을 하고 있는 데이터엔지니어가 있다면 도움이 되길 바란다.

 

참고 - https://aws.amazon.com/ko/events/aws-innovate/apj/migrate-modernize-build/

 

 

 

ps..프로젝트 대부분을 함께 진행했던 최애 동료 SYAN 에게는 혼자 발표해서 너무 미안.. 다음에 함께.. 

반응형
반응형

 

1.문제 소개

 

 

2.코드

# Main Idea :
# 	- 정답을 편하게 구하기 위해 자료구조를 만든다
# 		(lt,height)
# 		* lt = 왼쪽 방향으로 키가 큰 사람 수 
# 		* height = 키 
# 	- lt,height 순서로 정렬 한다.
# 	- 정답 배열을 만든다
# 	- 정답 배열에 lt 조건 대로 height 를 저장한다
# 	- lt 조건에 맞는지 체크하면서, 정답 배열에 들어갈 위치(cursor)를 구한다.
# 	- 정답 배열에 원소 추가
# 		- 위치(cursor) 기준으로 오른쪽 배열 복제.
# 		- 정답배열 위치(cursor)에 원소를 추가하고 + 오른 쪽 배열 복제본 복사 

def set_test_case():
    n = int(input())
    input_str = input().split(" ")
    arr = []
    input_str = list(map(int,input_str))
    for i,v in enumerate(input_str):
        arr += [(v,(i+1))]

    return arr

def solution():
    # 테스트 케이스 입력
    arr = set_test_case()

    # 왼쪽 방향 자기보다 키 큰 사람의 수 기준으로 정렬
    sorted_arr = sorted(arr, key=lambda x: x[1], reverse=True)
    # 키 큰 사람의 수가 동일할 경우 키가 큰 사람 기준으로 내림 차순 정렬
    sorted_arr = sorted(sorted_arr, key=lambda x: x[0], reverse=False)
    # 정답 배열 선언
    answer = [0] * len(sorted_arr)


    for item in sorted_arr:
        cursor = 0
        height = item[1]
        cnt = item[0]
        #lt 조건에 맞는지 체크하면서, 정답 배열에 들어갈 위치(cursor)를 찾음
        while cursor < len(arr) and answer[cursor] > 0 and cnt > 0 :
            if answer[cursor] > height :
                cnt -=1
            cursor += 1
        # 정답 배열에 원소 추가
        right_part = answer[cursor:-1]
        answer[cursor] = height
        answer[cursor+1:] = right_part

    # 정답 출력
    answer = list(map(str,answer))
    print(" ".join(answer))


if __name__ == '__main__':
    solution()

 

3.코멘트

  • 단순히 입력 케이스 배열에서 규칙을 찾아 정답을 구할 수 있는 방법으로 접근하려면 더 어렵다. 유형대로 그리디하게 풀어야 한다.
  • 그 동안 서로 많이 바빠서 4개월만에 알고리즘 스터디원들이 모여 재미있게 진행했다.
  • 앞으로는 조금 더 자주 볼 수 있기를 기대한다.
반응형
반응형

 1.데코레이터

많이들 아시겠지만 파이썬에는 데코레이터라는 기능이 있습니다보통 함수나 메소드에 적용하는 기능인데함수나 메서드의 기능을 확장하거나 변경하는 역할을 합니다

 

 

예를 들어 제가 아래와 같이 어떤 처리 함수 my_func를 만들었습니다. 그런데 함수의 성능을 측정하기 위해 함수의 실행시간을 체크하고 싶어요.

 

함수를 수정할 수도 있겠지만, 저라면 runtime_check 라는 데코레이터로 만들어서 여러 함수에 적용해볼 수 있을 것 같습니다. 아래 코드 처럼 데코레이터를 써볼 수 있습니다.

 

    import time 
    def runtime_check(func):
        def func_wrapper():        
            start_time = time.time()
            func()        # 데코레이터를 적용한 함수가 호출되는 부분
            end_time = time.time()
            print(f"runtime : {(end_time - start_time):.4f}")
        return func_wrapper # wrapper 함수 자체를 반환  

    @runtime_check
    def my_func():
        print("function call..")
        time.sleep(2)
    my_func()

    

   

이 처럼 데코레이터 내부에서의 동작은 기존 함수에 로직을 더해 새로운 함수를 만들고 반환하는 방식입니다.

 

 2.데이터클래스

 

데이터클래스는 모듈 수준의 데코레이터라고 할 수 있어요.

 

예제 코드를 보면서 설명해보겠습니다.

 

# 데이터클래스 데코레이터를 쓰기 위한 import 선언 문이구요.
from dataclasses import dataclass, asdict

@dataclass # 데코레이터는 @ 예약어를 씁니다.
class Customer: # 고객 클래스를 선언하구요.
    name: str   # 이름, 나이, 이메일 정도의 클래스 멤버 변수를 만들구요
    age: int
    email: str
# 2개의 객체를 만들어보았습니다.
c1 = Customer("jss1",20,"jss@test.com")
c2 = Customer("jss1",20,"jss@test.com")
# 객체를 출력하고, 객체간의 비교를 해봤습니다. 
# 그리고 마지막으로 클래스 정보를 json 오브젝트로 변환하기 위해 python dictionary 로 변환해보겠습니다.
print(c1)       # Customer(name='jss1', age=20, email='jss@test.com')
print(c2)        # Customer(name='jss1', age=20, email='jss@test.com')
print(c1==c2)    # True  
print(asdict(c1)) # {'name': 'jss1', 'age': 20, 'email': 'jss@test.com'}

 

네 특별한 게 없는 것 같죠..?

그럼 위 코드에서 @dataclass 를 빼고 실행해보시기 바랍니다.

 

그럼 아마도... 아래와 같은 에러가 발생할 거에요

TypeError: Customer() takes no arguments

 

 

그럼 에러를 처리하기 위해 직접 구현해보겠습니다.

class Customer:
    name: str
    age: int
    email: str
    # 객체 초기화를 위한 특별 메소드
    def __init__(self,name,age,email):
        self.name = name
        self.age = age
        self.email = email
    # 객체를 문자열로 표현해주는 특별 메소드
    def __str__(self) -> str:
        return f"name : {self.name} age : {self.age} email : {self.email}"
    # 객체 비교 특별 메소드
    def __eq__(self, value: object) -> bool:
        return True if self.age == self.age else False

 

 

 

위 코드는 객체를 출력하기 위해 __str__ , 객체를 비교하기 위한 __eq__ , 객체의 생성과 초기화를 위해 __init__ 을 구현해습니다.

** asdict()는 dataclass 타입 인스턴스만 인자로 받기 때문에 에러가 여전히 발생할겁니다.

 

결과적으로 데이터클래스 데코터레이터를 이용하면 작성해야 할 코드를 생략할 수 있어요.  데이터클래스 데코레이터를 이용해서 특수 메서드들이 자동으로 추가된 겁니다.

 

필요하면 활용해보세요. :)

 

끝.

반응형

반응형

5년 전 즈음에 실제 제가 면접에서 받았던 손코딩 문제인데, 재미로 공유 드려봅니다.

 

문제는 되게 간단해요.

 

아래 변수 A 와 B 에 담긴 값을 추가 변수 없이(temp) 없이 교환(swap) 해보는 겁니다.

 

A = 10 

B = 5 

 

한 번 풀어보시죠.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

대부분은 임시 변수를 하나 선언해서 swap 하는 방식을 먼저 떠 올릴 것 같은데요. 고민해보면 이런 방법도 있습니다.

정답은 아래 코드입니다. 

A = A+B // 15 

B = A-B // 10 

A = A-B // 5 

 

 

 

4 바이트를 절약할 수 있었네요. 

 

.

 
반응형
반응형

 

올해는 드디어 기회가 돼서 AWS submmit 에 다녀온 후기를 남겨볼까 한다. 난 경력이 적지 않은 편이라고 생각하는데, 이런 기술 행사를 다녀온 경험이 별로 없다. 

5월 16일~17일 동안 코엑스 컨벤션 센터에서 열렸고, 엄청난 인기를 경험했다. 

 

내가 생각하는 AWS 가 잘하는 비지니스 전략은 IT 트렌드한 신기술을 고객 관리형 서비스로 빠르게 출시하면서 시장 점유율을 높이는 것이다. 따라서 AWS 기술 행사에는 고객이 선택하고 집중하는 IT 트렌드를 엿 볼 수 있다고 믿는 편이다.

 

기조연설에서 기억에 남았던 내용은 2가지다. the frugal architect (검소한 아키텍트)가 돼서 비지니스 전략과 트래픽의 변화에 맞게 인프라 비용을 유연하게 절감하자는 내용과 생성형 AI 애플리케이션 개발 트렌드와 Amazon Bedrock 이다. 

 

우리 회사도 파트에서 Data on EKS 전략으로 넘어가면서 비용 절감에 큰 노력을 하고 있기 때문에,  배경과 목적이 크게 공감이 됐다. 그리고 앞으로 데이터 엔지니어링 영역이 생성형 AI 개발안에서도 RAG 영역에서 활용될 수 있는 부분이 흥미롭게 들렸다. 

 

개인적으로 EMR on EKS 를 주제로 발표한 우아한 형제들과 쿠팡의 레드시프트,  karpenter 주제를 맡은 요기요, 그리고 당근마켓의 실시간 분석에 대한 주제가 궁금했는데, 아쉽게도 당근마켓만 듣지 못했다. 세션 간 대기 시간이 30분이나 되는데도, 미리 줄을 서지 못해 못 들어갔다.. ㅎㅎ

 

내가 들었던 세션은 모두 큰 도움이 될 만한 내용들이었다. emr on eks 의 스케쥴러 도입과 karpenter 최적화 (사용 중인 provisioner 가 nodepool 로 대체됨) 등 해야 할 일들이 많이 생겼다.  

 

나도 내년에는 의미 있는 내용과 경험으로 저런 큰 행사에서 발표를 해보고 싶은 마음이 크게 들었다.

 

조금 더 열심히 해야겠다.

 

 

 

 

반응형

+ Recent posts