LEARNING REPORT

---

작성일 : 2024-07-02

작성자 : migdracios

학습기술 : Xcode

학습분류 : SW개발, 앱개발

 

학습내용

1. Xcode 설치와 버전, 프로젝트 생성

Xcode 설치를 위해서는 맥 버전 호환을 확인해야 한다.

현재 내 기준 설치한 Xcode 버전은 15.4, Mac 버전은 Sonoma 14.5

Xcode에서 프로젝트를 생성할 때 Identifier가 있는데 앱 고유 식별자이다. 이 식별자는 웹 도메인처럼 쓰이는데

naver.com이 아니라 com.naver 처럼 반대로 씌여있다

 

2. Swift 파일의 주석

Swift 파일은 코드 주석과 문서 주석으로 나뉘어 있다.

코드 주석은 슬래쉬(/) 두 개로, 문서 주석은 세 개로 구분한다.

문서 주석은 코드에 붙여 작성하였을 때, opt + click 으로 주석을 상세히 볼 수 있다.

또 해당 코드를 클릭하면 Quick Help Inspector에서도 확인할 수 있다.

 

3. 에디터 단축키

내비게이터에서 opt + click 으로 화면을 분할 할 수 있다.

클래스에 command + click 으로 정의부로 들어가 확인할 수 있다.

돌아갈때는 에디터의 뒤로가기 버튼을 눌러 나올 수 있다.

중괄호가 있는 코드에 command + opt + click 으로 코드를 접어둘 수 있다.

 

 

학습결과물

LEARNING REPORT

---

작성일 : 2024-07-02

작성자 : migdracios

학습기술 : Python, Langchain, OpenAiAPI

학습분류 : SW 개발, AI 기능 개발

 

학습내용

랭체인으로 AI 모델의 API를 가져와 응답(Chat Completion)을 받기 위해서는 라이브러리 설치가 필요함

필요 라이브러리는 langchain, huggingface-hub, openai, streamlit을 세팅

각각 랭체인 채팅 객체를 선언하고 응답 받기 위해, 허깅페이스 모델을 가져오기 위해, OpenAI 모델을 가져오기 위해 사용함(Streamlit은 아직 사용 안함)

 

 

 

학습결과물

1. Langchain PromptTemplate로 프롬프트 세팅

from langchain import PromptTemplate

template = "{product}를 홍보하기 위한 좋은 문구를 추천해줘?"

 

prompt = PromptTemplate(

    input_variables=["product"],

    template=template,

)

prompt.format(product="카메라")

 

2. 랭체인으로 GPT 응답 생성하기

'''

랭체인 라이브러리에서 가져오기

1. OpenAI의 채팅 기반 모델 ChatOpenAI

2. 사용자의 메시지를 나타내는 HumanMessage

'''

from langchain.chat_models import ChatOpenAI

from langchain.schema import HumanMessage

 

# ChatOpenAI 메서드를 사용하여 

chat = ChatOpenAI(model_name="gpt-4o") # ChatOpenAI 인스턴스 생성 및 모델 지정

prompt = "영상이는 강아지를 키우고 있습니다. 영상이가 키우고 있는 동물은?" # AI에게 물어볼 질문은 문자열로 생성

messages = [HumanMessage(content=prompt)] # AI와 대화를 위한 HumanMessage 객체 생성 및 포맷팅

completion = chat(messages) # AI 응답 생성

print(completion.content) # AI 응답 출력

 

3. Langchain으로 Goolge 오픈 소스 모델 응답 생성하기

from langchain_huggingface import HuggingFaceEndpoint

 

llm2 = HuggingFaceEndpoint(

    repo_id="google/flan-t5-xxl",

    temperature=0.8,

    max_length=512

)

prompt = "영상이는 강아지를 키우고 있습니다. 영상이가 키우고 있는 동물은?"

completion = llm2.invoke(prompt)

print(completion)

 

학습 중 떠오르게 된 생각

교재를 바탕으로 실습 중인데, 생각보다 빠르게 버전 변경이 있으며 이에 따른 메서드 변경도 있음.

아직 세팅까지 밖에 안해봄.

학습 주제

랜덤으로 떨어지는 빗방울 만들기

학습 목표는 무엇입니까?

랜덤한 위치와 크기를 가진 오브젝트로 다양성을 주는 방법 알아내기

학습 내용

학습 내용을 작성해주세요

  • GetComponent를 잊지 말자
    • 에셋 내 컴포넌트를 가져오기 위해서는 두 가지가 필요하다
      • 가져올 컴포넌트를 메인 함수에서 선언하기
      • 작동 함수에서 GetComponent로 가져오기
      public class Rain : MonoBehaviour
      {
          ... 중략
          
          SpriteRenderer renderer;
          
          void Start()
          {
              renderer = GetComponent<SpriteRenderer>();
      
      
  • 랜덤 값을 만드는 Random.Range()
    • Random.Range()는 시작 값, 끝 값으로 조정함
    • 정수의 경우 시작 값, 끝 값 -1이 됨
    float x = Random.Range(-2.4f, 2.4f);
    float y = Random.Range(3.0f, 5.0f);
    
    int type = Random.Range(1, 4);
    
  • Sprite Renderer에서 색깔을 조정할 수 있음
    • renderer.Color 속성으로 색 값을 변경 가능
    • new Color(c,m,y,k) 값을 넣어 속성 지정
    • 숫자 값은 number / 255f 형식으로 지정 가능
    renderer.color = new Color(50 / 255f, 50 / 255f, 1f, 1f);
    
  • transform 속성에서 위치와 크기를 바꾸자
    • transform.position으로 위치 변경 가능
    • float x = Random.Range(-2.4f, 2.4f); float y = Random.Range(3.0f, 5.0f); transform.position = new Vector3(x, y);
    • transform.localScale로 크기 변경 가능
    • else if (type == 3) { size = 1.2f; score = 1; renderer.color = new Color(150 / 255f, 150 / 255f, 1f, 1f); } transform.localScale = new Vector3(size, size, 0);
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Rain : MonoBehaviour
{
    // 빗방울 기본 사이즈, 점수 설정
    float size = 1.0f;
    int score = 1;

    SpriteRenderer renderer;
    // Start is called before the first frame update
    void Start()
    {
        renderer = GetComponent<SpriteRenderer>();

        // 빗방울 위치 설정
        float x = Random.Range(-2.4f, 2.4f);
        float y = Random.Range(3.0f, 5.0f);
        transform.position = new Vector3(x, y);

        int type = Random.Range(1, 4);
        Debug.Log($"타입 값은 --> {type}");
        if (type == 1)
        {
            size = 0.8f;
            score = 3;
            renderer.color = new Color(50 / 255f, 50 / 255f, 1f, 1f);
        }
        else if (type == 2)
        {
            size = 1.0f;
            score = 2;
            renderer.color = new Color(100 / 255f, 100 / 255f, 1f, 1f);
        }
        else if (type == 3)
        {
            size = 1.2f;
            score = 1;
            renderer.color = new Color(150 / 255f, 150 / 255f, 1f, 1f);
        }
        transform.localScale = new Vector3(size, size, 0);
    }

    // Update is called once per frame
    void Update()
    {

    }

    private void OnCollisionEnter2D(Collision2D collision)
    {
        if (collision.gameObject.CompareTag("Ground"))
        {
            Destroy(this.gameObject);
        }
    }
}

학습 주제

빗방울 오브젝트를 생성하고 바닥과 충돌 시 사라지게 만들기

학습 목표는 무엇입니까?

오브젝트 충돌 관리와 충돌 시 제거 구현

학습 내용

학습 내용을 작성해주세요

  • 중력을 작동시켜 아래로 떨어지게 하는 물리엔진은 Rigidbody(현재 프로젝트는 2D 사용)
  • 충돌 이벤트를 만들기 위해서는 충돌과 관련된 오브젝트에 collider 컴포넌트를 추가한다
    • ground는 box collider 2d 사용
    • rain은 circle collider 2d 사용
  • 부딪히는 순간 오브젝트를 추적하고 제거하려면 스크립트에서 private void OnCollisionEnter2D(Collision2D collision) 함수를 이용
    • 함수 내에서 만약 충돌한 오브젝트가 ground라면~ 으로 분기를 만들기
      • 이 Ground를 gameObject.name 속성으로 넣는다면 이름이 바뀌면 트래킹 불가
      • 그래서 Ground라는 에셋 태그를 만들어 추가하는 방식으로 해소
    • 값이 ground라면, rain 스크립트 컴포넌트를 파괴하는 명령어를 작성하기

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Rain : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {

    }

    // Update is called once per frame
    void Update()
    {

    }

    private void OnCollisionEnter2D(Collision2D collision)
    {
        if (collision.gameObject.CompareTag("Ground"))
        {
            Destroy(this.gameObject);
        }
    }
}

 

학습 주제

유니티-에셋-애니메이션 스크립트를 연동하여 캐릭터 움직이게 만들기

학습 목표는 무엇입니까?

유니티 엔진 에셋으로 오브젝트 지정하고 움직이게 만드는 것 그 자체

학습 내용

학습 내용을 작성해주세요

  • Unity 에셋과 컴포넌트
    • Unity Engine에서 오브젝트가 움직이게 하기 위해서는 에셋을 만들고, 그 에셋을 움직이게 만들 컴포넌트(Component)가 필요하다
    • 컴포넌트는 에셋에 포함된 transfer, sprite render, animation, script 등이 있음
  • Unity에서 모든 기기가 똑같은 프레임으로 작동할 수 있게 하기
    • Unity에서 작성된 스크립트를 실행하면, 기기 성능에 따라 게임의 속도가 다를 수 있음
    • 속도를 맞추기 위해 게임 내 실행할 프레임을 정의하는 속성이 Application.targetFrameRate임
    • 이 속성 값을 60으로 맞춰서 항상 60프레임으로 게임을 작동하게 만들 수 있음
    void Start()
        {
            Application.targetFrameRate = 60;
        }
    
  • Unity에서 컴포넌트를 가져올 수 있는 스크립트
    • C# 스크립트로 에셋 내부의 여러 값을 가져와 제어할 수 있음
    • Sprite renderer를 예시로 한다면 이를 전체 스크립트 함수에서 선언해주어야 함
    • 그리고, 선언한 변수를 가져다 사용하여 제어 가능
    using System.Collections;
    using System.Collections.Generic;
    using Unity.VisualScripting;
    using UnityEngine;
    
    public class Rtan : MonoBehaviour
    {
        float direction = 0.1f;
    
        **new SpriteRenderer renderer;**
    
        // Start is called before the first frame update
        void Start()
        {
            Application.targetFrameRate = 60;
            renderer = GetComponent<SpriteRenderer>();
            Debug.Log("check");
        }
    
        // Update is called once per frame
        void Update()
        {
            if (Input.GetMouseButtonDown(0))
            {
                direction *= -1;
                **renderer.flipX = !renderer.flipX;**
            }
    
            // 조건 : 벽에 부딪히면 반대방향을 보게 만들어라!
            // +라면 오른쪽으로 -라면 왼쪽으로 돌기 때문에 -1을 곱해주기만 하면 됨
            if (transform.position.x > 2.6 || transform.position.x < -2.6)
            {
                direction *= -1;
                **renderer.flipX = !renderer.flipX;**
            }
    
            // transform.position += new Vector3(1f, 0, 0); 을 아래 코드로 만들 수 있음
            transform.position += Vector3.right * direction;
        }
    }
    
    

 

개발 기획 기술

문제 정의

업무 중 슬랙에서 요청 메시지가 급하게 들어오는 건들이 많다.

그때그때 슬랙을 확인하여 읽더라도, 기억하기 어려울 정도로 늘어나고 있으며, 내 기억은 정말 짧다..

따라서 일을 놓치지 않기 위해서는 이 기록을 모아둘 수 있는 자동화 도구가 필요하며, Zapier를 사용한 Slack to Google Sheet 자동화로 해결할 수 있을 것이라 생각하게 되었음

 

스펙 기술

  • 자동화 도구로 해결한다면 어떤 그림일까?
    • 내게 들어오는 업무 큐를 만들어 슬랙에서 시트로 보내 한 눈에 보고싶다
  • 어떤 순서로 작동할까?
    1. 슬랙메시지를 재피어로 푸시한다
    2. 재피어에서 메시지를 확인하여 구글 시트에 추가한다
    3. 구글시트에서 메시지를 잘라서 원하는 정보로 나눠담고, 대시보드를 업데이트한다
    4. 매일 업무 종료 2시간 전에 확인할 수 있게 매일을 발송한다
  • 이 정보를 통해서 획득하는 정보의 종류를 구분하면?
    • 슬랙 메시지로 얻는 내용 
      • 중요한 메시지 내용
      • 메시지 발신자
      • 메시지 발신 채널
      • 메시지 발신 일자
    • 위 내용을 바탕으로 정리할 내용
      • 업무 우선순위
      • 해결 데드라인
      • 진행 상황
      • 리마인드 횟수
      • 진행상황 공유 횟수
  • 사용해야 하는 기술은?
    • Slack, Zapier, Google Sheet, Gmail, Apps Script

 

 


 

 

 


개발 내용 기록

 

슬랙 메시지를 재피어로 보내는 방법

Zapier가 연동되어 있다면, 아래와 같은 추가 기능이 보인다

 

 

 

 채널에서 내게 멘션하는 사람들의 메시지를 그대로 가져다 적재 해놓는게 제일 괜찮다고 생각했다. 그러나 버튼을 클릭했을 때는 연결할 수 있는 Zap이 없다고 표시된다.

 

 

 

 

 

 

 그래서 확인해보니, 재피어의 트리거 중, Slack에서 "New Pushed Message in Slack"이 있다. 이걸로 클릭하여 트리거 세팅을 완료한다. 슬랙 메신저를 사용하고 있는 계정의 연동은 필수이니 참고.

 

 

재피어로 슬랙 메시지를 받아와 구글 시트로 보내기

 

 

 

 

 

재피어의 액션 앱을 구글 시트로 설정하고 연동 한 뒤, "Create New Row"를 선택하여, 내 슬랙 메시지를 구글 시트에 적재하도록 한다. 구글 시트 또한 사용하기 위해서는 구글 이메일 연동이 필요하다.

 

 

 

 

재피어에서 구글 시트를 통해 데이터를 입력할 때에는 반드시 시트 상단부에 열제목을 등록해야 하는데 나는 위의 이미지와 같은 정보를 받아서 처리하고 싶었다. 

 

 

 

 

 

열제목을 만들어 두면, 알아서 재피어에서 시트를 추적하여 열제목 목록을 확인하고, 입력 공간을 생성한다.

여기에 클릭한 뒤, 아까 슬랙에서 추적한 슬랙 메시지 정보를 확인해가면서 값을 넣어 저장할 수 있다.

보낸 이, 메시지 전송 요청 날짜부터 다양한 메시지 관련 데이터를 갖고 있기 때문에 확인한다. 여기에서 중요한 건 메시지 자체도 하나의 데이터 형태로 갖고 있는 것이라, 메시지를 잘라 쓰고 싶다면 이후에 구글 시트에서 다시 처리해야만 한다.

 

 

 


분류

 

#재피어#Zapier#자동화#RPA#업무자동화#슬랙#Slack

+ Recent posts