[내배캠 Android 4기] TIL 0610

오리너구리·2024년 6월 10일
0

TIL

목록 보기
29/48
post-thumbnail

오늘 할일

  • 코드카타 34번
  • 과제 점검 및 제출
  • 코틀린 문법 강의 4,5주차 학습
  • 기초문법 특강 - 이종범 튜터님
  • 레이아웃 학습(Drawer)

코드카타

⏲️ 공부 시간 9 : 10 ~ 10 : 10

33번 링크
(어제 푼건데 어제 아파서 이거만하고 드러누워버려서 글도 못올리고 TIL 못올려가지구 오늘거에 올림)
https://velog.io/@orinugoori_art/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-CODEKATA-33-%EC%95%BD%EC%88%98%EC%99%80-%EA%B0%9C%EC%88%98%EC%99%80-%EB%8D%A7%EC%85%88

34번 링크
https://velog.io/@orinugoori_art/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-CODEKATA-34-%EB%AC%B8%EC%9E%90%EC%97%B4-%EB%82%B4%EB%A6%BC%EC%B0%A8%EC%88%9C%EC%9C%BC%EB%A1%9C-%EB%B0%B0%EC%B9%98%ED%95%98%EA%B8%B0-d9zsg0fx

오늘은 String을 정렬하는 문제였는데

String에서도 sorted를 사용하면 ASCII 값을 비교해서 정렬할 수 있다는 걸 알았당.

그리고 sort랑 sorted의 차이를 공부했당
근데 코드카타에 오히려 타이머가 생겨버리니깐 먼가 타이머끝나고 더 들여다보기싫어서 급하게 끝내버리는 감이있당 원래는 더 자세하게 보는데ㅋㅋ 핑계긴 함 ㅋ 슈발 그냥 타이머끝나고 더 공부하면되는데 빠져가지고;;


과제 점검 및 제출

⏲️ 공부 시간 10 : 30 ~ 11 : 20

과제를 마지막으로 한번 코드 훑어보고 틀린거 업는지 확인하고 제출했다.

근데 이미 머 저번주에 건들고 제출할 과제는 따로 건들지 않아서 그냥 제출했씀~

그리고 어제 원래 들어와서 콘솔 버전 으로 다시 제작하던거 마저 했당


같은 팀 팀원 분 과제 알려드리기

⏲️ 공부 시간 11 : 20 ~ 13 : 20

같은 팀원 분 중에 과제 내용을 잘못 이해하셔서 헤메던 분이 계셨는데 그걸 금요일에야 알아버려서 팀장으로서 책임을 통감하고 금요일에 일과시간 끝나고 좀 도와드리고 오늘도 제출 전까지 조금 도와드렸다.

나랑 같은 비전공자신데 사전캠프도 참여하지 못하셔서 아직 혼자서 과제를 따라오기 벅차하셔서 하나씩 설명해드렸음!

급하게 LV1 하는 방법을 설명드리고 했는데

아직 아주 기본적인 문법도 헷갈리고계셔서 하나하나 설명해드렸당

변수 선언, 함수 선언, 클래스 선언 등부터,

데이터 타입 같은거 알려드림~~

그리고 깃 허브에 레포지토리 생성해서 올리는 방법도 알려드렸당

나도 엊그제까지 못하던건데 이렇게 조금이나마 누구 알려줄수도있고 아주 뿌듯하당~~~

열심히 공부하는 보람이있당~~~

해당 팀원 분이 과제 잘못이해하고계신걸 좀 더 일찍 알아차렸다면 더 알려드릴수있었을텐데

너무 늦게 알아차려서 Lv 1 까지밖에 완성못하고 내시게되어서 죄송스러웠당 ..

나는 역시 섬세하게 누굴 챙기거나하는거에 약하당..

가짜사나이 나갔으면 종내 혼났을듯

2조팀장은..개인주의야..?


콘솔버전 계산기 구현

⏲️ 공부시간 : 14 : 00 ~ 15 : 20

토요일에 Lv 1 까지 구현해놨어서

Lv 2 ,3, 4 를 구현했당

사실 한번 앱버전으로 했었던거라 크게 어려운 건 없었고

그냥 콘솔 버전도 만들어봐야 놓치는거 없이 넘어가지 않을까해서 한번해보는거라

클래스별로 파일도 따로 안만들고 코틀린파일하나에 모든 클래스 다 넣으면서

버전별로 파일 하나씩해서 만들면서 했음..ㅎㅎ

굳이.. 새롭게 안 점을 따진다면

while 문 안에 (ture) 적으면 무한반복시킬 수있다는거 정도 알았다.

이런 지식들이 생각해보면 당연한건데 막상 알기전까지는 혼자서 떠올리지 못하는 것들이라

그래도 이렇게 다시 콘솔버전도 만들어보길 잘했다고 생각함~!

Lv2 코드

설명

main 함수가 실행되면

계산기에 필요한 정보들을 입력받는 inputInformation() 함수가 실행되게 만들고,

if문으로 “1234” 문자열에 입력한 operator 가 있으면 계산결과를 표시하고,

아니면 잘못된 연산자입니다를 표시하게했고,

첫번째 계산 후에 while문에 true 값을 줘서 무한 루프를 만들어주고

추가 연산을 진행하려면 1 아니면 2 를 입력하게 해서

1을 누르면 이전에 계산한 답을 num1 에 넣은채로 계속 원하는 연산을 진행할 수 있게 해줬다.

그리고 만약에 2를 누르면 계산기를 종료한다는 안내문구를 출력하고, break으로 while문을 탈출하게 해서 계산기가 끝나도록 코드를 짰다.

  • main 함수 코드
    var num1 = 0
    var num2 = 0
    var operator = ""
    var answerLv2 = 0
    
    fun main() {
    
            println("-------오리너구리가 만든 계산기-------")
    
            inputInformation()
    
            if ("1234".contains(operator)) {
                answerLv2 = calculateLv2(num1, num2, operator)
                displayInfoLv2(num1, num2, operator, answerLv2)
            } else {
                println("잘못된 연산자입니다")
            }
    
        while (true) {
    
            println("--------------------------------------")
            println("추가 연산을 진행하려면 1, 아니면 2를 입력해라")
    
            val yesOrNo = readln()!!
    
                if (yesOrNo == "1") {
                    println("계산을 계속 진행합니다.")
                    num1 = answerLv2
                    inputInformationLoop()
                    calculateLv2(num1, num2, operator)
                    displayInfoLv2(num1, num2, operator, answerLv2)
                } else {
                    println("계산기를 종료합니다")
                    break
                }
    
            }
        }
    
    fun inputInformation(){
        println("첫번째 숫자를 입력해라")
        num1 = readln()!!.toInt()
    
        println("연산자를 입력해라 ( 1: + , 2: - , 3: * , 4: / , 5: % )")
        operator = readln()!!
    
        println("두번째 숫자를 입력해라")
        num2 = readln()!!.toInt()
    }
    
    fun inputInformationLoop(){
        println("첫번째 숫자 : $num1")
        println("연산자를 입력해라 ( 1: + , 2: - , 3: * , 4: / , 5: %")
        operator = readln()!!
    
        println("두번째 숫자를 입력해라")
        num2 = readln()!!.toInt()
    
    }
  • main에서 사용한 함수들
    fun displayInfoLv2(num1: Int, num2: Int, operator: String, answerLv2 : Int){
        val operatorToSymbol = when(operator){
            "1" -> "+"
            "2" -> "-"
            "3" -> "*"
            "4" -> "/"
            "5" -> "%"
            else -> "잘못된 연산자"
        }
        println("-------계산 결과-------")
        println("당신이 입력한 식 : $num1 $operatorToSymbol $num2")
        println("답 : $answerLv2")
    }
    
    val calculatorLv2 = CalculatorLv2()
    
    fun calculateLv2(num1: Int, num2: Int, operator: String) : Int {
    
        for (i in operator) {
            answerLv2 = when (operator) {
                "1" -> calculatorLv2.add(num1, num2)
                "2" -> calculatorLv2.substract(num1, num2)
                "3" -> calculatorLv2.multiply(num1, num2)
                "4" -> calculatorLv2.divide(num1, num2)
                "5" -> calculatorLv2.mod(num1, num2)
                else -> -1
            }
        }
        return answerLv2
  • Calculator Class 코드
    class CalculatorLv2 {
        fun add (num1 : Int , num2 : Int) = num1 + num2
    
        fun substract (num1 : Int, num2 : Int) = num1 - num2
    
        fun multiply (num1 : Int , num2 : Int ) = num1 * num2
    
        fun divide (num1 : Int , num2 : Int) = num1 / num2
    
        fun mod (num1 : Int , num2 : Int) = num1 % num2
    }

Lv3 코드

설명

Lv 2 에 했던 거에서 똑같은데, Calculator 클래스에 있던 연산 함수들을 각각 의 클래스로 분리해주고, Calculator에 operate 함수를 만들어서 각 연산 함수를 operate를 상속받아서 만들도록 해줬당

  • main 함수 코드
    var num1 = 0
    var num2 = 0
    var operator = ""
    var answerLv3 = 0
    fun main() {
    
        println("-------오리너구리가 만든 계산기-------")
    
        inputInformation()
    
        if ("12345".contains(operator)) {
            answerLv3 = calculateLv3(num1, num2, operator)
            displayInfoLv3(num1, num2, operator, answerLv3)
        } else {
            println("잘못된 연산자입니다")
        }
    
        while (true) {
    
            println("--------------------------------------")
            println("추가 연산을 진행하려면 1, 아니면 2를 입력해라")
    
            val yesOrNo = readln()!!
    
            if (yesOrNo == "1") {
                println("계산을 계속 진행합니다.")
                num1 = answerLv3
                inputInformationLoop()
                calculateLv3(num1, num2, operator)
                displayInfoLv3(num1, num2, operator, answerLv3)
            } else {
                println("계산기를 종료합니다")
                break
            }
    
        }
    }
  • main 에서 사용한 함수들
    fun inputInformation() {
        println("첫번째 숫자를 입력해라")
        num1 = readln()!!.toInt()
    
        println("연산자를 입력해라 ( 1: + , 2: - , 3: * , 4: / , 5: % )")
        operator = readln()!!
    
        println("두번째 숫자를 입력해라")
        num2 = readln()!!.toInt()
    }
    
    fun inputInformationLoop() {
        println("첫번째 숫자 : $num1")
        println("연산자를 입력해라 ( 1: + , 2: - , 3: * , 4: / , 5: %")
        operator = readln()!!
    
        println("두번째 숫자를 입력해라")
        num2 = readln()!!.toInt()
    
    }
    
    fun displayInfoLv3(num1: Int, num2: Int, operator: String, answerLv3: Int) {
        val operatorToSymbol = when (operator) {
            "1" -> "+"
            "2" -> "-"
            "3" -> "*"
            "4" -> "/"
            "5" -> "%"
            else -> "잘못된 연산자"
        }
        println("-------계산 결과-------")
        println("당신이 입력한 식 : $num1 $operatorToSymbol $num2")
        println("답 : $answerLv3")
    }
    
    val addOperation = AddOperation()
    val substractOperation = SubstractOperation()
    val multiplyOperation = MultiplyOperation()
    val divideOperation = DivideOperation()
    
    fun calculateLv3(num1: Int, num2: Int, operator: String): Int {
    
        for (i in operator) {
            when (operator) {
                "1" -> addOperation.operate(num1, num2)
                "2" -> substractOperation.operate(num1, num2)
                "3" -> multiplyOperation.operate(num1, num2)
                "4" -> divideOperation.operate(num1, num2)
                else -> -1
            }
        }
        return answerLv3
    }
  • Calculator 클래스
    open class CalculatorLv3 {
    
        open fun operate(num1: Int, num2: Int): Int {
            return answerLv3
        }
    
    }
  • 각 연산 클래스
    class AddOperation : CalculatorLv3() {
    
        override fun operate(num1: Int, num2: Int): Int {
            answerLv3 = num1 + num2
            return answerLv3
        }
    }
    class SubstractOperation : CalculatorLv3() {
    
        override fun operate(num1: Int, num2: Int): Int {
            answerLv3 = num1 - num2
            return answerLv3
        }
    }
    class MultiplyOperation : CalculatorLv3() {
    
        override fun operate(num1: Int, num2: Int): Int {
            answerLv3 = num1 * num2
            return answerLv3
        }
    }
    class DivideOperation : CalculatorLv3() {
    
        override fun operate(num1: Int, num2: Int): Int {
            answerLv3 = num1 / num2
            return answerLv3
        }
    }

Lv4 코드

의존성 역전 법칙을 위해

Calculator 를 직접 상속받아서 연산 클래스를 만들지 않고

추상클래스인 AbstractOperation을 만들어서 연산클래스를 추상클래스를 상속해서 만들고

Calculator의 매개변수에 AbstractOperation을 받아서 사용하도록 만들어줌으로서

Calculator랑 연산클래스들을 추상화를 통해 링크를 갖도록했당

  • main 함수 코드
    var num1 = 0
    var num2 = 0
    var operator = ""
    var answerLv4 = 0
    fun main() {
    
        println("-------오리너구리가 만든 계산기-------")
    
        inputInformation()
    
        if ("12345".contains(operator)) {
            answerLv4 = calculateLv4(num1, num2, operator)
            displayInfoLv4(num1, num2, operator, answerLv4)
        } else {
            println("잘못된 연산자입니다")
        }
    
        while (true) {
    
            println("--------------------------------------")
            println("추가 연산을 진행하려면 1, 아니면 2를 입력해라")
    
            val yesOrNo = readln()!!
    
            if (yesOrNo == "1") {
                println("계산을 계속 진행합니다.")
                num1 = answerLv4
                inputInformationLoop()
                calculateLv4(num1, num2, operator)
                displayInfoLv4(num1, num2, operator, answerLv4)
            } else {
                println("계산기를 종료합니다")
                break
            }
    
        }
    }
  • main 에서 사용한 함수들
    fun inputInformation() {
        println("첫번째 숫자를 입력해라")
        num1 = readln()!!.toInt()
    
        println("연산자를 입력해라 ( 1: + , 2: - , 3: * , 4: /)")
        operator = readln()!!
    
        println("두번째 숫자를 입력해라")
        num2 = readln()!!.toInt()
    }
    
    fun inputInformationLoop() {
        println("첫번째 숫자 : $num1")
        println("연산자를 입력해라 ( 1: + , 2: - , 3: * , 4: / ")
        operator = readln()!!
    
        println("두번째 숫자를 입력해라")
        num2 = readln()!!.toInt()
    
    }
    
    fun displayInfoLv4(num1: Int, num2: Int, operator: String, answerLv4: Int) {
        val operatorToSymbol = when (operator) {
            "1" -> "+"
            "2" -> "-"
            "3" -> "*"
            "4" -> "/"
            else -> "잘못된 연산자"
        }
        println("-------계산 결과-------")
        println("당신이 입력한 식 : $num1 $operatorToSymbol $num2")
        println("답 : $answerLv4")
    }
    
    val addOperation = CalculatorLv4(AddOperation())
    val substractOperation = CalculatorLv4(SubstractOperation())
    val multiplyOperation = CalculatorLv4(MultiplyOperation())
    val divideOperation = CalculatorLv4(DivideOperation())
    
    fun calculateLv4(num1: Int, num2: Int,operator: String ): Int {
    
        answerLv4 = when(operator){
            "1" -> addOperation.operate(num1,num2)
            "2" -> substractOperation.operate(num1,num2)
            "3" -> multiplyOperation.operate(num1,num2)
            "4" -> divideOperation.operate(num1,num2)
            else -> -1
        }
    
        return answerLv4
    }
  • Calculator 클래스
    class CalculatorLv4(private val abstractOperation : AbstractOperation ) {
    
        fun operate(num1: Int, num2: Int): Int{
            return abstractOperation.operate(num1,num2)
        }
    }
  • AbstractOperation 추상 클래스
    open class AbstractOperation{
    
        open fun operate(num1: Int, num2 :Int):Int{
            return answerLv4
        }
    }
  • 각 연산 클래스
    class AddOperation : AbstractOperation() {
    
        override fun operate(num1: Int, num2: Int): Int {
            answerLv4 = num1 + num2
            return answerLv4
        }
    
    class SubstractOperation : AbstractOperation() {
    
        override fun operate(num1: Int, num2: Int): Int {
            answerLv4 = num1 - num2
            return answerLv4
        }
    }

과제 해설 영상 공부

⏲️ 공부시간 15 : 20 ~ 16 : 30

만든 콘솔버전 계산기를 해설영상보면서 내가 혹시 잘못한게 있는지 더 효율적으로 처리할게 있는지 확인하려고 했는데..

음 애초에 내가 입력을 받는것처럼 메인에서 하나하나 숫자를 입력받는 방식이아니라 그냥 숫자를 지정해놓게 푸는 거였나봄..!?!?!?!?!?!?

왓더..ㅎㅎ당연히 입력받아서 하는 건줄 알았어용..ㅜ

앱으로 만들기의 부작용인가?????

그래서 당연히 코드는 좀 다르지만 오히려 답지 코드가 더 간단하기 때문에 그냥 영상보면서 내가 놓친 부분이 있는지만 살펴보기로함~!

내가 놓친 부분 :

딱히 없는듯? 콘솔계산기 급하게 한번 만들어보느라 Int형으로만 만들었는데, Double로 처리안하는점?이 다르고, 예외처리 같은거 빼먹은거 빼면 없는것같당~~ 장하다 나 자신~!

Lv 5 계산 우선순위 구현

Lv 5 에 계산 우선순위 구현은 앱 계산기에서도 구현못했기 때문에 어떻게하는건지 강의를 봤당

stack을 활용? 한다고함.. 근데 너무어려워..

pop push 등이 정확히 이해가 안감

어렴풋이 어떤 방식인지는 알것같은데………교수님 진도가너무빨ㄹㅏ요..

하지만 이걸해내야 내 계산기앱이 끝나는데…

하지만 너무어려워..

10분만쉬고다시해야징

이라고했는데 쉬면서 멤버카드? 작성하다보니까 5시가 되었당 아 잘 쉬었다

근데 일단 저 stack 어쩌구는 좀 더 시간 여유로울 때 따로 더 파보도록 해야할듯.ㅎ

지금 나한테너무 어려운 것 같당 주제 파악 해버리기~~


코틀린 기본 문법 강의 4주차

⏲️ 공부 시간 17 : 05 ~ 18 : 00 + 20 : 15 ~ 20 : 30

접근 제한자

변수나 메서드의 접근을 제한하는 키워드

접근 : 객체를 이용해서 변수나 메서드를 호출하는 것

접근 제한자 종류

  • public : 기본 접근 제한자 , 어디서나 접근 가능
  • private : 동일한 클래스 내부에서만 접근 가능
  • internal : 같은 모듈 내부에서만 접근 가능
  • protected : 기본적으로 private 이지만 상속을 받은경우 타 모듈에서 접근 가능

프로젝트>모듈>패키지>클래스

접근제한자가 필요한 이유

  • 접근 권한을 설정해서 데이터에 무분별한 접근을 막을 수 있다.
  • 클래스들간에 접근하면 안되는 상황을 구분해서 유지보수가 용이하다

예외처리 활용

오류와 예외의 차이

오류 : 프로그램 실행 전에 알 수 있는 컴파일 에러

예외 : 프로그램 실행하는 도중에 발생하는 런타임 에러

try catch / throw 로 예외를 처리함

try-catch 문법

fun method() {
	try { 
		예외가 발생할 가능성이 존재하는 코드
		} catch(예외 종류) {
			예외가 발생했을 때 처리할 코드
			}
		}

throw 문법

fun mothod() {
	if(num1>10) {
		throw 예외 종류
	}
}

예외처리가 필요한 이유

  • 프로그램 실행하다가 예외가 발생해서 프로그램이 종료되면 사용하는 사람이 아주 뿔이난다
  • 미리 예외를 생각하고 소스코드를 작성해야 안정성이 높아진다.

finally 활용

finally : try - catch 와 상관없이 항상 실행할 코드를 입력하는 곳

지연초기화

지연 초기화 : 변수나 상수의 값을 나중에 초기화하는것

지연 초기화를 사용하는 이유:

  • 클래스를 설계할 때 초기 값을 정의하기 난처해서
  • 저사양으로 제한되어있는 환경에서 메모리를 효율적으로 사용하기 위해서

지연 초기화 하는 방법 :

  • lateinit , lazy 키워드를 사용해서 할 수 있음

변수의 지연 초기화를 할 때에는 lateinit 사용

변수를 지연초기화해서 사용할 때에는 초기화가 잘 되었는지 확인해주어야함

  • isInitialized 를 통해서 할 수 있다.
  • if(this::name.isInitialized)하면 된당

상수의 지연 초기화를 할 때 에는 lazy 키워드를 사용

Null Safety

코틀린은 Null예외로부터 안전한 설계를 위해 자료형에서 Null 여부를 명시할 수 있다.

자료형? : 해당 변수에 Null을 저장할 수도 있다는 뜻

!! : Null이 아님을 보장하는 키워드

?.어쩌구 : (안전 호출 연산자) Null인지 확인하고 Null이 아닐 때만 참조하는 메서드

?: : (앨비스 연산자) Null대신에 다른 문자열을 출력하는 키워드

Set

Set.Union(anotherSet) : 두 Set의 합집합

Set.interest(anotherSet) : 두 Set의 교집합

Set.substract(anotherSet) : 두 Set의 차집합

Single-expression function

람다식을 이용해서 메서드를 간결하게 정의 가능함

{매개변수1, 매개변수 2… → 코드}


기초문법 특강 - 이종범 튜터님

⏲️ 공부시간 19 : 00 ~ 20 : 15

클래스와 함수 등에 대해서 다시한번 배우고,

클래스의 상속과 추상클래스 등에 대해서 다시 배우는 시간 이였당.

근데 밥먹고 바로 들으니까 자꾸 하품이 나와버림..

하품하다 딱 들켜서 튜터님이 20분바께안됐는데 벌써 하품하냐고하심

재미없어서 하품한거아니에영..그냥…밥먹고오면 어쩔수업서요..ㅜ

후 실시간 강의 들을때마다 ㄹㅇ ADHD 의심된다.

타이핑 안하고 가만히 있으면 손이랑 발을 가만히 둘수가 없어버림

사실 그 의존성 역전 법칙에서 의존성 주입에 대해서 아무리봐도 어려워서 이부분이 많이 나오길바랬는데 끝에 살짝만 다루고 잘 몰라도 된다고 하셔서 똥싸다만 느낌이긴했는데 어쩔수업징..

의존성 주입 하는 방식은 따로 혼자 공부 더 해야겠당.


TMI

맨날 열심히 하는 것 같은데 공부할게 계속 쌓여간다ㅎㅎㅎ
오늘도 Layout 공부를 못해버렸당~~ ㅎㅎ
강의 5주차도 못들었음~! 왤캐 못했찌?
그래도 쪼금씩 늘겠지머~ 급하게 먹으면 체하니깐 천천히 먹는거임 ㅋㅋ

profile
오리너구리입니다

0개의 댓글