Rxjava와 MVVM 패턴을 사용한 영화 앱 강의를 듣던 중 유용해 보이는 플러그인을 발견해서 소개하려고 합니다.

 

플러그인 이름에서 볼 수 있듯이 Json 형식의 문자열을 코틀린 데이터 클래스로 쉽게 변환 해준다고 하네요.

 

간단한 사용법을 이미지와 함께 소개하겠습니당 ^0^

 

 

먼저 안드로이드 스튜디오 실행 후 File > Settings > Plugins 항목에서 json to kotlin 검색하여 설치하면

 

 

아래와 같이 새로운 파일 생성 시 "Kotlin data class File from JSON" 항목을 선택할 수 있습니다.

 

선택 후 Json 형식의 텍스트를 붙여넣기 해준 후에, 오른쪽 상단의 포맷 버튼을 눌러주면 붙여넣기로 인해 줄바꿈이 되어 있지 않던 Json 형식의 데이터가 보기좋게 정리됩니다. 하단의 Class Name에 원하는 클래스 명을 입력 하시면 그대로 데이터 클래스가 생성됩니다. 

 

 

추가적으로 설정하고 싶으신 옵션이 있으면 Advanced 버튼 클릭 후 둘러보세용..

 

짜잔 아주 간단하게 데이터 클래스가 생성된 모습 ^&^

 

문제 설명

대학 교수인 당신은, 상호평가를 통하여 학생들이 제출한 과제물에 학점을 부여하려고 합니다. 아래는 0번부터 4번까지 번호가 매겨진 5명의 학생들이 자신과 다른 학생의 과제를 평가한 점수표입니다.

No. 0 1 2 3 4
0 100 90 98 88 65
1 50 45 99 85 77
2 47 88 95 80 67
3 61 57 100 80 65
4 24 90 94 75 65
평균 45.5 81.25 97.2 81.6 67.8
학점 F B A B D

위의 점수표에서, i행 j열의 값은 i번 학생이 평가한 j번 학생의 과제 점수입니다.

  • 0번 학생이 평가한 점수는 0번 행에담긴 [100, 90, 98, 88, 65]입니다.
    • 0번 학생은 자기 자신에게 100점, 1번 학생에게 90점, 2번 학생에게 98점, 3번 학생에게 88점, 4번 학생에게 65점을 부여했습니다.
  • 2번 학생이 평가한 점수는 2번 행에담긴 [47, 88, 95, 80, 67]입니다.
    • 2번 학생은 0번 학생에게 47점, 1번 학생에게 88점, 자기 자신에게 95점, 3번 학생에게 80점, 4번 학생에게 67점을 부여했습니다.

당신은 각 학생들이 받은 점수의 평균을 구하여, 기준에 따라 학점을 부여하려고 합니다.
만약, 학생들이 자기 자신을 평가한 점수가 유일한 최고점 또는 유일한 최저점이라면 그 점수는 제외하고 평균을 구합니다.

  • 0번 학생이 받은 점수는 0번 열에 담긴 [100, 50, 47, 61, 24]입니다. 자기 자신을 평가한 100점은 자신이 받은 점수 중에서 유일한 최고점이므로, 평균을 구할 때 제외합니다.
    • 0번 학생의 평균 점수는 (50+47+61+24) / 4 = 45.5입니다.
  • 4번 학생이 받은 점수는 4번 열에 담긴 [65, 77, 67, 65, 65]입니다. 자기 자신을 평가한 65점은 자신이 받은 점수 중에서 최저점이지만 같은 점수가 2개 더 있으므로, 유일한 최저점이 아닙니다. 따라서, 평균을 구할 때 제외하지 않습니다.
    • 4번 학생의 평균 점수는 (65+77+67+65+65) / 5 = 67.8입니다.

제외할 점수는 제외하고 평균을 구한 후, 아래 기준에 따라 학점을 부여합니다.

평균학점

90점 이상 A
80점 이상 90점 미만 B
70점 이상 80점 미만 C
50점 이상 70점 미만 D
50점 미만 F

학생들의 점수가 담긴 정수형 2차원 배열 scores가 매개변수로 주어집니다. 이때, 학생들의 학점을 구하여 하나의 문자열로 만들어서 return 하도록 solution 함수를 완성해주세요.


제한사항

  • 2 ≤ scores의 행의 길이(학생 수) ≤ 10
  • scores의 열의 길이 = scores의 행의 길이
    • 즉, scores는 행과 열의 길이가 같은 2차원 배열입니다.
  • 0 ≤ scores의 원소 ≤ 100
  • return 값 형식
    • 0번 학생의 학점부터 차례대로 이어 붙인 하나의 문자열을 return 합니다.

입출력 예

scoresresult

[[100,90,98,88,65],[50,45,99,85,77],[47,88,95,80,67],[61,57,100,80,65],[24,90,94,75,65]] "FBABD"
[[50,90],[50,87]] "DA"
[[70,49,90],[68,50,38],[73,31,100]] "CFD"

입출력 예 설명

입출력 예 #1

문제 예시와 같습니다.

입출력 예 #2

No. 0 1
0 50 90
1 50 87
평균 50 90
학점 D A
  • 1번 학생이 자기 자신을 평가한 87점은 [90, 87]에서 유일한 최저점이므로, 평균을 구할 때 제외합니다.

입출력 예 #3

No. 0 1 2
0 70 49 90
1 68 50 38
2 73 31 100
평균 70.33… 40 64
학점 C F D
  • 1번 학생이 자기 자신을 평가한 50점은 [49, 50, 31]에서 유일한 최고점이므로, 평균을 구할 때 제외합니다.
  • 2번 학생이 자기 자신을 평가한 100점은 [90, 38, 100]에서 유일한 최고점이므로, 평균을 구할 때 제외합니다.

 

나의 풀이

 

1. 2차원 배열의 행 열을 변경하기 -> 코틀린 배열에서 제공하는 max, min 함수 사용을 위해

2. 자기 자신에게 평가 한 경우 max 또는 min 값인지 확인 후에 유일한 최저점, 최고점 확인 

 

class Solution {
     fun solution(scores: Array<IntArray>): String {
        var answer: String = ""
        var rotatedScores : Array<IntArray> = Array(scores.size) { IntArray(scores.size)}

        for ( i in scores.indices)
            for (j in scores[i].indices)
                rotatedScores[i][j] = scores[j][i]

        for (i in scores.indices)
        {
            var sum = 0.0F
            var cnt = rotatedScores[i].size

            for ( j in rotatedScores[i].indices)
            {
                if (i == j)
                {
                    if (rotatedScores[i][j] == rotatedScores[j].min() ||
                            rotatedScores[i][j] == rotatedScores[j].max())
                    {
                        var countOfSameVal = rotatedScores[i].filter { it.equals(rotatedScores[i][j])}
                        if (countOfSameVal.size < 2) {
                            cnt -= 1
                            continue
                        }
                    }
                }
                sum += rotatedScores[i][j]
            }
            sum /= cnt

            when (sum) {
                in 90F..100F -> answer = answer.plus("A")
                in 80F..90F -> answer = answer.plus("B")
                in 70F..80F -> answer = answer.plus("C")
                in 50F..70F -> answer = answer.plus("D")
                in  0F..50F -> answer = answer.plus("F")
            }
        }
        return answer
    }
}

코드는 생각보다 길어졌지만 코틀린에 익숙해지는 것을 목표로 해본다 ㅠ

  • 부족한 금액 계산하기

문제 설명

새로 생긴 놀이기구는 인기가 매우 많아 줄이 끊이질 않습니다. 이 놀이기구의 원래 이용료는 price원 인데, 놀이기구를 N 번 째 이용한다면 원래 이용료의 N배를 받기로 하였습니다. 즉, 처음 이용료가 100이었다면 2번째에는 200, 3번째에는 300으로 요금이 인상됩니다.
놀이기구를 count번 타게 되면 현재 자신이 가지고 있는 금액에서 얼마가 모자라는지를 return 하도록 solution 함수를 완성하세요.
단, 금액이 부족하지 않으면 0을 return 하세요.

제한사항

  • 놀이기구의 이용료 price : 1 ≤ price ≤ 2,500, price는 자연수
  • 처음 가지고 있던 금액 money : 1 ≤ money ≤ 1,000,000,000, money는 자연수
  • 놀이기구의 이용 횟수 count : 1 ≤ count ≤ 2,500, count는 자연수

입출력 예

pricemoneycountresult

3 20 4 10

입출력 예 설명

입출력 예 #1
이용금액이 3인 놀이기구를 4번 타고 싶은 고객이 현재 가진 금액이 20이라면, 총 필요한 놀이기구의 이용 금액은 30 (= 3+6+9+12) 이 되어 10만큼 부족하므로 10을 return 합니다.

참고 사항

  • 미션 언어는 Java, JavaScript, Python3, C++ 만 해당 됩니다.
  • 같은 코드를 제출한 사람이 여럿이라면 코드를 가장 먼저 제출한 분께 상품을 드립니다.
  • 좋아요 수가 동일할 경우 코드를 가장 먼저 제출한 분께 상품을 드립니다.

 

나의 풀이

 

문제는 간단했는데, 네가지 테스트가 계속 실패하는 바람에.. 도무지 모르겠어서 구글링 했더니 money값을 받을 때 

int형이 아닌 long형으로 받아야 한다고 해서 매개변수 타입을 long으로 변경하니 성공했다.. 문제를 보면 알 수 있는 부분인데 좀더 문제를 정확히 읽고 풀어야겠다 ㅠ-ㅠ

    public long solution(int price, long money, int count) {
        for(int i = 1; i <= count; i++)  
            money = money - price * i;
        return  money > 0 ? 0 : money*-1;
    }

이미지 경계선 얻기 - cv2.threshold()

 

우선 피포페인팅 도안을 생성하기 위해 도안이 될 이미지에서 선을 따는 작업이 필요했는데, 이를 도와줄 함수로 

cv2.threshold() 함수가 적절해 보여서, 사용하기로 했다. 비슷한 기능을 할 만한 함수로 cv2.canny() 함수가 있었는데, 다음 장에서 차이

threshold는 구글 번역기에서는 한계점 이라고 해석되는데, 구글링을 통해 관련 문서를 보면 임계점(사실 같은뜻이지만?) 이라고 많이 부르는 것 같다. 

 

임계점이라는 의미를 알았으니, OpenCV doc에서 cv2.threshold() 함수의 설명과 파라미터에 대해 알아보자.

 

문서의 내용을 간단히 요약하면, 

"픽셀 값이 임계값보다 작으면 0으로 설정되고, 그렇지 않으면 최대값으로 설정됩니다."

이 부분이 메인이라고 볼 수 있을 것 같다.

 

파라미터를 살펴보자.

cv2.threshold(src, thresh, maxval, type)

return value : retval, dst

parameter
src - 첫 번째 인수는 회색조 이미지여야 하는 소스 이미지 입니다.
thresh - 두 번째 인수는 픽셀 값을 분류하는 데 사용되는 임계값입니다.
maxval - 세 번째 인수는 임계값을 초과하는 픽셀 값에 할당되는 최대값입니다.
type - OpenCV는 함수의 네 번째 매개변수에 의해 제공되는 다양한 유형의 임계값을 제공합니다. 위에서 설명한 기본 임계값은 cv.THRESH_BINARY 유형을 사용하여 수행됩니다 . 

return value
retval - 첫 번째는 사용된 임계값이고
dst - 두 번째 출력은 임계값 이미지 입니다

 

OpenCV 문서에 아주 상세하게 설명되어 있다.

 

네번째 파라미터인 type을 변경해가면서 테스트를 해볼텐데, 나는 백예린님의 팬이므로 백예린님 사진을 통해 type을 변경해가면서 비교해보자.

 

코드의 출처는 OpenCV docs 문서이며, 이미지의 경로만 변경했다.

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
img = cv.imread('D:\yerin.jpg',0)
ret,thresh1 = cv.threshold(img,127,255,cv.THRESH_BINARY)
ret,thresh2 = cv.threshold(img,127,255,cv.THRESH_BINARY_INV)
ret,thresh3 = cv.threshold(img,127,255,cv.THRESH_TRUNC)
ret,thresh4 = cv.threshold(img,127,255,cv.THRESH_TOZERO)
ret,thresh5 = cv.threshold(img,127,255,cv.THRESH_TOZERO_INV)
titles = ['Original Image','BINARY','BINARY_INV','TRUNC','TOZERO','TOZERO_INV']
images = [img, thresh1, thresh2, thresh3, thresh4, thresh5]
for i in range(6):
    plt.subplot(2,3,i+1),plt.imshow(images[i],'gray',vmin=0,vmax=255)
    plt.title(titles[i])
    plt.xticks([]),plt.yticks([])
plt.show()

 

 

내가 원하는 피포페인팅의 도안을 위해서는 BINARY type을 사용하는게 맞아보인다.

 

사실 지금 사용하고 있는 경계선을 얻어내는 방식은 cv2.canny()함수를 사용하고 있는데 프로토타입이 완성되면

품질 향상을 위해 threshold 함수도 고려해볼 수 있어보인다.

 

이상으로 오늘의 포스팅은 끗 ㅎㅅㅎ

 

Reference

 

https://docs.opencv.org/4.5.2/d7/d4d/tutorial_py_thresholding.html

 

OpenCV: Image Thresholding

Goal In this tutorial, you will learn simple thresholding, adaptive thresholding and Otsu's thresholding. You will learn the functions cv.threshold and cv.adaptiveThreshold. Simple Thresholding Here, the matter is straight-forward. For every pixel, the sam

docs.opencv.org

https://opencv-python.readthedocs.io/en/latest/doc/09.imageThresholding/imageThresholding.html

 

이미지 임계처리 — gramman 0.1 documentation

기본 임계처리 이진화 처리는 간단하지만, 쉽지 않은 문제를 가지고 있다. 이진화란 영상을 흑/백으로 분류하여 처리하는 것을 말합니다. 이때 기준이 되는 임계값을 어떻게 결정할 것인지가 중

opencv-python.readthedocs.io

 

'TIL' 카테고리의 다른 글

2021.09.09  (0) 2021.09.10
2021.09.08  (0) 2021.09.08
[TIL] python OpenCV - 1  (1) 2021.07.26
외부에서 내 컴퓨터 접속하기 (apache, 포트포워딩)  (1) 2021.03.29
C언어에서 배열의 크기를 변수로 선언할 수 있을까?  (5) 2019.10.29

2021.07.26

오늘부터 토이 프로젝트로 개발중인 P4Maker를 개발하면서 배운 점들을 기록하려고 합니다.

개발하게된 이유는 가지고있는 피포 페인팅이 완성 된 후 새로운 그림을 그리고 싶은데, 마음에 드는 도안이 없어서

직접 개발해보면 어떨까 싶은 생각에 개발하게 되었습니다.

 

오늘부터 화이팅 해보자 ^0^..

 

니코쌤 강의 도중 github page에 배포하는 부분에서 오류가 발생했다.

 

1. A branch named 'gh-pages' already exists.

검색해보니 node_modules/.cache/gh-pages 폴더 삭제하면 됨

 

2. remote: Permission to gogoadl/movie_app_2021.git denied to AdamPark0030.
fatal: unable to access 'https://github.com/gogoadl/movie_app_2021.git/': The requested URL returned error: 403

 

이건 최초로 git에 등록한 계정과 배포에 사용할 계정이 다를경우 발생하는데, Windows 사용자 기준으로

Windows 키 > 자격 증명 관리자 > 일반 자격 증명 > git:https://github.com 항목을 편집하여

배포에 사용할 계정의 ID와 비밀번호로 업데이트 시켜준 후에 다시 시도해서 성공했다.

 

'React' 카테고리의 다른 글

react router가 동작하지 않을 때  (1) 2021.12.05

문제 설명

당신은 폰켓몬을 잡기 위한 오랜 여행 끝에, 홍 박사님의 연구실에 도착했습니다. 홍 박사님은 당신에게 자신의 연구실에 있는 총 N 마리의 폰켓몬 중에서 N/2마리를 가져가도 좋다고 했습니다.
홍 박사님 연구실의 폰켓몬은 종류에 따라 번호를 붙여 구분합니다. 따라서 같은 종류의 폰켓몬은 같은 번호를 가지고 있습니다. 예를 들어 연구실에 총 4마리의 폰켓몬이 있고, 각 폰켓몬의 종류 번호가 [3번, 1번, 2번, 3번]이라면 이는 3번 폰켓몬 두 마리, 1번 폰켓몬 한 마리, 2번 폰켓몬 한 마리가 있음을 나타냅니다. 이때, 4마리의 폰켓몬 중 2마리를 고르는 방법은 다음과 같이 6가지가 있습니다.

  1. 첫 번째(3번), 두 번째(1번) 폰켓몬을 선택
  2. 첫 번째(3번), 세 번째(2번) 폰켓몬을 선택
  3. 첫 번째(3번), 네 번째(3번) 폰켓몬을 선택
  4. 두 번째(1번), 세 번째(2번) 폰켓몬을 선택
  5. 두 번째(1번), 네 번째(3번) 폰켓몬을 선택
  6. 세 번째(2번), 네 번째(3번) 폰켓몬을 선택

이때, 첫 번째(3번) 폰켓몬과 네 번째(3번) 폰켓몬을 선택하는 방법은 한 종류(3번 폰켓몬 두 마리)의 폰켓몬만 가질 수 있지만, 다른 방법들은 모두 두 종류의 폰켓몬을 가질 수 있습니다. 따라서 위 예시에서 가질 수 있는 폰켓몬 종류 수의 최댓값은 2가 됩니다.
당신은 최대한 다양한 종류의 폰켓몬을 가지길 원하기 때문에, 최대한 많은 종류의 폰켓몬을 포함해서 N/2마리를 선택하려 합니다. N마리 폰켓몬의 종류 번호가 담긴 배열 nums가 매개변수로 주어질 때, N/2마리의 폰켓몬을 선택하는 방법 중, 가장 많은 종류의 폰켓몬을 선택하는 방법을 찾아, 그때의 폰켓몬 종류 번호의 개수를 return 하도록 solution 함수를 완성해주세요.

제한사항

  • nums는 폰켓몬의 종류 번호가 담긴 1차원 배열입니다.
  • nums의 길이(N)는 1 이상 10,000 이하의 자연수이며, 항상 짝수로 주어집니다.
  • 폰켓몬의 종류 번호는 1 이상 200,000 이하의 자연수로 나타냅니다.
  • 가장 많은 종류의 폰켓몬을 선택하는 방법이 여러 가지인 경우에도, 선택할 수 있는 폰켓몬 종류 개수의 최댓값 하나만 return 하면 됩니다.

입출력 예

numsresult

[3,1,2,3] 2
[3,3,3,2,2,4] 3
[3,3,3,2,2,2] 2

입출력 예 설명

입출력 예 #1
문제의 예시와 같습니다.

입출력 예 #2
6마리의 폰켓몬이 있으므로, 3마리의 폰켓몬을 골라야 합니다.
가장 많은 종류의 폰켓몬을 고르기 위해서는 3번 폰켓몬 한 마리, 2번 폰켓몬 한 마리, 4번 폰켓몬 한 마리를 고르면 되며, 따라서 3을 return 합니다.

입출력 예 #3
6마리의 폰켓몬이 있으므로, 3마리의 폰켓몬을 골라야 합니다.
가장 많은 종류의 폰켓몬을 고르기 위해서는 3번 폰켓몬 한 마리와 2번 폰켓몬 두 마리를 고르거나, 혹은 3번 폰켓몬 두 마리와 3번 폰켓몬 한 마리를 고르면 됩니다. 따라서 최대 고를 수 있는 폰켓몬 종류의 수는 2입니다.

 

1. 최대한 많은 수의 포켓몬을 골라야 하기 때문에, 중복을 제거해준다.
2. 가질 수 있는 최댓값은 N/2 마리 이므로, 배열의 길이 / 2 가 최대값이다.
3. 중복을 제거한 포켓몬 수 보다 최댓값이 크면 중복을 제거한 포켓몬 수가 최대값이 된다.

 

풀이 코드

  public int solution(int[] nums) {
        int answer = nums.length / 2;

        Set<Integer> set = new HashSet<>();

        for (int i = 0; i < nums.length; i++) {
            set.add(nums[i]);
        }
        if(answer > set.size())
            answer = set.size();
        return answer;
    }

 

MFC 프로젝트를 테스트 하는 도중 오류가 발생했다.

 

LINK1168 cannot open C:\경로\플젝이름.exe for writing 

 

나같은 경우에는 솔루션 구성을 Debug로 설정 후 빌드하고, Debug 폴더에서 바로 exe 파일을 열어서 테스트 하는데, 

 

새로 빌드 된 내용을 exe 파일에 적용해야 하는데 파일이 열려있어서 발생한 것으로 보인다.

 

테스트 하던 exe 프로그램을 종료 후 다시 빌드하니 문제가 없어졌다... ^^;

 

오늘은 오준석님의 생존코딩 강의를 듣던 중 함수와 인터페이스의 색상을 구분하는 테마를 사용하고 계셔서

이참에 테마를 변경 했습니다.

 

적용하고나니 더 코드 읽기가 좋아진 것 같네요 ㅎㅎ

 

바로 본문으로 이동 하겠습니다.

 

안드로이드 스튜디오 테마 변경 방법

 

File > Settings > Appearance & Behavior > Appearance 이동 후 Theme 선택 해주시면 됩니다.

 

별도의 테마를 설치하지 않으신 분은 저처럼 테마가 여러개 나오지 않으실 겁니다. 

 

외부 테마를 사용하는 방법

 

Files > Settings > Plugins > "Material Theme UI" 검색

 

이 플러그인 설치 후 IDE를 재시작 하시면 위의 테마를 선택하는 부분에서 마음에 드는 테마를 선택하시면 됩니다.

 

제가 사용하는 Atom One Dark 테마는 인터페이스와 클래스를 구분하여 하이라이트 해주기 때문에 코드 읽기가 더 편한것 같아서 추천 드립니다!

 

이상으로 글 마치겠습니다!

컴퓨터 공학 전공이 아닌 학교 친구가 통신에 대해서 여쭤봐서, 실시간으로 안드로이드 기기와 통신할 수 있는 방법을 알아야 했는데, 내 컴퓨터를 웹서버로 만들고 외부에서 접속하는 방법을 간단하게 알아보았다.

 

1. apache 설치 및 환경설정

 

https://www.apachelounge.com/download/ 아파치 공식 웹 사이트에 접속하여 아파치를 다운로드한다.

 

다운로드 후 apache24 폴더를 원하는 경로에 지정해준다. 나는 D:\Apache24 로 설정했다.

그 후 conf 폴더로 이동하여 httpd.conf 에서 몇가지 설정을 해준다.

 

폴더 경로를 아래와 같이 변경해준다.

Define SRVROOT "d:/Apache24"

그리고 포트를 변경하고 싶다면 LISTEN 을 검색한다. 기본으로 80으로 설정되어 있지만, 나는 8080으로 변경해줬다.

Listen 8080

 

그 후 D:\Apache24\bin 폴더에서 httpd.exe 파일을 실행해준다.

 

localhost에 접속하여 화면이 잘 나오는것을 확인하자.

 

2. 포트포워딩 설정하기

 

여기까지 설정이 되었다면 다음은 포트포워딩을 할 차례이다. 

 

필자는 딜라이브 공유기를 사용하므로 딜라이브 공유기 환경설정 페이지로 이동하겠다.

 

http://192.168.200.254/ 로 접속하여 네트워크 > 포트 포워딩 페이지에서 아래와 같이 설정한다.

 

설명 : 본인이 원하는 이름으로 설정. 나는 develop으로 설정했다.

ip주소 : cmd 창에서 ipconfig 입력 후 IPv4 주소를 입력한다.

포트번호 : 위에 설정한 포트번호와 같은 번호로 입력한다.

프로토콜 : UDP, TCP 중 선택가능하다. 나는 TCP로 선택했다.

 

마지막으로, 네이버에 공인IP 검색하여 공인IP를 알아낸다.

 

 

공인IP:8080 검색하여 접속하면 끝이다.

 

이번에는 웹서버 연결으로 외부 망 접속을 시도했으나. 조만간 소켓을 통해서도 연결하는 방법을 공부해봐야겠다..

'TIL' 카테고리의 다른 글

2021.09.09  (0) 2021.09.10
2021.09.08  (0) 2021.09.08
[TIL] python OpenCV - threshold 함수로 경계선 얻기  (0) 2021.07.26
[TIL] python OpenCV - 1  (1) 2021.07.26
C언어에서 배열의 크기를 변수로 선언할 수 있을까?  (5) 2019.10.29

+ Recent posts