[자료구조 파헤치기] Stack구조란


간만에 자료구조나 뒤집어엎어보자는 생각에 하나씩 다뤄볼까 싶어서 한번 꺼내봤습니다.

아마 버전은 시간나는 틈틈이 제가 다룰 수 있는 모든 언어로 다뤄볼 예정입니다.

 

그럼 우선 첫번째로 Stack구조는 어떤형식의 구조인지를 한번 파악해보시죠.

이거 하나만 알면 됩니다. LIFO!

 

LIFO

LIFO의 의미는 후입선출(Last In First Out)이라는 의미로 맨 마지막에 들어온(Push) 데이터가 처음으로 빠져나간다고(Pop) 보시면 됩니다.

 

조금 쉽게 생각을 해보자면 창고에 박힌 상자를 생각해보시면 될 것 같습니다.

창고에 아래서부터 차근차근 상자를 쌓아 올려놨다면, 상자를 꺼내기 위해서는 맨 위에 있는 상자부터 꺼내게 될겁니다.

 

백문이 불여일견. 말보다는 눈으로 직접 보면서 설명드리겠습니다.

데이터를 넣고(Push) 빼는(Pop) 작업을 잘 확인해보세요!

 

 - 아래 보시는 이미지는 Stack과 데이터 A, B, C를 준비했습니다.

Stack의 구조

 

 - Stack에 데이터 A를 넣고, (Push)

A를 Stack에 Push

 

- 다시한번 더 데이터 B를 Stack에 넣습니다. (Push)

B를 Stack에 Push

 

 - 그럼 A와 B가 들어간 Stack에서 데이터를 뺀다면 어떤 데이터가(A?, B?) 빠져나올까요? (Pop)

Stack에서 Pop을 한다면

 

 - 정답은 B입니다.

  -> Stack은 LIFO. 즉, Last In First Out이기 때문에 맨 마지막에 들어간(Push) 데이터가 나오는(Pop) 형식입니다.

Stack에서 Pop을 한다면 데이터 B가 나옵니다.

 

 - 계속해서 진행을 해보면 C라는 데이터를 넣고(Push) 뺀다면(Pop) 이 또한 맨 마지막에 들어온(Push) C가 나오는(Pop) 형식입니다. (Last In First Out)

Stack에 데이터 C를 Push 후 Pop을 하면 데이터 C가 나옵니다.

 

- 마지막으로 데이터를 뺀다면(Pop) B-C-A 순으로 나오게 됩니다.

B-C-A순으로 데이터가 나옵니다.(Pop)

 

항상 맨 마지막에 들어온 데이터가 맨 처음으로 나온다는걸(LIFO - Last In First Out) 잘 기억해주세요.

이 LIFO만 잘 이해 하셨다면 Stack구조는 다 이해하신겁니다!

 

 # Stack을 소스로 만들어 보기

  ▷ JAVA-List : [자료구조]Java로 Stack 구현해보기 (List 활용) -> 링크로 이동

 

 

** 그림에 사용된 글자체는 네이버 나눔글꼴의 나눔스퀘어 Bold입니다.

 

버전정보 (v1.1)

 - v1.0 2020.06.17 배포

 - v1.1 2020.06.23 내용 추가

 

* 저작권에 위반될 수 있는 컨텐츠(이미지, 동영상 등)나 게시글은 삭제되거나 수정될 수 있습니다.

* 문제의 여지가 될 수 있는 컨텐츠의 경우 댓글 달아 주시면 빠른 시일 내에 조치하도록 하겠습니다.

 

Karzin

abbeea@naver.com

 

 

 


[Kotlin, Java] Android 10에서 파일 엑세스가 되지 않는 문제 해결

- EPERM 오류 해결하기 -


얼마전 개발 테스트 진행중 Android 8이나, Android 9에서 잘만 읽기/쓰기가 되던 파일이 Android 10에서 구동을 하니 에러만 열심히 뿜어내고 저장이 안되는 문제가 있었습니다.

로그창을 확인해보니 EPERM 오류를 뿜어내고 있었고, 저장이 되지않아 곤란해 하고 있었습니다.

특히 테스트를 하며 확인되었지만, READ_EXTERNAL_STORAGE 및 WRITE_EXTERNAL_STORAGE 권한을 유저에게 승인받고 있어서 유독 Android 10에서만 생기는 문제로 파악이 되었죠.

오늘은 이런 Android10으로 올라가면서 파일에 대한 읽기 쓰기가 되지않는 문제에 대해 다뤄보겠습니다.

 - 원인과 해결

Android 10 부터는 외부 저장소 액세스에 대해서 제한을 걸어두는 모양입니다.

해당 제한을 풀기 위해서는 AndroidManifest.xml에 requestLegacyExternalStorage의 값을 true로 설정해주어야합니다. (Android 10 이상을 타겟팅으로 하는 앱의 경우)

<manifest ... >

  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
  <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
  
  <!-- This attribute is "false" by default on apps targeting
  Android 10 or higher. -->
  <application 
  	android:requestLegacyExternalStorage="true" ... >
    
  ...
  
  </application>
</manifest>

 

* Android 10 이상에서는 외부저장소에 접근을 하기위해 requestLegacyExternalStorage 속성을 꼭 넣어주시기 바랍니다.

** 다만 해당 방법이 완벽히 해결을 할 수 있는 방법은 아니며, 추후 업데이트 되는 Android 버전에서는 동작하지 않을수 있으니 주의해주시기 바랍니다.

 

 - 참조

https://developer.android.com/training/data-storage/files/external-scoped?hl=ko#opt-out-of-scoped-storage

 

범위가 지정된 외부 저장소 액세스 관리하기  |  Android 개발자  |  Android Developers

사용자에게 파일의 더 많은 권한을 제공하고 파일이 복잡해지는 것을 제한하기 위해, Android 10(API 레벨 29) 이상을 타겟팅하는 앱은 외부 저장소로 범위가 지정된 액세스 또는 범위 지정 저장소��

developer.android.com

버전정보 (v1.0)

 - v1.0 2020.06.12 배포

 

* 저작권에 위반될 수 있는 컨텐츠(이미지, 동영상 등)나 게시글은 삭제되거나 수정될 수 있습니다.

* 문제의 여지가 될 수 있는 컨텐츠의 경우 댓글 달아 주시면 빠른 시일 내에 조치하도록 하겠습니다.

 

Karzin

abbeea@naver.com


파이썬(Python)이란?

- 특징, 문법 등 -


딥러닝 관련 소스들을 까 보면 자주 Python 언어를 접해볼 수 있습니다.

특히 요즘에는 Django 장고라고 해서 Python 기반의 웹 프레임워크로 웹 개발을 하는 경우도 많이 보이더라고요.

장고의 느낌은 Java 개발자 분들께는 스프링 프레임워크를 생각하시면 아! 그렇구나 하실 것 같습니다.

오늘은 Python이란 언어를 잠깐 공부해볼까 합니다.

맛보기형식으로 이렇다는 식으로 저도 공부해볼겸 겸사겸사 정리 해보았습니다.

 

> 특징

Python이란 언어는 인터프리터 언어로 한 줄씩 소스코드를 해석해서 바로 돌려 결과를 확인할 수 있는 언어입니다.

(친한 지인분 중에는 이를 보곤 근본 없는 언어라며 싫어하기도...)

 

> 진입장벽

언어는 쉬운 편에 속하고, 주변에서도 쉽고 편리하다는 말은 많이들 하지만..

Java, Swift, Kotlin, C# 등등.. python이란 언어 자체가 어려운 건 아닌데 인터프리터 방식을 거의 사용해본 적이 없다 보니 불편한 느낌은 조금 드네요 ㅠㅠ

특히 Kotlin이나 Swift처럼 세미콜론(;) 안 넣는 거 불편..

 

> 사용방법

Ubuntu와 같은 Linux 사용자는 운영체제를 설치하면 기본적으로 Python이 설치되어 있습니다.

제가 개인 서버로 사용 중인 Ubuntu 18.04 버전에도 Python 3.6.9 버전이 설치되어 있습니다.

Ubuntu에서는 명령어에 python3을 입력해보시면 바로 실행이 됨을 확인하실 수 있습니다.

만일 설치되어 있는 python3의 버전을 알고 싶다면 python3 -V를 명령어 창에 입력하시면 됩니다.

 

Windows의 경우 Python 홈페이지의 다운로드 페이지를 이용하면 금방 설치하실 수 있습니다.

(installer를 받으시면 금방 설치됩니다.)

 

최신 버전으로는 3.8.1 버전 (2020년 6월 12일 00시 기준)이며, 현재 3.9.0 베타 버전이 테스트 중에 있습니다.

 

예전에 어디서 들은 바로는 너무 최신 버전의 경우 호환되는 api가 조금씩 달라져 문제가 생길 수 있다고 하니 최신 버전보다는 적당한 옛날 버전(...)을 설치하시는 걸 추천합니다.

 

> 응용

Python은 앞에서 나온 것처럼 장고라는 프레임워크를 이용하시면 웹 프로그래밍이 가능하고, R언어 대용으로 데이터 분석이나 머신러닝, 딥러닝 등에 응용하기도 합니다.

 

> 문법

문법의 경우 기나긴 설명보다는 한번 보는 예제가 좋을 듯하여 예제 소스를 보여드리겠습니다.

 

 - 변수

Python에는 변수 타입이 존재하지 않습니다.

오로지 객체라고만 생각하시면 됩니다.

예를 들어 Java의 경우 int형의 변수 x에 1이라는 숫자를 담는 것 처럼하고 싶으시다면 타입의 명시 없이

x = 1과 같은 형식으로 변수에 숫자를 대입시킬 수 있습니다. (Kotlin과 비슷한)

 

Python의 경우 :(콜론)을 통해 코드가 이어짐을 알려주고, 이어지는 소스에 대해서는 앞에 >>>가 아닌 ...으로 변경됨을 확인하실 수 있습니다.

또한 지금까지 작성된 소스의 내용을 확인하고 싶으시다면 엔터를 한번 더 침으로써 결과를 확인할 수 있습니다.

(이는 리눅스 터미널창등에 실행하는 인터프리터 방식을 얘기하며, 개발할 소스가 가볍고 몇 문장이 안 되는 경우 터미널 등의 인터프리터 방식을, 그렇지 않다면 파이 참등의 IDE를 사용하시기를 권장합니다.)

 

 - if문

아래 예제는 변수 x에 1을 대입하고, x의 값이 1인 경우 "x는 1입니다."라는 문장을 보이게 하는 if문 예제 소스입니다.

>>> x = 1
>>> if x == 1 :
...  print("x는 1입니다.")

a는 1입니다.

 

 - for문

아래 예제는 변수 x에 문자열 "abc"를 대입하고, x의 값을 하나씩 프린트하는 for문 예제 소스입니다.

>>> for x in "abc" :
...  print(x)

a
b
c

 

 - while 문

아래 예제는 변수 i를 0부터 시작하여 4가 될 때까지 "test"라는 문자열을 print 하는 while문 예제 소스입니다.

>>> i = 0
>>> while i < 5 :
...  i=i+1
...  print("test")

test
test
test
test
test

 

 - 함수 선언

kotlin의 fun이나 javaScript의 function처럼 def를 사용하여 함수임을 선언해줍니다.

아래 예제는 a라는 매개변수를 통해 myPrint라는 수식어를 붙여 print 하는 함수 예제 소스입니다.

>>> def myPrint(a) :
...  print("myPrint_"+a)

>>> myPrint("Test!!!")
myPrint_Test!!!

 

기타 연산 방식은 우리가 아는 방식들과 크게 다르지 않는다는 거 기억하시면 금세 배우실 수 있습니다.

 

> Python 패키지 설치

파이썬 라이브러리를 설치할 때에는 pip를 사용합니다.

Ubuntu의 apt를 연상케 하는데, apt처럼(apt install <패키지명>) pip install <패키지명>을 이용하시면 됩니다.

리눅스의 apt처럼 pip 또한 패키지를 설치함에 있어 무궁무진하다는 느낌이 많이 듭니다.

특히 python 개발자가 많아지는 만큼 많은 패키지가 있어 골라먹는 재미도 느낄 수 있죠.

 

> IDE

 - PyCharm

 - Visual Studio Code

 - Visaul Studio 2019

등등..

 

확장자는 .py이며, vim과 같은 텍스트 편집기에서 편집 후 실행을 시켜도 됩니다.

 

저는 주로 Visaul Studio Code 및 터미널창(...)을 씁니다.

 

* 저작권에 위반될 수 있는 컨텐츠(이미지, 동영상 등)나 게시글은 삭제되거나 수정될 수 있습니다.

* 문제의 여지가 될 수 있는 컨텐츠의 경우 댓글 달아 주시면 빠른 시일 내에 조치하도록 하겠습니다.

 

Karzin

abbeea@naver.com


[Java]안드로이드 권한요청 class


 

어플을 개발하다보면 권한요청을 해야하는 경우가 많이 생깁니다.

특히 센서나, 저장소의 권한을 요청하는 경우가 많은데 이를 조금 더 편하게 사용할 수 있도록 Class로 만들었습니다.

사용방법은 심플합니다.

프로젝트에 .class 파일 넣어주고! 객체 생성해서! 함수한번 실행해주면 끝나게 만들어놨습니다!

(혼자 쓰다가 같이 쓰면 좋을것 같아서..)

 

Github 권한요청 Class : https://github.com/dawon-karzin/Android_PermissionCheck_Java

 

dawon-karzin/Android_PermissionCheck_Java

안드로이드 권한 요청 클래스입니다.(java). Contribute to dawon-karzin/Android_PermissionCheck_Java development by creating an account on GitHub.

github.com

 -> 버그등은 이슈로 남겨주시면 빠른시일내에 수정토록하겠습니다.

 

 - 구조

  • 클래스명 : PermissionCheck
  • 생성자 파라미터 : Activity
  • 내부 함수 :
    •   check(List<String>)
    •   permissionGranted()
  • 실행 방식 :
    • PermissionCheck 객체 생성(생성시 현 Activity를 매개변수로 전달)
    • 권한 요청을 받아야하는 List를 전달하여 check함수 실행
    • check함수 내에서 매개변수로 전달받은 List를 확인하여 권한이 부여되지 않은(Denied) 권한을 List로 생성
    • 이후 permissionGranted 함수를 실행하여 권한이 부여되지 않은(Denied) 권한에 대하여 요청(request)을 함
  • 사용 방법 :
    •   permission처리를 할 activity 상속 클래스에서 PermissionCheck 클래스 선언.
    •   check함수(파라미터로 permission 리스트를 전달) 사용함으로써 유저에게 권한요청 실행
//권한요청을 받을 List 생성
List myPermission = Arrays.asList( new String[]{ Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE});

//권한요청 class 생성 (생성시 지금의 Activity를 매개변수로 전달)
PermissionCheck permissionCheck = new PermissionCheck(this); 

//권한요청 시작(권한요청을 받아야하는 List를 매개변수로 전달)
permissionCheck.check(myPermission);

 

-> 개인적으로 개발할때 class 옮겨가며 사용하는 중인데, 생각해보니 permissionDeniedList 변수를 왜 전역으로 선언 했는지 기억이 안나네요;; 무언가 이유가 있었던 것 같은데....... 졸면서 해서그런가;;; (나중에 생각나면 업데이트 해놓겠습니다.)

 

 

* 저작권에 위반될 수 있는 컨텐츠(이미지, 동영상 등)나 게시글은 삭제되거나 수정될 수 있습니다.

* 문제의 여지가 될 수 있는 컨텐츠의 경우 댓글 달아 주시면 빠른시일내에 조치하도록 하겠습니다.

 

Karzin

abbeea@naver.com

 


[Ubuntu] alias(별명) 만들어주기


Linux(Ubuntu)를 활용하다보면 편리하게 사용하기 위해 alias를 지정해주는것이 좋습니다.

 

오늘은 alias(별명) 만들어주는 방법을 소개하겠습니다.

 


- 우선 커멘드창을 띄워 bashrc에 등록되어 있는 aliases를 확인해봅니다.

 

vim .bashrc​

 

 

특별히 기존에 있던 설정을 건드린게 없다면 90줄에 #some more ls aliases가 보일겁니다.

 

90줄 아래(#some more ls aliases)줄에는 ll, la, l 명령어의 alias가 지정되어있습니다.

이는 커맨드창을 통해 ls -alF를 입력하는 것을 ll이라는 alias(별명)를 지정함으로써 명령어를 더욱 간편하게 사용하기 위한 방법을 제공해주는 것인데요,

실제로 ll과 ls -alF를 비교해보겠습니다.

 > 실제로 두 명령어가 같다는 것을 확인할 수 있습니다.

 

또한 사용자는 99줄에 #Alias definitions에 등록된 파일에 alias를 지정해주면 되는데요,

아마 특별한 설정을 건드리지 않았다면 .bash_aliases 파일은 생성이 안되어 있어 사용자가 직접 만들어야합니다.

 

 - .bash_aliases 파일 생성하기

vim .bash_aliases

 

- alias(별명)를 지정할 명령어 선언 (저는 예시로 python3를 python으로 등록하겠습니다.) 

  --> 참고로 아래 #의 의미는 주석처리입니다.

#python3
alias python='python3'

> 저장을 해줍니다.

 

- 저장 후 설정한 alias(별명)를 커맨드창에 입력 후 실행하면 지정된 alias가 잘 동작함을 확인할 수 있습니다.

 

> 만일 저장하고도 동작이 되지 않는다면 alias를 지정한 계정으로 재접속 해주세요.

 

 

 

 

* 저작권에 위반될 수 있는 컨텐츠(이미지, 동영상 등)나 게시글은 삭제되거나 수정될 수 있습니다.

* 문제의 여지가 될 수 있는 컨텐츠의 경우 댓글 달아 주시면 빠른시일내에 조치하도록 하겠습니다.


[Kotlin, JAVA]

밀리세컨드 단위 시간 구하기


간혹 파일명을 만든다던가하는 특수한 경우마다 중복이 일어나지 않기 위해 밀리세컨드 단위의 시간을 구해야하는 경우가 있습니다.

(키값이 중복되지 않는다는 점에선 가장 편한 방법일지도 모르겠지요. 주요 예로는 파일의 저장(영상, 사진) 등)

 

 - Kotlin 현재 시간 구하기

System.currentTimeMillis()

val testTime = "${System.currentTimeMillis()}"

 

 - JAVA 현재 시간 구하기

System.currentTimeMillis();

String testTime = String.valueOf(System.currentTimeMillis());

 

return type는 long형입니다.

 

 *** Reference : https://developer.android.com/reference/java/lang/System#currentTimeMillis()

 

System  |  Android 개발자  |  Android Developers

System public final class System extends Object java.lang.Object    ↳ java.lang.System The System class contains several useful class fields and methods. It cannot be instantiated. Among the facilities provided by the System class are standard input, stand

developer.android.com

 *** 소스에 문제가 있을 시 댓글달아주시면 최신화하도록 하겠습니다. 감사합니다

 


[Kotlin]Handler 이용하여 메인 UI 건드리기

(메인 쓰레드 제어하기)


Timer등을 설정해서 로직을 돌리다보면 이벤트에 따라 UI가 변경되어야하는 경우가 있습니다.

 

쉽게말해 UI를 건드리기 위해 서브쓰레드에서 메인쓰레드를 제어한다는건데, 여기서는 Timer를 실행했을때를 예시로 들겠습니다.

 

 - Timer를 통해 i를 증가시키기

private fun timerTest() {
  var i = 0
  myTimer = timer(period = 1000) {
    i++
    handlerTest(i)
  }
}​

  > 위처럼 타이머를 설정하여 1초(period=1000)마다 i를 증가시킨다는 예시를 들겠습니다.

 

 - Handler를 생성하여 UI를 바꿔주기

private fun handlerTest(msg:Int) {
    val handler : Handler = object : Handler(Looper.getMainLooper()) {
        override fun handleMessage(inputMessage: Message) {
            timer_text.setText(msg)
        }
    }
    handler.obtainMessage().sendToTarget()
}

 

  > timerTest 함수에서는 i를 증가시켜 handlerTest 함수에 해당 i값을 매개변수로 넘겨주어 메인쓰레드(UI)를 제어하는 형식입니다.

  > 위 함수에서는 timer_text(TextView)에 1씩 증가시켜 UI단에서 보이게 해줍니다.

 

 *** Reference : https://developer.android.com/reference/android/os/Handler?hl=en

 

Handler  |  Android 개발자  |  Android Developers

Handler public class Handler extends Object java.lang.Object    ↳ android.os.Handler A Handler allows you to send and process Message and Runnable objects associated with a thread's MessageQueue. Each Handler instance is associated with a single thread and

developer.android.com

 *** 소스에 문제가 있을 시 댓글달아주시면 최신화하도록 하겠습니다. 감사합니다.

 


[Kotlin]Toast 사용하기


간혹 유저에게 간단한 메세지를 전달해주기위해 Toast를 사용하는 경우가 있습니다.

이런 경우를 위해 Kotlin에서의 Toast 사용법을 알아보겠습니다.

 

- 기본 형태

Toast.makeText(context, text, duration).show()

 > context(Context)는 현재 Activity의 context를 전달해주시면 되며,

 > text(String)는 Toast에 띄우고 싶은 String형식의 text를,

 > duration(Int)은 Toast를 얼마나 긴 혹은 짧은 시간동안 보이게하고 싶은지를 의미합니다.

 > duration의 경우 Toast.LENGTH_SHORT 및 Toast.LENGTH_LONG을 사용할 수 있으며 각각 0과 1로 대치됩니다. (즉, 0 혹은 1로 넣어도 동작)

 > SHORT는 4000ms(4초), LONG은 7000ms(7초) 입니다.

 

 > *makeText 후 show를 사용하지 않으면 Toast는 보이지 않습니다.

 

 - 예시

Toast.makeText(this, "토스트 테스트_짧게", Toast.LENGTH_SHORT).show()
Toast.makeText(this, "토스트 테스트_길게", Toast.LENGTH_LONG).show()

위는 비교적 간단한 예시이며, duration부분의 SHORT와 LONG의 차이로 Toast를 짧은 시간 혹은 긴 시간동안 보이게 해주는 예시입니다.

 

 - 간단하게 함수를 이용하여 Text만 받아 사용하기

private fun shortToast(text:String) {
	Toast.makeText(this, text, Toast.LENGTH_SHORT).show()
}

private fun longToast(text:String) {
	Toast.makeText(this, text, Toast.LENGTH_LONG).show()
}

 - 사용법 :

  shortToast("안녕! Karzin!")

  longToast("안녕! Karzin!")

 

 *** Reference : https://developer.android.com/reference/android/widget/Toast

 

Toast  |  Android 개발자  |  Android Developers

Toast public class Toast extends Object java.lang.Object    ↳ android.widget.Toast A toast is a view containing a quick little message for the user. The toast class helps you create and show those. When the view is shown to the user, appears as a floating

developer.android.com

 *** 소스에 문제가 있을 시 댓글달아주시면 최신화하도록 하겠습니다. 감사합니다.

+ Recent posts