<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>We are Creators</title>
    <link>https://edcan.tistory.com/</link>
    <description>선린인터넷고등학교 모바일 콘텐츠 동아리, EDCAN의 이야기입니다.</description>
    <language>ko</language>
    <pubDate>Wed, 8 Apr 2026 04:57:10 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>EDCAN</managingEditor>
    <image>
      <title>We are Creators</title>
      <url>https://tistory1.daumcdn.net/tistory/5818152/attach/9ea0d5c68eb443b68e2348f98d2da679</url>
      <link>https://edcan.tistory.com</link>
    </image>
    <item>
      <title>Android 인터넷에서 데이터 가져오기 Codelab 정리</title>
      <link>https://edcan.tistory.com/16</link>
      <description>&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;p&gt;이 글은 Google Codelab &lt;strong&gt;인터넷에서 데이터 가져오기&lt;/strong&gt;를&lt;br&gt;학습하고 정리한 글 입니다.&lt;/p&gt;
&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;최근 레트로핏을 사용한지 오래 됐고 문법이 기억나지 않아서&lt;br&gt;Google Codelab에서 레트로핏을 공부했다. &lt;a href=&quot;https://developer.android.com/codelabs/basic-android-kotlin-training-getting-data-internet#0&quot;&gt;해당 코드랩&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;이 글은 공부한 내용을 정리한 글이다.&lt;/p&gt;
&lt;h2&gt;예제 앱 보기&lt;/h2&gt;
&lt;p&gt;이 앱은 화성 표면의 이미지르 받아와서 보여주는 앱니다.!&lt;br&gt;&lt;img src=&quot;https://velog.velcdn.com/images/ckstmznf/post/e8d1c2f2-34e8-4089-86bf-26bc9b545c3b/image.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;이 앱은 &lt;a href=&quot;https://github.com/google-developer-training/android-basics-kotlin-mars-photos-app&quot;&gt;이 프로젝트의&lt;/a&gt; starter 브랜치를 학습하면 된다.&lt;/p&gt;
&lt;h2&gt;Retrofit 의존성 추가하기&lt;/h2&gt;
&lt;p&gt;외부 라이브러리를 프로젝트에 추가하기 위해서는 라이브러리가 호스팅 되는,&lt;br&gt;즉 라이브러리를 받아오는 저장소를 추가해줘야 한다.&lt;/p&gt;
&lt;p&gt;build.gradle(Project)에 repositories에 다음과 같은 코드를 추가해준다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-kotlin&quot;&gt;repositories {
   google()
   jcenter()
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;각각 google과 JCenter라는 커뮤니티에서 라이브러리를 받아오는 것이다.&lt;/p&gt;
&lt;p&gt;라이브러리를 가져오기 위해서 build.gradle(app)에 dependencies 섹션에 다음과 같은 코드를 추가해준다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-kotlin&quot;&gt;// Retrofit
implementation &amp;quot;com.squareup.retrofit2:retrofit:2.9.0&amp;quot;
// Retrofit with Moshi Converter
implementation &amp;quot;com.squareup.retrofit2:converter-scalars:2.9.0&amp;quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Sync Now를 눌러준뒤 적용한다.&lt;/p&gt;
&lt;p&gt;Retrofit2와 같이 타사의 라이브러리는 Java8 기능을 사용한다.&lt;br&gt;Android Gradle에는 Java8 기능이 내장되어 있고 이 기능을 사용하기 위해서는 build.gradle(Project)에 다음 코드가 있어야 한다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-kotlin&quot;&gt;android {
  ...

  compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
  }

  kotlinOptions {
    jvmTarget = &amp;#39;1.8&amp;#39;
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Retrofit 서비스 만들기&lt;/h2&gt;
&lt;p&gt;우선 기본적으로 API를 요청할 주소를 상수로 저장해둔다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-kotlin&quot;&gt;private const val BASE_URL = &amp;quot;https://android-kotlin-fun-mars-server.appspot.com&amp;quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;이 주소를 변수로 저장하지 않고 하드코딩해서 사용해도 된다.&lt;br&gt;하드코딩을 한다면 보안상으로 좋지 않을뿐 아니라 나중에 주소가 변경된다면 하나씩 수정해야한다는 불편함이 있다.&lt;/p&gt;
&lt;p&gt;그 다음 Retrofit의 기능이 담겨져있는 객체를 만들어 준다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-kotlin&quot;&gt;private val retrofit = Retrofit.Builder()&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;네트워크에서 받아온 값을 String으로 변경해주는 팩토리가 있어야 한다.&lt;br&gt;팩토리는 네트워크에서 얻은 데이터로 해야할 일을 알려주는 역할을 한다.&lt;br&gt;String으로 변경하기 위햐서는 &lt;strong&gt;ScalarsConverterFactory&lt;/strong&gt;를 사용해준다.&lt;/p&gt;
&lt;p&gt;addConverteFactory()함수를 사용해서 팩토리를 가져와준다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-kotlin&quot;&gt;private val retrofit = Retrofit.Builder()
    .addConverterFactory(ScalarsConverterFactory.create())&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;이 레드토핏 서비스가 어떤 웹 서비스에 접근해서 데이터를 가져올 것인지를 명시하기 위해서&lt;br&gt;baseUrl() 함수를 사용해서 기본 URL을 추가해준다.&lt;br&gt;아까 상수로 저장한 BASE_URL을 사용한다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-kotlin&quot;&gt;private val retrofit = Retrofit.Builder()
   .addConverterFactory(ScalarsConverterFactory.create())
   .baseUrl(BASE_URL)
   .build()&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Retrofit이 웹 서버와 통신하는 방법을 정의해줘야 한다.&lt;br&gt;이말은 BASE_URL의 어떤 경로에 접속할지를 정의하는 것이다.&lt;/p&gt;
&lt;p&gt;인터페이스를 만들고 함수를 만들어 준다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-kotlin&quot;&gt;interface MarsApiService {

}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;이 인터페이스에 함수를 만들어주고 해당 함수가&lt;br&gt;어떤 방법으로 어떤 경로에 접속하는 것인지를 정의한다.&lt;/p&gt;
&lt;p&gt;네트워크 통신을 하면 시간이 딜레이 되기 때문에 suspend 함수로 만들어준다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-kotlin&quot;&gt;interface MarsApiService {
    @GET(name = &amp;quot;photos&amp;quot;)
    suspend fun getPhotos() : String
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;getPhotos() 함수를 &lt;strong&gt;GET&lt;/strong&gt;방식의 &lt;strong&gt;photos&lt;/strong&gt;으로 지정했다.&lt;/p&gt;
&lt;p&gt;base url이 &lt;strong&gt;&lt;a href=&quot;https://android-kotlin-fun-mars-server.appspot.com&quot;&gt;https://android-kotlin-fun-mars-server.appspot.com&lt;/a&gt;&lt;/strong&gt;이니&lt;br&gt;getPhotos() 함수를 호출하면 GET 방식으로 &lt;a href=&quot;https://android-kotlin-fun-mars-server.appspot.com/photos&quot;&gt;https://android-kotlin-fun-mars-server.appspot.com/photos&lt;/a&gt; 경로로 요청을 보내게 된다.&lt;/p&gt;
&lt;p&gt;반환값으로 String을 넣어 줬는데 위에서 ScalarsConverterFactory를 사용해서&lt;br&gt;네트워크 요청 결과를 String으로 만들어 줬기 때문에 이 결과가 반환된다.&lt;/p&gt;
&lt;h2&gt;Retrofit 객체 만들기&lt;/h2&gt;
&lt;p&gt;싱글톤 패턴으로 객체 하나를 만들어주기 위해서 object를 만들어 준다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-kotlin&quot;&gt;object MarsApi {
    val retrofitService : MarsApiService by lazy {
       retrofit.create(MarsApiService::class.java)
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;이 object에는 retrofitService 변수가 있고 이 변수를 호출하면 늦은 초기화로&lt;br&gt;위에서 만들어준 retrofit 객체에 create() 함수를 사용해서 만들어준다.&lt;br&gt;이때 통신하는 법을 정의해준 인터페이스를 같이 넣어주게 된다.&lt;/p&gt;
&lt;h2&gt;만들어준 Retrofit을 ViewModel에서 호출하기&lt;/h2&gt;
&lt;p&gt;지금까지는 Retrofit을 사용하기 위해서 사전 세팅을 해줬다면 이제는&lt;br&gt;ViewModel에서 Retrofit을 호출해서 사용해준다.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;viewModel에 데이터를 불러오는 함수를 만들고 ViewModelScope를 열어준다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-kotlin&quot;&gt;private fun getMarsPhotos() {
    viewModelScope.launch {

    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;이 ViewModelScope안에서 Retrofit 서비스의 getPhotos() 함수를 사용해준다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-kotlin&quot;&gt;private fun getMarsPhotos() {
    viewModelScope.launch {
        val listResult = MarsApi.retrofitService.getPhotos()
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;이 코드의 결과로 listResult가 &lt;a href=&quot;https://android-kotlin-fun-mars-server.appspot.com/photos&quot;&gt;이 링크&lt;/a&gt;로 요청한 결과가 String으로 들어오게 된다.&lt;/p&gt;
&lt;h2&gt;에러및 예외 처리&lt;/h2&gt;
&lt;p&gt;앱을 실행하면 다음과 같은 에러가 발생한다.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    --------- beginning of crash
22803-22865/com.example.android.marsphotos E/AndroidRuntime: FATAL EXCEPTION: OkHttp Dispatcher
    Process: com.example.android.marsphotos, PID: 22803
    java.lang.SecurityException: Permission denied (missing INTERNET permission?)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;이 에러는 앱에 인터넷 권한을 허용하지 않아서 발생하는 에러이다.&lt;/p&gt;
&lt;p&gt;manifest에서 다음 코드를 추가해줘서 인터넷 권한을 추가해준다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-xml&quot;&gt;&amp;lt;uses-permission android:name=&amp;quot;android.permission.INTERNET&amp;quot;/&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;이 권한을 추가하고 다시 빌드하면 다음과 같이 결과가 잘 나온다.&lt;br&gt;&lt;img src=&quot;https://velog.velcdn.com/images/ckstmznf/post/be6c4ad7-4ee1-4185-bc83-669066710097/image.png&quot; width=&quot;400px&quot;/&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;하지만 인터넷이 꺼져 있는 상황에서 앱을 실행하면 다음과 같은 에러가 발생해서 앱이 꺼진다.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;3302-3302/com.example.android.marsphotos E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.android.marsphotos, PID: 3302
    java.net.SocketTimeoutException: timeout&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;이런 경우를 위해서 예외처리를 사용한다.&lt;br&gt;ViewModel에서 try-catch 문을 사용해서 네트워크 요청을 보낸다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-kotlin&quot;&gt;viewModelScope.launch {
   try {
       val listResult = MarsApi.retrofitService.getPhotos()
       _status.value = listResult
   } catch (e: Exception) {
        _status.value = &amp;quot;Failure: ${e.message}&amp;quot;
   }&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;인터넷이 꺼져 있는 등 네트워크 통신을 할수 없는 상황이라면 앱이 거지는게 아니라&lt;br&gt;다음과 같은 결과가 나온다.&lt;br&gt;&lt;img src=&quot;https://velog.velcdn.com/images/ckstmznf/post/e93506ff-fea4-409a-a95e-eb719ec46b49/image.png&quot; width=&quot;400px&quot;/&gt;&lt;/p&gt;
&lt;h2&gt;네트워크 요청 결과를 객체로 만들기&lt;/h2&gt;
&lt;p&gt;현재 코드의 문제점은 요청 결과 Json을 String으로 변환해서 사용하는 것이다.&lt;/p&gt;
&lt;p&gt;String으로 변환하면 데이터를 사용할 수 없으니&lt;br&gt;Moshi를 사용해서 Json으로 객체로 만들어서 사용한다.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;build.gradle(app)에 다음 코드를 추가한다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-kotlin&quot;&gt;// Moshi
implementation &amp;#39;com.squareup.moshi:moshi-kotlin:1.9.3&amp;#39;&lt;/code&gt;&lt;/pre&gt;
&lt;br&gt;

&lt;p&gt;위에서 추가한 레드로핏을 Moshi와 호환되는 라이브러리로 변경해준다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-kotlin&quot;&gt;// Retrofit
implementation &amp;quot;com.squareup.retrofit2:retrofit:2.9.0&amp;quot;
// Retrofit with Moshi Converter
implementation &amp;quot;com.squareup.retrofit2:converter-scalars:2.9.0&amp;quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;이 코드를 삭제하고&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-kotlin&quot;&gt;// Retrofit with Moshi Converter
implementation &amp;#39;com.squareup.retrofit2:converter-moshi:2.9.0&amp;#39;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;이 코드로 변경한다.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;현재 Json은 다음과 같은 형식을 가지고 있다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-json&quot;&gt;[
  {
    &amp;quot;id&amp;quot;: &amp;quot;424905&amp;quot;,
    &amp;quot;img_src&amp;quot;: &amp;quot;https://mars.jpl.nasa.gov/msl-raw-images/msss/01000/mcam/1000MR0044631300503690E01_DXXX.jpg&amp;quot;
  },
  {
    &amp;quot;id&amp;quot;: &amp;quot;424906&amp;quot;,
    &amp;quot;img_src&amp;quot;: &amp;quot;https://mars.jpl.nasa.gov/msl-raw-images/msss/01000/mcam/1000ML0044631300305227E03_DXXX.jpg&amp;quot;
  },
]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Json객체가 id와 img_src의 키로 규칙적으로 반복되고&lt;br&gt;이 객체들이 Json List에 담겨있다.&lt;/p&gt;
&lt;p&gt;Json객체를 Kotlin의 data class로 만들어 준다.&lt;br&gt;그리고 Moshi를 사용해서 자동으로 변환해준다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-kotlin&quot;&gt;data class MarsPhoto(
   val id: String,
   val img_src: String
)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Json의 id와 img_src의 값이 클래스 맴버 변수의 id와 img_src에 들어가서 객체가 만들어진다.&lt;/p&gt;
&lt;p&gt;Kotlin애서는 변수명을 카멜 케이스로 작성한다.&lt;br&gt;Json 객체의 key값은 img_src이지만 맴버 변수명을 imgSrc로&lt;br&gt;사용하고 싶다면 Json 어노테이션을 사용한다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-kotlin&quot;&gt;data class MarsPhoto(
   val id: String,
   @Json(name = &amp;quot;img_src&amp;quot;)
   val imgSrcUrl: String
)&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;p&gt;현재는 retrofit을 만들 때 팩토리로 &lt;strong&gt;ScalarsConverterFactory&lt;/strong&gt;를 사용하지만 Moshi를 사용하도록 변경해준다.&lt;/p&gt;
&lt;p&gt;우선 moshi 객체를 만들어 준다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-kotlin&quot;&gt;private val moshi = Moshi.Builder()
    .add(KotlinJsonAdapterFactory())
    .build()&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;retforit을 만들때 addConverterFactory 함수를 변경해준다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-kotlin&quot;&gt;private val retrofit = Retrofit.Builder()
   .addConverterFactory(MoshiConverterFactory.create(moshi))
   .baseUrl(BASE_URL)
   .build()&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;retrofit의 결과가 변경됐으니까 MarsApiService 인터페이스의 getPhotos() 함수의 반환값도 변경해준다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-kotlin&quot;&gt;interface MarsApiService {
    @GET(&amp;quot;photos&amp;quot;)
    suspend fun getPhotos() : List&amp;lt;MarsPhoto&amp;gt;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;이제 viewModel에서 호출한 결과로 String이 아닌 데이터 리스트가 들어가게 된다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-kotlin&quot;&gt;val listResult : List&amp;lt;MarsPhoto&amp;gt; = MarsApi.retrofitService.getPhotos()&lt;/code&gt;&lt;/pre&gt;</description>
      <author>Heechan Park</author>
      <guid isPermaLink="true">https://edcan.tistory.com/16</guid>
      <comments>https://edcan.tistory.com/16#entry16comment</comments>
      <pubDate>Wed, 13 Dec 2023 17:06:26 +0900</pubDate>
    </item>
    <item>
      <title>2022년 EDCAN을 마치며 - 학과 발표회 발표 정리</title>
      <link>https://edcan.tistory.com/15</link>
      <description>&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;p&gt;이 글은 2022 선린 소프트웨어과 학교 발표회에서 발표한&lt;br&gt;동아리 발표 - EDCAN 입니다.&lt;/p&gt;
&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;img src=&quot;https://velog.velcdn.com/images/ckstmznf/post/de26e42e-3d1b-4167-b2af-22776ff8ee29/image.png&quot; alt=&quot;학과발표회 배너&quot; width=&quot;700px&quot;/&gt;

&lt;img src=&quot;https://velog.velcdn.com/images/ckstmznf/post/c10fda30-8af7-4e3c-832f-2a39316b70c5/image.png&quot; alt=&quot;학과발표회 발표 모습&quot; width=&quot;700px&quot;/&gt;

&lt;p&gt;2022년 12월 27일 학교에서 학과 발표회를 진행하였다.&lt;br&gt;나는 이번 학과 발표회에서 동아리 발표로 우리 EDCAN 발표를 맡았다.&lt;/p&gt;
&lt;p&gt;이 글은 발표 내용을 정리한 글이다.&lt;/p&gt;
&lt;h1&gt;발표 내용&lt;/h1&gt;
&lt;hr&gt;
&lt;p&gt;&lt;img src=&quot;https://velog.velcdn.com/images/ckstmznf/post/ff061453-93cc-4ee8-8b94-e0cad51a46d0/image.png&quot; alt=&quot;슬라이드 1 - 2022년의 EDCAN을 마치며&quot;&gt;&lt;/p&gt;
&lt;p&gt;올해 2022년은 정말 많은 변화가 있던 한해였습니다.&lt;br&gt;절대 끝나지 않을것 같았던 코로나 팬데믹이 끝을 보이고,&lt;br&gt;학교 행사들도 온라인에서 점차 오프라인으로 돌아왔죠&lt;/p&gt;
&lt;p&gt;이런 많은 변화 속에서 저희 EDCAN이 어떤 활동을 했고,&lt;br&gt;어떤 성과를 거두었으며 어떤 시행착오를 했는지,&lt;br&gt;오늘 이 자리에서 여러분들께 발표하겠습니다.&lt;/p&gt;
&lt;p&gt;2022년의 EDCAN을 마치며 발표를 시작하겠습니다.&lt;/p&gt;
&lt;p&gt;!youtube[jdnadhdfqy8]&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;img src=&quot;https://velog.velcdn.com/images/ckstmznf/post/2efb0eb8-ed2f-4aea-ad0b-2370ffc4e411/image.png&quot; alt=&quot;슬라이드 2 - 올해 EDCAN은 18명의 부원과 함께했습니다.&quot;&gt;&lt;/p&gt;
&lt;p&gt;올해 EDCAN은 18명의 부원과 함께 했습니다.&lt;br&gt;이중 개발자 유닛인 아틀리에 부원이 12명,&lt;br&gt;디자이너 유닛인 픽셀 부원이 6명이었고&lt;/p&gt;
&lt;p&gt;1학년 부원이 11명 2학년 부원이 7명으로 구성되었습니다.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;img src=&quot;https://velog.velcdn.com/images/ckstmznf/post/fe9d0653-56d6-4119-86cb-ec6374045787/image.png&quot; alt=&quot;슬라이드 3 - 올해 EDCAN은 18명의 부원과 함께했습니다.&quot;&gt;&lt;br&gt;이 18명 모두 EDCAN의 크리에이터로서 많은 활동을 해주었고,&lt;br&gt;함께 진행한 동아리 행사, 프로젝트들 모두 성공적으로 마쳤습니다.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;img src=&quot;https://velog.velcdn.com/images/ckstmznf/post/68c40d81-9a31-4e80-8309-c5aaf79eba70/image.png&quot; alt=&quot;슬라이드 4 - 올해 EDCAN은 18명의 부원과 함께했습니다.&quot;&gt;&lt;/p&gt;
&lt;p&gt;부부장으로서 동아리를 이끈 저는 물론&lt;br&gt;함께 한 17명의 부원 모두 이 경험들이&lt;br&gt;소중한 추억과 뜻깊은 경험이 되었습니다.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;img src=&quot;https://velog.velcdn.com/images/ckstmznf/post/df545496-66e8-4c4a-9bdc-203bf97f33f8/image.png&quot; alt=&quot;슬라이드 5 - EDCAN에서 제작한 작품들&quot;&gt;&lt;/p&gt;
&lt;p&gt;올 한해 EDCAN에서는 30여개의 작품을 &lt;strong&gt;창작&lt;/strong&gt;하였습니다.&lt;br&gt;개발자, 디자이너가 아닌 EDCAN의 크리에이터로서&lt;/p&gt;
&lt;p&gt;각자의 분야에 상관 없이&lt;br&gt;각자의 학과에 상관 없이 모두 다양한 작품을 창작을 해주었습니다.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;img src=&quot;https://velog.velcdn.com/images/ckstmznf/post/68ca578a-70b5-4834-811d-d0f8efc832df/image.png&quot; alt=&quot;슬라이드 6 - EDCAN 수상 실적&quot;&gt;&lt;br&gt;이 많은 작품 중에서 대회에서 입상한 우수한 작품들을 소개하겠습니다.&lt;br&gt;부원 모두가 창작자로서 분야에 상관 없이 다양한 대회에 나가서 수상했는데요.&lt;/p&gt;
&lt;p&gt;화면에 나와있는 9개의 수이과 더불어&lt;br&gt;어제 발표가 나왔던 &amp;lt;디지털 콘텐츠 경진대회&amp;gt;에서도 금상과 동상을 수상하며&lt;br&gt;올해 EDCAN은 총 11개의 수상 실적을 거뒀습니다.&lt;/p&gt;
&lt;p&gt;특히 이번 &amp;lt;선린 해커톤&amp;gt;에서는 1학년 중에서는 유일하게 저희 부원들이 수상하면서&lt;br&gt;EDCAN의 밝은 미래를 보여주었습니다.&lt;/p&gt;
&lt;p&gt;여기에 더불어서 작년 한해동안 EDCAN의 기둥이 되어주신 3학년 선배님들 역시&lt;br&gt;&amp;lt;선린 해커톤&amp;gt;과 교외 대회인 &amp;lt;메타버스 경진대회&amp;gt;에서 대상을 수상하시는등&lt;br&gt;EDCAN을 빛내주셨습니다.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;img src=&quot;https://velog.velcdn.com/images/ckstmznf/post/06586049-0870-4a9b-9d59-f27d8447b215/image.png&quot; alt=&quot;슬라이드 7 - EDCAN 활동 사진&quot;&gt;&lt;br&gt;이렇게 많은 수상실적이 있던 반면&lt;br&gt;많은 변화속에서 동아리 운영은 순탄하지 못했는데요.&lt;/p&gt;
&lt;p&gt;코로나로 인한 선배님들과의 단절, 동아리 정체성 이슈등&lt;br&gt;올 2022년은 조금은 아쉬운 한해가 아니었나 생각됩니다.&lt;/p&gt;
&lt;p&gt;그러면 아쉬운 2022년은 마무리하고&lt;br&gt;새로운 2023년을 시작해보겠습니다.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;img src=&quot;https://velog.velcdn.com/images/ckstmznf/post/6ff9dc26-0bba-4648-9a8b-8b49e2b5bc4a/image.png&quot; alt=&quot;슬라이드 8 - 2023년의 EDCAN을 시작하며&quot;&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;img src=&quot;https://velog.velcdn.com/images/ckstmznf/post/53753d88-4d53-4082-aa43-899c7b502f15/image.png&quot; alt=&quot;슬라이드 9 - 10기를 맞아서 찾아오는 변화&quot;&gt;&lt;/p&gt;
&lt;p&gt;이번 2023년은 EDCAN에게는 정말 뜻깊은 한해인데요.&lt;br&gt;이번에 들어오는 신입생들은 10기로 EDCAN이 10주년이 되는 해입니다.&lt;/p&gt;
&lt;p&gt;이런 10주년을 맞아서 저희는 새로운 것들을 준비했습니다.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;img src=&quot;https://velog.velcdn.com/images/ckstmznf/post/8ac579f7-2c54-45f2-8a93-6053d45937c5/image.png&quot; alt=&quot;슬라이드 10 - 새로운 커리큘럼&quot;&gt;&lt;br&gt;처음으로는 커리큘럼을 새롭게 정비했는데요.&lt;/p&gt;
&lt;p&gt;기존에 있는지도 모르게 지난간 웹 수업을 빼고,&lt;br&gt;안드로이드를 조금더 자세히, Jetpack Compose까지 준비하였습니다.&lt;/p&gt;
&lt;p&gt;그렇다고 EDCAN이 안드로이드만 하는것인가&lt;br&gt;이건 아닙니다.&lt;br&gt;만약 부원중에 웹이나 게임을 공부하고 싶은 부원이 있다면&lt;br&gt;방학중에 선배에게 질문을 하면서 스스로 공부하면 됩니다.&lt;/p&gt;
&lt;p&gt;저희는 커리큘럼을 만들때 3가지 원칙을 중심으로 준비했습니다.&lt;/p&gt;
&lt;p&gt;첫째, 기초부터 확실하게&lt;br&gt;둘째, 팀 프로젝트를 중심으로&lt;br&gt;셋째, 심화까지 완벽하게&lt;/p&gt;
&lt;p&gt;이런 원칙으로 다음과 같은 커리큘럼을 준비해보았습니다.&lt;/p&gt;
&lt;p&gt;이중에서 중요한 점은 팀 프로젝트 기초 수업인데요.&lt;br&gt;이 수업에서는 팀 프로젝트를 하기 위한 준비 과정으로&lt;br&gt;프로젝트 기획, 설계, 헙업 기술 등을 배우게됩니다.&lt;/p&gt;
&lt;p&gt;특히 디자이너도 안드로이드에서 UI를 만드는 언어인 XML을 공부하고,&lt;br&gt;개발자도 디자인 툴인 Figma를 공부하게됩니다.&lt;/p&gt;
&lt;p&gt;이 과정에서 협업을 준비한 다음 방학 프로젝트나 중강중간 작은 팀 프로젝트를 진행하게됩니다.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;img src=&quot;https://velog.velcdn.com/images/ckstmznf/post/a6e75e47-52b7-4af0-92b9-833c39ab6a4a/image.png&quot; alt=&quot;슬라이드 11 - 새로운 디자인시스템&quot;&gt;&lt;br&gt;또 10주년을 맞아서&lt;br&gt;새로운 로고,&lt;br&gt;새로운 컬러,&lt;br&gt;새로운 아이덴티티 등 새로운 디자인 시스템을 제작하고 있습니다.&lt;/p&gt;
&lt;p&gt;현재에는 제작중이며 신입생들이 들어오는 3월달에 공개 할 예정입니다.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;img src=&quot;https://velog.velcdn.com/images/ckstmznf/post/aa202d5c-d7d8-4d0f-8611-e1d1b5ff8679/image.png&quot; alt=&quot;슬라이드 12 - EDCAN 블로그&quot;&gt;&lt;br&gt;이번에 보자 자세한 소통을 위해서 블로그를 개설했는데요.&lt;br&gt;아래 주소가 있으니 한번씩 방문해서 작성된 글을 읽어주세요.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;img src=&quot;https://velog.velcdn.com/images/ckstmznf/post/8fb44bb3-7d96-43da-905e-c0258255deb5/image.png&quot; alt=&quot;슬라이드 13 - 디미고 전공동아리 루나와 협동수업&quot;&gt;&lt;br&gt;오늘 이 자리에서 여러분들께 처음 발표하겠습니다.&lt;br&gt;저희 EDCAN은 2023년, 한국 디지털 미디어 고등학교의&lt;br&gt;전공 동아리 LUNA와 협동 수업을 계획하고 있습니다.&lt;/p&gt;
&lt;p&gt;이는 양 학교간의 공식적인 첫 동아리 협동수업이며&lt;br&gt;이 기회는 저희 EDCAN 부원뿐만 아니라 선린고, 디미고 학생 모두에게 좋은 기회가 될것입니다.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;img src=&quot;https://velog.velcdn.com/images/ckstmznf/post/34662f53-5dd3-4126-9a07-97f92d4a6244/image.png&quot; alt=&quot;슬라이드 14 - for Era of Digital Content And Next&quot;&gt;&lt;br&gt;마지막으로 EDCAN의 2번째 뜻으로 발표를 마치겠습니다.&lt;br&gt;for Era of Digital Content And Next&lt;br&gt;디지털 콘텐츠 시대와 다음 시대를 위하여&lt;/p&gt;
&lt;p&gt;저의 2023년, EDCAN의 새로운 모습을 기대해주세요.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;img src=&quot;https://velog.velcdn.com/images/ckstmznf/post/2a06369a-5f53-4077-977a-5938b54e7d0c/image.png&quot; alt=&quot;슬라이드 15 - 감사합니다.&quot;&gt;&lt;br&gt;발표를 들어주셔서 감사합니다.&lt;/p&gt;
&lt;h1&gt;후기&lt;/h1&gt;
&lt;p&gt;나는 이날 약 150명 정도의 사람 앞에서 발표를 했다.&lt;br&gt;이렇게 많은 사람 앞에서 발표하는 건 처음이고&lt;br&gt;만약에 내가 발표를 실수하면 EDCAN을 망신 시키는 것이라고 생각되니까&lt;br&gt;엄청 긴장했고 발표 연습도 정말 많이 했던거 같다.&lt;/p&gt;
&lt;p&gt;덕분에 발표는 정말 성공적이었다.&lt;/p&gt;
&lt;p&gt;이렇게 많은 사람앞에서 발표하는걸 다음에 또 할 수 있을것 같다.&lt;/p&gt;</description>
      <author>Heechan Park</author>
      <guid isPermaLink="true">https://edcan.tistory.com/15</guid>
      <comments>https://edcan.tistory.com/15#entry15comment</comments>
      <pubDate>Wed, 13 Dec 2023 17:05:48 +0900</pubDate>
    </item>
    <item>
      <title>명함을 만들었다  </title>
      <link>https://edcan.tistory.com/14</link>
      <description>&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;p&gt;이 글은 명함 만든걸 자랑(?) 하는 글입니다.&lt;/p&gt;
&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;최근 동아리에서 행사 예산이 조금 남아서 부원들과 함께 명함을 만들었다.&lt;br&gt;&lt;img src=&quot;https://velog.velcdn.com/images/ckstmznf/post/ecf96058-f132-49f7-bc1e-48bc7415ab45/image.png&quot; width=&quot;600px&quot;/&gt;&lt;/p&gt;
&lt;p&gt;작년에도 만들었지만 작년에는 너무 조금 만든것 같고 또 EDCAN의 느낌이 아니라&lt;br&gt;개발자 유닛은 ATELIER의 명함인 느낌이라&lt;br&gt;이번에 후배들도 명함을 만들어 줄겸 명함을 제작했다.&lt;/p&gt;
&lt;p&gt;디자인은 우리 EDCAN 픽셀장 친구가 해줬다.&lt;br&gt;디자인을 처음 봤을 때 너무 예뻐서 놀랐다. 내가 생각한 EDCAN 스러움이 정말 잘 드러나는 것 같다.&lt;/p&gt;
&lt;p&gt;추석에 친척들께도 내 명함을 드리니 감탄하셨고, 정말 잘 만들었다고 해주셨다.&lt;br&gt;&lt;del&gt;용돈은 덤이었다.&lt;/del&gt;&lt;/p&gt;</description>
      <author>Heechan Park</author>
      <guid isPermaLink="true">https://edcan.tistory.com/14</guid>
      <comments>https://edcan.tistory.com/14#entry14comment</comments>
      <pubDate>Wed, 13 Dec 2023 17:05:21 +0900</pubDate>
    </item>
    <item>
      <title>[프로젝트] 트위치 한국 철수 디데이 웹사이트 개발기</title>
      <link>https://edcan.tistory.com/13</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;gt;&amp;nbsp;이&amp;nbsp;글은&amp;nbsp;트위치&amp;nbsp;한국&amp;nbsp;철수&amp;nbsp;디데이&amp;nbsp;웹사이트를&amp;nbsp;개발하면서&amp;nbsp;배운점을&amp;nbsp;정리하는&amp;nbsp;글&amp;nbsp;입니다. &lt;br /&gt;&lt;br /&gt;#&amp;nbsp;3줄&amp;nbsp;요약&amp;nbsp;+&amp;nbsp;사용해보기 &lt;br /&gt;1.&amp;nbsp;트위치가&amp;nbsp;한국에서&amp;nbsp;철수한다 &lt;br /&gt;2.&amp;nbsp;한국&amp;nbsp;철수까지&amp;nbsp;남은&amp;nbsp;시간을&amp;nbsp;보여주는&amp;nbsp;웹을&amp;nbsp;개발했다. &lt;br /&gt;3.&amp;nbsp;사용해보고&amp;nbsp;싶다면&amp;nbsp;[twitch.kichan.dev](&lt;a href=&quot;https://twitch.kichan.dev/)에서&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://twitch.kichan.dev/)에서&lt;/a&gt;&amp;nbsp;봐주세요 &lt;br /&gt;&lt;br /&gt;-&amp;nbsp;소스&amp;nbsp;코드는&amp;nbsp;[github.com/kichan05/Goodbye-Twitch](&lt;a href=&quot;https://github.com/kichan05/Goodbye-Twitch)을&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kichan05/Goodbye-Twitch)을&lt;/a&gt;&amp;nbsp;봐주세요 &lt;br /&gt;&lt;br /&gt;#&amp;nbsp;트위치가&amp;nbsp;섭종한다... &lt;br /&gt;아침에&amp;nbsp;자고&amp;nbsp;일어나서&amp;nbsp;인스타에&amp;nbsp;들어가보니&amp;nbsp;충격적인&amp;nbsp;뉴스를&amp;nbsp;보았다. &lt;br /&gt;트위치가&amp;nbsp;한국에서&amp;nbsp;철수한다는&amp;nbsp;소식을&amp;nbsp;들었다. &lt;br /&gt;이때부터&amp;nbsp;트위치&amp;nbsp;스트리머들은&amp;nbsp;장례식을&amp;nbsp;준비했다. &lt;br /&gt;&lt;br /&gt;한&amp;nbsp;스트리머&amp;nbsp;방송에서는&amp;nbsp;한국&amp;nbsp;철수까지&amp;nbsp;남은&amp;nbsp;디데이를&amp;nbsp;보여주었다. &lt;br /&gt;이&amp;nbsp;방송을&amp;nbsp;보고&amp;nbsp;잠을&amp;nbsp;자려고&amp;nbsp;누웠는데 &lt;br /&gt;눕자마자&amp;nbsp;한국&amp;nbsp;철수까지&amp;nbsp;남은&amp;nbsp;시간을&amp;nbsp;보여주는&amp;nbsp;웹사이트를&amp;nbsp;만들고&amp;nbsp;싶어졌다. &lt;br /&gt;&lt;br /&gt;그&amp;nbsp;즉시(새벽&amp;nbsp;2시)&amp;nbsp;바로&amp;nbsp;일어나서&amp;nbsp;개발을&amp;nbsp;시작했다. &lt;br /&gt;&lt;br /&gt;#&amp;nbsp;남은&amp;nbsp;시간을&amp;nbsp;보여주는&amp;nbsp;웹을&amp;nbsp;만들어보자 &lt;br /&gt;단순히&amp;nbsp;디데이&amp;nbsp;웹사이트를&amp;nbsp;만들고&amp;nbsp;싶어서&amp;nbsp;개발을&amp;nbsp;시작한건&amp;nbsp;아니다. &lt;br /&gt;&lt;br /&gt;1.&amp;nbsp;최근에&amp;nbsp;공부한&amp;nbsp;리액트로&amp;nbsp;프로젝트를&amp;nbsp;하고&amp;nbsp;싶었다. &lt;br /&gt;2.&amp;nbsp;숫자가&amp;nbsp;롤렛처럼&amp;nbsp;보이는&amp;nbsp;애니매이션의&amp;nbsp;UI를&amp;nbsp;만들고&amp;nbsp;싶었다. &lt;br /&gt;3.&amp;nbsp;간단한&amp;nbsp;토이&amp;nbsp;프로젝트가&amp;nbsp;하고&amp;nbsp;싶어&amp;nbsp;졌다. &lt;br /&gt;&lt;br /&gt;우선&amp;nbsp;프로젝트의&amp;nbsp;가장&amp;nbsp;기본이&amp;nbsp;되는&amp;nbsp;날짜&amp;nbsp;계산&amp;nbsp;부분은 &lt;br /&gt;평소&amp;nbsp;공부해보고&amp;nbsp;싶었던&amp;nbsp;**moment.js**를&amp;nbsp;사용했다. &lt;br /&gt;&lt;br /&gt;```js &lt;br /&gt;const&amp;nbsp;END_D_DAY&amp;nbsp;=&amp;nbsp;moment(&quot;2024-02-27:00:00:00&quot;) &lt;br /&gt;&lt;br /&gt;useEffect(()&amp;nbsp;=&amp;gt;&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;const&amp;nbsp;timeInterval&amp;nbsp;=&amp;nbsp;setInterval(()&amp;nbsp;=&amp;gt;&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;d&amp;nbsp;=&amp;nbsp;END_D_DAY.diff(moment()) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;duration&amp;nbsp;=&amp;nbsp;moment.duration(d) &lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;setDDay({ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;days:&amp;nbsp;Math.floor(duration.asDays()), &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;hours:&amp;nbsp;duration.hours(), &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;minutes:&amp;nbsp;duration.minutes(), &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;second:&amp;nbsp;duration.seconds(), &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;asSecond&amp;nbsp;:&amp;nbsp;Math.floor(duration.asSeconds()),&amp;nbsp;//&amp;nbsp;남은&amp;nbsp;시간을&amp;nbsp;모두&amp;nbsp;초로&amp;nbsp;계산 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}) &lt;br /&gt;&amp;nbsp;&amp;nbsp;},&amp;nbsp;500) &lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;return&amp;nbsp;()&amp;nbsp;=&amp;gt;&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;clearInterval(timeInterval) &lt;br /&gt;&amp;nbsp;&amp;nbsp;} &lt;br /&gt;},&amp;nbsp;[]) &lt;br /&gt;``` &lt;br /&gt;&lt;br /&gt;moment를&amp;nbsp;사용해서&amp;nbsp;트위치&amp;nbsp;한국&amp;nbsp;철수&amp;nbsp;예정일인&amp;nbsp;2024년&amp;nbsp;2월&amp;nbsp;27일&amp;nbsp;0시&amp;nbsp;00분으로&amp;nbsp;기준을&amp;nbsp;잡아주었고 &lt;br /&gt;useEffect&amp;nbsp;훅을&amp;nbsp;사용해서&amp;nbsp;처음&amp;nbsp;마운트&amp;nbsp;될때&amp;nbsp;timeInterval를&amp;nbsp;걸어주었고 &lt;br /&gt;언마운트&amp;nbsp;될때&amp;nbsp;삭제&amp;nbsp;되게&amp;nbsp;해주었다. &lt;br /&gt;&lt;br /&gt;![개발&amp;nbsp;예시&amp;nbsp;사진](&lt;a href=&quot;https://velog.velcdn.com/images/ckstmznf/post/1f92c917-e302-4cec-af93-ea73870b541f/image.png)&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://velog.velcdn.com/images/ckstmznf/post/1f92c917-e302-4cec-af93-ea73870b541f/image.png)&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;위의&amp;nbsp;사진&amp;nbsp;처럼&amp;nbsp;숫사가&amp;nbsp;수직으로&amp;nbsp;배열되어&amp;nbsp;있는&amp;nbsp;**Number**&amp;nbsp;컴포넌트를&amp;nbsp;만들어&amp;nbsp;주었고 &lt;br /&gt;이&amp;nbsp;컴포넌트에서&amp;nbsp;숫자&amp;nbsp;몇을&amp;nbsp;보여줘야&amp;nbsp;하는지는&amp;nbsp;props로&amp;nbsp;받아주었다. &lt;br /&gt;&lt;br /&gt;Number&amp;nbsp;컴포넌트에서&amp;nbsp;보여주는&amp;nbsp;숫자에&amp;nbsp;대해서&amp;nbsp;위치를&amp;nbsp;계산해주는게 &lt;br /&gt;위치는&amp;nbsp;`-1&amp;nbsp;*&amp;nbsp;각&amp;nbsp;숫자들의&amp;nbsp;높이&amp;nbsp;*&amp;nbsp;보여주는&amp;nbsp;숫자`를&amp;nbsp;계산한&amp;nbsp;값으로&amp;nbsp;주어서 &lt;br /&gt;각&amp;nbsp;숫자마다&amp;nbsp;위로&amp;nbsp;올라가게&amp;nbsp;하고 &lt;br /&gt;**.d-day**&amp;nbsp;엘리먼트의&amp;nbsp;overflow를&amp;nbsp;hidden으로&amp;nbsp;주면서&amp;nbsp;요소의&amp;nbsp;너비를&amp;nbsp;넘어간&amp;nbsp;부분은&amp;nbsp;숨겨주었다. &lt;br /&gt;&lt;br /&gt;그래서&amp;nbsp;다음과&amp;nbsp;같은&amp;nbsp;애니매이션을&amp;nbsp;만들었다. &lt;br /&gt;![애니메이션&amp;nbsp;시연](&lt;a href=&quot;https://velog.velcdn.com/images/ckstmznf/post/89d4e915-626b-432c-8750-0c7b76050889/image.gif)&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://velog.velcdn.com/images/ckstmznf/post/89d4e915-626b-432c-8750-0c7b76050889/image.gif)&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;#&amp;nbsp;이게&amp;nbsp;무슨&amp;nbsp;버그야..&amp;nbsp;아오&amp;nbsp;애플 &lt;br /&gt;새벽에&amp;nbsp;개발을&amp;nbsp;완료하고&amp;nbsp;인스타그램으로&amp;nbsp;지인들에게&amp;nbsp;먼저&amp;nbsp;공개를&amp;nbsp;하고&amp;nbsp;잠에&amp;nbsp;들었다. &lt;br /&gt;그리고&amp;nbsp;아침에&amp;nbsp;일어나서&amp;nbsp;많은&amp;nbsp;DM을&amp;nbsp;받았는데... &lt;br /&gt;&lt;br /&gt;![버그&amp;nbsp;제보&amp;nbsp;DM](&lt;a href=&quot;https://velog.velcdn.com/images/ckstmznf/post/ba75fa31-613b-4270-897a-b4fa1cbdc8b9/image.jpg)&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://velog.velcdn.com/images/ckstmznf/post/ba75fa31-613b-4270-897a-b4fa1cbdc8b9/image.jpg)&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;ios&amp;nbsp;남은&amp;nbsp;시간이&amp;nbsp;보이지&amp;nbsp;않는&amp;nbsp;버그가&amp;nbsp;발생한것이다. &lt;br /&gt;나는&amp;nbsp;노트북부터&amp;nbsp;휴대폰까지&amp;nbsp;모두&amp;nbsp;애플&amp;nbsp;기기가&amp;nbsp;아니었기&amp;nbsp;때문에&amp;nbsp;테스트할때&amp;nbsp;확인을&amp;nbsp;못했다. &lt;br /&gt;또&amp;nbsp;이런&amp;nbsp;버그가&amp;nbsp;발생할거라고&amp;nbsp;생각도&amp;nbsp;못했다. &lt;br /&gt;&lt;br /&gt;급하게&amp;nbsp;동생&amp;nbsp;핸드폰을&amp;nbsp;빌려와서~~(뺐어&amp;nbsp;와서)~~&amp;nbsp;테스트를&amp;nbsp;해보았다. &lt;br /&gt;&lt;br /&gt;버그의&amp;nbsp;원인은&amp;nbsp;moment.js가&amp;nbsp;동작&amp;nbsp;하지&amp;nbsp;않는것&amp;nbsp;같았다. &lt;br /&gt;그리고&amp;nbsp;해결법을&amp;nbsp;찾아보니&amp;nbsp;moment.js가&amp;nbsp;아니라&amp;nbsp;**Luxon**&amp;nbsp;라이브러리를&amp;nbsp;사용하는&amp;nbsp;방법이&amp;nbsp;있었고 &lt;br /&gt;이&amp;nbsp;방법을&amp;nbsp;사용하기로&amp;nbsp;했다. &lt;br /&gt;&lt;br /&gt;사용법은&amp;nbsp;moment.js와&amp;nbsp;비슷해서&amp;nbsp;오래&amp;nbsp;걸리지는&amp;nbsp;않았다. &lt;br /&gt;&lt;br /&gt;```jsx &lt;br /&gt;import&amp;nbsp;{&amp;nbsp;DateTime&amp;nbsp;}&amp;nbsp;from&amp;nbsp;'luxon' &lt;br /&gt;&lt;br /&gt;useEffect(()&amp;nbsp;=&amp;gt;&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;const&amp;nbsp;timeInterval&amp;nbsp;=&amp;nbsp;setInterval(()&amp;nbsp;=&amp;gt;&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;duration&amp;nbsp;=&amp;nbsp;END_D_DAY.diff( &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;DateTime.now(),&amp;nbsp;['days',&amp;nbsp;'hours',&amp;nbsp;'minutes',&amp;nbsp;'seconds'] &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;)&amp;nbsp;//&amp;nbsp;남은&amp;nbsp;시간&amp;nbsp;계산 &lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;setDDay({ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;days:&amp;nbsp;duration.days, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;hours:&amp;nbsp;duration.hours, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;minutes:&amp;nbsp;duration.minutes, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;second:&amp;nbsp;Math.floor(duration.seconds), &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;asSecond&amp;nbsp;:&amp;nbsp;Math.floor(duration.as(&quot;seconds&quot;)),&amp;nbsp;//&amp;nbsp;남은&amp;nbsp;시간을&amp;nbsp;모두&amp;nbsp;초로&amp;nbsp;계산 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}) &lt;br /&gt;&amp;nbsp;&amp;nbsp;},&amp;nbsp;500) &lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;return&amp;nbsp;()&amp;nbsp;=&amp;gt;&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;clearInterval(timeInterval) &lt;br /&gt;&amp;nbsp;&amp;nbsp;} &lt;br /&gt;},&amp;nbsp;[]) &lt;br /&gt;``` &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;#&amp;nbsp;프로젝트하면서&amp;nbsp;어떤걸&amp;nbsp;배웠나요 &lt;br /&gt;1.&amp;nbsp;날짜&amp;nbsp;계산&amp;nbsp;하는&amp;nbsp;방법 &lt;br /&gt;2.&amp;nbsp;애플&amp;nbsp;기기에서는&amp;nbsp;moment.js는&amp;nbsp;정상적인&amp;nbsp;작동&amp;nbsp;안한다. &lt;br /&gt;3.&amp;nbsp;처음으로&amp;nbsp;하는&amp;nbsp;리액트&amp;nbsp;프로젝트 &lt;br /&gt;4.&amp;nbsp;숫자&amp;nbsp;애니메이션&amp;nbsp;만드는&amp;nbsp;방법&lt;/p&gt;</description>
      <author>Heechan Park</author>
      <guid isPermaLink="true">https://edcan.tistory.com/13</guid>
      <comments>https://edcan.tistory.com/13#entry13comment</comments>
      <pubDate>Wed, 13 Dec 2023 17:01:47 +0900</pubDate>
    </item>
    <item>
      <title>[Android] 여러 프래그먼트에서 공유되는 ViewModel 만들기</title>
      <link>https://edcan.tistory.com/12</link>
      <description>&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;p&gt;이 글은 여러 프래그먼트에서 하나의 ViewModel을 공유해서 사용하는 법을 기록했고&lt;br&gt;Google Codelab을 통해 학습한 내용을 정한 글 입니다.&lt;/p&gt;
&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;Android에서 회원가입, 메인 페이지 등 Navigation을 사용해서 여러 프래그먼트에서&lt;br&gt;데이터를 공유해서 사용해야 할 때가 있다. 이 방법을 공부하기 위해서&lt;br&gt;Google Codelab에서 공부했다. &lt;a href=&quot;https://developer.android.com/codelabs/basic-android-kotlin-training-shared-viewmodel?hl=ko#0&quot;&gt;해당 코드랩&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;결론부터  &lt;/h1&gt;
&lt;p&gt;ViewModel은 다음과 같이 동일하게 만들어 주면 된다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-kotlin&quot;&gt;class OrderViewModel : ViewModel() {
  private val _quantity = MutableLiveData&amp;lt;Int&amp;gt;(0)
  val quantity: LiveData&amp;lt;Int&amp;gt; = _quantity
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Fragment에서 ViewModel을 만들때 &lt;strong&gt;&lt;em&gt;activityViewModels()&lt;/em&gt;&lt;/strong&gt;을 사용해주면 된다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-kotlin&quot;&gt;class PickupFragment : Fragment() {

    private val sharedViewModel: OrderViewModel by activityViewModels()

    ...    
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;다음과 같이 여러 프래그먼트에서 만들어줘도 접근하는건 하나의 객체에 접근한다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-kotlin&quot;&gt;class FlavorFragment : Fragment() {
    private val sharedViewModel: OrderViewModel by activityViewModels()
    ...

    // 공유 뷰모델에서 접근 하는 법
    // sharedViewModel.quantity.value
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>개발</category>
      <author>Heechan Park</author>
      <guid isPermaLink="true">https://edcan.tistory.com/12</guid>
      <comments>https://edcan.tistory.com/12#entry12comment</comments>
      <pubDate>Wed, 13 Dec 2023 17:01:07 +0900</pubDate>
    </item>
    <item>
      <title>[React.js] React Router 사용법</title>
      <link>https://edcan.tistory.com/11</link>
      <description>&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;p&gt;이 글은 React Router를 공부하고 정리한 글 입니다.&lt;/p&gt;
&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;h1&gt;React Router이 뭔가요?&lt;/h1&gt;
&lt;p&gt;React Router은 리액트에서 &lt;strong&gt;여러 페이지&lt;/strong&gt;를 만들고 사용할 때 사용하는 리액트 라이브러리입니다.&lt;br&gt;전문용어로 라우팅리라고 하죠.&lt;/p&gt;
&lt;h1&gt;기본 사용법&lt;/h1&gt;
&lt;p&gt;npm에서 react-router 라이브러리를 설치해줍니다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;npm i react-router&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;라우터의 기본 구조는 다음과 같은 컨포넌트 구조로 이루어져있습니다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-jsx&quot;&gt;import { BrowserRouter, Routes, Route } from &amp;#39;react-router-dom&amp;#39;;

function App() {
  return (
    &amp;lt;BrowserRouter&amp;gt;
      &amp;lt;Routes&amp;gt;
        &amp;lt;Route index element={...} /&amp;gt;
        &amp;lt;Route path=&amp;quot;path1&amp;quot; element={...} /&amp;gt;
        ...
      &amp;lt;/Routes&amp;gt;
    &amp;lt;/BrowserRouter&amp;gt;
  );
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;BrowserRouter라는 컨포넌트가 최상위에 있고&lt;br&gt;그 다음으로 Routes가 Route 컨포넌트들을 감싸고 있습니다.&lt;/p&gt;
&lt;p&gt;Route의 element 속성은 해당 경로로 접속을 하면 보여줄 컨포넌트를 받고&lt;br&gt;index 속성이 있다면 루트 경로로 접속을 했을때 보여주는 컨포넌트 입니다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-jsx&quot;&gt;import { Link, Outlet } from &amp;quot;react-router-dom&amp;quot;;

&amp;lt;nav&amp;gt;
  &amp;lt;ui&amp;gt;
    &amp;lt;li&amp;gt;
      &amp;lt;Link to=&amp;quot;/&amp;quot; &amp;gt;Home&amp;lt;/Link&amp;gt;
    &amp;lt;/li&amp;gt;
    &amp;lt;li&amp;gt;
      &amp;lt;Link to=&amp;quot;/path1&amp;quot;&amp;gt;path1롤 가기&amp;lt;/Link&amp;gt;
    &amp;lt;/li&amp;gt;
  &amp;lt;/ui&amp;gt;
&amp;lt;/nav&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Link 컨포넌트는 라우터의 경로를 이동하는 컨포넌트입니다.&lt;/p&gt;
&lt;p&gt;Link 컨포넌트가 가지고 있는 속성을 다음과 같습니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;preventscrollreset : 페이지 이동시 스크롤이 최상단으로 이동하는 것을 방지합니다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;state : 이동하는 페이지의 데이터를 전달 할 수 있습니다.&lt;br&gt;state 속성을 사용해서 다음과 같이 name 데이터를 전달하면&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-jsx&quot;&gt;&amp;lt;Link to=&amp;quot;new-path&amp;quot; state={{name : &amp;quot;박희찬&amp;quot;}}/&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;다음과 같이 name 데이터를 가져올 수 있습니다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-jsx&quot;&gt;const { state } = useLocation()

const name = state.name&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;reloadDocument : &lt;strong&gt;reloadDocument&lt;/strong&gt;속성은 페이지를 이동할때 클라이언트측에서만 랜더링 하는게 아니라 처음 접속하는것 처럼 문서 전체를 재 랜더링을 합니다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>개발</category>
      <author>Heechan Park</author>
      <guid isPermaLink="true">https://edcan.tistory.com/11</guid>
      <comments>https://edcan.tistory.com/11#entry11comment</comments>
      <pubDate>Wed, 13 Dec 2023 17:00:05 +0900</pubDate>
    </item>
    <item>
      <title>[Python] Pandas에서 데이터 전처리 하기</title>
      <link>https://edcan.tistory.com/10</link>
      <description>&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;p&gt;이 글은 Pandas에서 데이터 전처리 하는 방법을 공부하고 정리한 글 입니다.&lt;/p&gt;
&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;w3school의 &lt;a href=&quot;https://www.w3schools.com/python/pandas/pandas_cleaning.asp&quot;&gt;해당 강의&lt;/a&gt;를 참고하며 공부했습니다.&lt;/p&gt;
&lt;h1&gt;데이터 전처리란&lt;/h1&gt;
&lt;p&gt;우리의 데이터가 항상 깔끔했으면 좋겠지만 아닌 경우가 너무 많다.&lt;br&gt;다음과 같은 경우가 있다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;데이터의 셀이 비어있다.&lt;/li&gt;
&lt;li&gt;데이터 형식이 잘못되었다.&lt;/li&gt;
&lt;li&gt;너무 크거나 작은 데이터가 있다.&lt;/li&gt;
&lt;li&gt;중복된 데이터가 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;이런 경우에 데이터 분석에 영향을 없애기 위해서 처리를 해줘야 한다.&lt;/p&gt;
&lt;h1&gt;비어있는 데이터 전처리&lt;/h1&gt;
&lt;p&gt;데이터의 셀이 비어있는 경우&lt;br&gt;해당 데이터의 행을 지워버리거나 비어있는 셀을 특정 값으로 채워 넣을 수 있다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-py&quot;&gt;new_df = df.dropna()&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;dropna() 함수를 사용하면 비어있는 셀이 있는 모든 행을 삭제한다.&lt;/p&gt;
&lt;p&gt;데이터의 양이 많거나 삭제하는 행이 적을때는 문제가 되지 않지만&lt;br&gt;데이터 양 자체가 적거나 너무 많은 행을 삭제할때는&lt;br&gt;다른 방법을 사용하는게 좋다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-py&quot;&gt;newdf = df.fillna(100)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;fillna() 함수를 사용하면 인자로 들어온 값으로 비어있는 셀 전체를 채운다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-py&quot;&gt;newdf = df[&amp;quot;Calories&amp;quot;].fillna(100)
df[&amp;quot;Calories&amp;quot;] = newdf
df.head(100)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;fillna() 함수는 시리즈에도 적용해서 특성 열만 전처리가 가능하다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-py&quot;&gt;평균값 = df[&amp;quot;Calories&amp;quot;].mean()
중앙값 = df[&amp;quot;Calories&amp;quot;].median()
최빈값 = df[&amp;quot;Calories&amp;quot;].mode()

print(평균값, 중앙값, 최빈값)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;채워넣는 값은 임의의 값이 아니라 보통 평균값, 중앙값, 최빈값을 사용한다.&lt;br&gt;각각의 값은 &lt;code&gt;mean()&lt;/code&gt;, &lt;code&gt;median()&lt;/code&gt;, &lt;code&gt;mode()&lt;/code&gt; 함수를 사용해서 구해준다.&lt;/p&gt;
&lt;h1&gt;잘못된 데이터 전처리&lt;/h1&gt;
&lt;p&gt;데이터의 값이 너무 크거나 작은 경우 수동으로 전처르 해줄 수 있다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-py&quot;&gt;df.loc[7, &amp;quot;Duration&amp;quot;] = 1&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;해당 코드는 7번 행의 &amp;quot;Duration&amp;quot;열의 값을 1로 수정하는 코드다.&lt;br&gt;이때 수정하는 값은 평균값, 중앙값, 최빈값 등을 사용 할 수 있다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-py&quot;&gt;mean_value = df[&amp;quot;Duration&amp;quot;].mean()

for index in df.index:
    if df.loc[index, &amp;quot;Duration&amp;quot;] &amp;gt; 100:
        df.loc[index, &amp;quot;Duration&amp;quot;] = mean_value&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;너무 많은 값을 수동으로 전처리 해주기는 힘들기 때문에&lt;br&gt;for 문을 사용해서 자동으로 평균값으로 입력 해줄 수 있다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-py&quot;&gt;for index in df.index:
    if df.loc[index, &amp;quot;Duration&amp;quot;] &amp;gt; 100:
        df.drop(index, inplace=True)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;혹은 기준에 넘는 행을 삭제 할 수 있다.&lt;/p&gt;
&lt;h1&gt;중복된 데이터 전처리&lt;/h1&gt;
&lt;pre&gt;&lt;code class=&quot;language-py&quot;&gt;df.duplicated()&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;df.duplicated() 함수를 사용하면 중복된 행이 있는지 탐색하고&lt;br&gt;결과를 각각의 bool값을 가진 시리즈를 반환한다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-py&quot;&gt;new_df = df.drop_duplicates()&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;df.drop_duplicates() 함수를 사용하면 중복된 행들은 삭제한 결과를 반환한다.&lt;/p&gt;</description>
      <category>개발</category>
      <author>Heechan Park</author>
      <guid isPermaLink="true">https://edcan.tistory.com/10</guid>
      <comments>https://edcan.tistory.com/10#entry10comment</comments>
      <pubDate>Wed, 13 Dec 2023 16:59:29 +0900</pubDate>
    </item>
    <item>
      <title>[Python] Pandas 기초 공부해보기</title>
      <link>https://edcan.tistory.com/9</link>
      <description>&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;p&gt;이 글은 Python의 모듈인 Pandas를 공부하고 정리한 글입니다.&lt;/p&gt;
&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;항상 Python에서 데이터를 다룰때 Pandas를 사용했지만&lt;br&gt;기초는 모른체 구글에서 검색하거나 감으로 사용했었다.&lt;br&gt;이 기회에 기초를 공부해보았다.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.w3schools.com/python/pandas/default.asp&quot;&gt;w3school의 Pandas강의&lt;/a&gt;를 참고해서 공부했다&lt;/p&gt;
&lt;h1&gt;Pandas가 뭔가요&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;Pandas는 Python에서 데이터 분석을 할때 사용하는 모듈이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;테이블 형식의 2차원 자료를 다룰때 유용하게 사용한다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;pip install pandas&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;위의 명령어를 사용해서 모듈을 다운로드 할 수있다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-py&quot;&gt;import pandas&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;위의 코드를 사용해서 모듈을 사용 할 수 있다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-py&quot;&gt;import pandas as pd&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Python에서 모듈은 as 키워드를 사용해서 모듈명을 축약 할 수 있는데&lt;br&gt;보통 Pandas는 pd라는 이름으로 축약한다.&lt;/p&gt;
&lt;h1&gt;Pandas의 시리즈란?&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;Series : 테이블의 하나의 열, 1차원 배열과 같다.&lt;br&gt;하나의 시리즈에는 여러 자료형이 들어갈 수 있다.&lt;pre&gt;&lt;code class=&quot;language-py&quot;&gt;a = [1, 7, 2]
myvar = pd.Series(a)&lt;/code&gt;&lt;/pre&gt;
위의 코드를 사용해서 리스트를 시리즈로 만들었다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://velog.velcdn.com/images/ckstmznf/post/6825ab4d-a84a-486d-aa43-17616a0a18bf/image.png&quot; alt=&quot;시리즈 자료형 확인&quot;&gt;&lt;br&gt;자료형이 &lt;code&gt;pandas.core.series.Series&lt;/code&gt;인걸 볼 수 있다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-py&quot;&gt;a = [1, 7, 2, 12]
myvar = pd.Series(a)
print(myvar[3]) #12&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;시리즈의 원소에 접근할때는 인덱스를 사용한다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-py&quot;&gt;a = [1, 7, 2]
myvar = pd.Series(a, index=[&amp;quot;x&amp;quot;, &amp;quot;y&amp;quot;, &amp;quot;z&amp;quot;])
print(myvar[&amp;quot;z]) #2&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;시리즈를 생성할 때 기본 인텍스는 기존 리스트의 인덱스와 같다.&lt;br&gt;시리즈를 생성할 때 index인자를 사용하면 인덱스를 따로 지정 해 줄 수 있다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-py&quot;&gt;calories = {&amp;quot;day1&amp;quot;: 420, &amp;quot;day2&amp;quot;: 380, &amp;quot;day3&amp;quot;: 390}

myvar = pd.Series(calories)
myvar&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;딕셔너리를 시리즈로 제작해주면 각 원소의 인텍스가 해당하는 Key로 지정된다.&lt;/p&gt;
&lt;h1&gt;데이터프래임이란????&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;데이터 프래임은 2차원 구조를 가진 테이블과 같은 자료구조이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code class=&quot;language-py&quot;&gt;data = {
  &amp;quot;calories&amp;quot;: [420, 380, 390],
  &amp;quot;duration&amp;quot;: [50, 40, 45]
}

df = pd.DataFrame(data)
df&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;위의 예제는 data 딕셔너리를 데이터프래임으로 만들어주었다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://velog.velcdn.com/images/ckstmznf/post/c12bb556-0b0a-4656-b3c8-3e02c24230ee/image.png&quot; alt=&quot;Pandas 데이터프래임 제작&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;data&lt;/code&gt;의 key들이 각각의 열이 되고 value가 열을 이루는 데이터로 행이 된것을 볼 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://velog.velcdn.com/images/ckstmznf/post/f532cdd0-f0a1-4dff-ba80-6e2a2a86db97/image.png&quot; alt=&quot;데이터프래임에서 열 찾기&quot;&gt;&lt;/p&gt;
&lt;p&gt;데이터프래임에서 인텍스를 사용해서 행을 찾을때는 loc라는 속성을 사용한다.&lt;br&gt;이때 결과는 시리즈를 반환한다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://velog.velcdn.com/images/ckstmznf/post/58feab52-5b30-4fba-89b1-a571faea499b/image.png&quot; alt=&quot;데이터프래임에서 여러 행 찾기&quot;&gt;&lt;/p&gt;
&lt;p&gt;여러 행을 찾을때는 찾고자하는 인덱스를 리스트로 전달을 한다.&lt;br&gt;이때는 결과로 데이터프래임을 반환한다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://velog.velcdn.com/images/ckstmznf/post/24242420-700d-4909-aec8-ac3a82f9b850/image.png&quot; alt=&quot;index를 지정해서 데이터프래임 만들기&quot;&gt;&lt;/p&gt;
&lt;p&gt;데이터프래임 역시 &lt;code&gt;index&lt;/code&gt; 속성을 사용해서 각 행들의 인덱스를 지정 해 줄 수 있다.&lt;/p&gt;</description>
      <category>개발</category>
      <author>Heechan Park</author>
      <guid isPermaLink="true">https://edcan.tistory.com/9</guid>
      <comments>https://edcan.tistory.com/9#entry9comment</comments>
      <pubDate>Wed, 13 Dec 2023 16:58:11 +0900</pubDate>
    </item>
    <item>
      <title>EDCAN 10기 부원들을 위한 FireBase Guide 2</title>
      <link>https://edcan.tistory.com/8</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;1. res/brawble 안에 다음 두 xml 파일을 만들어주세요. (drawble 파일 new -&amp;gt; new resource file)&lt;/p&gt;
&lt;pre id=&quot;code_1686545209564&quot; class=&quot;css&quot; data-ke-language=&quot;css&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* btn.xml */

&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&amp;gt;
&amp;lt;shape xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;&amp;gt;
    &amp;lt;stroke
        android:width=&quot;1dp&quot;
        android:color=&quot;#425563&quot; /&amp;gt; 
    &amp;lt;solid android:color=&quot;#425563&quot; /&amp;gt;
    &amp;lt;corners android:radius=&quot;12dp&quot; /&amp;gt;
&amp;lt;/shape&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1686545250710&quot; class=&quot;css&quot; data-ke-language=&quot;css&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* border.xml */

&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&amp;gt;
&amp;lt;shape xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;&amp;gt;
    &amp;lt;stroke
        android:width=&quot;1dp&quot;
        android:color=&quot;#E3E6E8&quot; /&amp;gt; 
    &amp;lt;solid android:color=&quot;#FFFFFF&quot; /&amp;gt;
    &amp;lt;corners android:radius=&quot;12dp&quot; /&amp;gt; 
&amp;lt;/shape&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. RegisterActivity를 만들고 XML을 다음과 같이 만들어주세요.&lt;/p&gt;
&lt;pre id=&quot;code_1686545118260&quot; class=&quot;css&quot; data-ke-language=&quot;css&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&amp;gt;
&amp;lt;androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
    xmlns:app=&quot;http://schemas.android.com/apk/res-auto&quot;
    xmlns:tools=&quot;http://schemas.android.com/tools&quot;
    android:layout_width=&quot;match_parent&quot;
    android:background=&quot;@color/white&quot;
    android:layout_height=&quot;match_parent&quot;
    tools:context=&quot;.RegisterActivity&quot;&amp;gt;

    &amp;lt;androidx.constraintlayout.widget.ConstraintLayout
        app:layout_constraintTop_toTopOf=&quot;parent&quot;
        app:layout_constraintEnd_toEndOf=&quot;parent&quot;
        app:layout_constraintBottom_toBottomOf=&quot;parent&quot;
        app:layout_constraintStart_toStartOf=&quot;parent&quot;
        android:layout_width=&quot;match_parent&quot;
        android:layout_height=&quot;wrap_content&quot;&amp;gt;

        &amp;lt;ImageView
            android:id=&quot;@+id/header&quot;
            app:layout_constraintStart_toStartOf=&quot;parent&quot;
            app:layout_constraintTop_toTopOf=&quot;parent&quot;
            app:layout_constraintEnd_toEndOf=&quot;parent&quot;
            android:layout_width=&quot;372dp&quot;
            android:layout_height=&quot;152dp&quot;
            android:src=&quot;@drawable/photo&quot; /&amp;gt;

        &amp;lt;TextView
            android:id=&quot;@+id/id_info_txt&quot;
            android:layout_marginTop=&quot;32dp&quot;
            android:text=&quot;아이디&quot;
            app:layout_constraintTop_toBottomOf=&quot;@+id/header&quot;
            app:layout_constraintStart_toStartOf=&quot;parent&quot;
            app:layout_constraintEnd_toEndOf=&quot;parent&quot;
            android:layout_width=&quot;match_parent&quot;
            android:textColor=&quot;#425563&quot;
            android:textSize=&quot;15sp&quot;
            android:layout_marginStart=&quot;24dp&quot;
            android:layout_marginEnd=&quot;24dp&quot;
            android:layout_height=&quot;wrap_content&quot; /&amp;gt;

        &amp;lt;EditText
            android:id=&quot;@+id/id_et&quot;
            android:layout_marginTop=&quot;12dp&quot;
            android:layout_width=&quot;match_parent&quot;
            android:layout_height=&quot;52dp&quot;
            android:hint=&quot;아이디를 입력해주세요&quot;
            android:paddingStart=&quot;20dp&quot;
            android:background=&quot;@drawable/border&quot;
            android:textSize=&quot;15sp&quot;
            app:layout_constraintStart_toStartOf=&quot;parent&quot;
            android:layout_marginStart=&quot;24dp&quot;
            android:layout_marginEnd=&quot;24dp&quot;
            app:layout_constraintEnd_toEndOf=&quot;parent&quot;
            android:textColorHint=&quot;#98A4AE&quot;
            app:layout_constraintTop_toBottomOf=&quot;@+id/id_info_txt&quot; /&amp;gt;

        &amp;lt;TextView
            android:id=&quot;@+id/id_password_txt&quot;
            android:layout_marginTop=&quot;20dp&quot;
            android:text=&quot;비밀번호&quot;
            app:layout_constraintTop_toBottomOf=&quot;@+id/id_et&quot;
            app:layout_constraintStart_toStartOf=&quot;parent&quot;
            app:layout_constraintEnd_toEndOf=&quot;parent&quot;
            android:layout_width=&quot;match_parent&quot;
            android:textColor=&quot;#425563&quot;
            android:textSize=&quot;15sp&quot;
            android:layout_marginStart=&quot;24dp&quot;
            android:layout_marginEnd=&quot;24dp&quot;
            android:layout_height=&quot;wrap_content&quot; /&amp;gt;


        &amp;lt;EditText
            android:id=&quot;@+id/password_et&quot;
            android:layout_marginTop=&quot;12dp&quot;
            android:layout_width=&quot;match_parent&quot;
            android:layout_height=&quot;52dp&quot;
            android:hint=&quot;비밀번호를 입력해주세요&quot;
            android:paddingStart=&quot;20dp&quot;
            android:background=&quot;@drawable/border&quot;
            android:textSize=&quot;15sp&quot;
            app:layout_constraintStart_toStartOf=&quot;parent&quot;
            android:layout_marginStart=&quot;24dp&quot;
            android:layout_marginEnd=&quot;24dp&quot;
            app:layout_constraintEnd_toEndOf=&quot;parent&quot;
            android:textColorHint=&quot;#98A4AE&quot;
            app:layout_constraintTop_toBottomOf=&quot;@+id/id_password_txt&quot; /&amp;gt;

        &amp;lt;Button
            android:id=&quot;@+id/submit_btn&quot;
            android:background=&quot;@drawable/btn&quot;
            android:layout_width=&quot;372dp&quot;
            android:layout_marginTop=&quot;48dp&quot;
            android:textColor=&quot;@color/white&quot;
            android:layout_height=&quot;52dp&quot;
            android:textSize=&quot;15sp&quot;
            app:layout_constraintStart_toStartOf=&quot;parent&quot;
            app:layout_constraintEnd_toEndOf=&quot;parent&quot;
            android:text=&quot;회원가입&quot;
            android:textStyle=&quot;bold&quot;
            app:layout_constraintTop_toBottomOf=&quot;@id/password_et&quot; /&amp;gt;

        &amp;lt;TextView
            android:id=&quot;@+id/change_btn&quot;
            android:layout_width=&quot;wrap_content&quot;
            android:layout_height=&quot;wrap_content&quot;
            app:layout_constraintStart_toStartOf=&quot;parent&quot;
            android:layout_marginTop=&quot;20dp&quot;
            app:layout_constraintEnd_toEndOf=&quot;parent&quot;
            android:text=&quot;이미 계정이 있어요&quot;
            android:textColor=&quot;#425563&quot;
            app:layout_constraintTop_toBottomOf=&quot;@id/submit_btn&quot; /&amp;gt;


    &amp;lt;/androidx.constraintlayout.widget.ConstraintLayout&amp;gt;

&amp;lt;/androidx.constraintlayout.widget.ConstraintLayout&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. LoginActivity를 만들고 XML을 다음과 같이 만들어주세요.&lt;/p&gt;
&lt;pre id=&quot;code_1686545303214&quot; class=&quot;css&quot; data-ke-language=&quot;css&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&amp;gt;
&amp;lt;androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
    xmlns:app=&quot;http://schemas.android.com/apk/res-auto&quot;
    xmlns:tools=&quot;http://schemas.android.com/tools&quot;
    android:layout_width=&quot;match_parent&quot;
    android:background=&quot;@color/white&quot;
    android:layout_height=&quot;match_parent&quot;
    tools:context=&quot;.LoginActivity&quot;&amp;gt;

    &amp;lt;androidx.constraintlayout.widget.ConstraintLayout
        app:layout_constraintTop_toTopOf=&quot;parent&quot;
        app:layout_constraintEnd_toEndOf=&quot;parent&quot;
        app:layout_constraintBottom_toBottomOf=&quot;parent&quot;
        app:layout_constraintStart_toStartOf=&quot;parent&quot;
        android:layout_width=&quot;match_parent&quot;
        android:layout_height=&quot;wrap_content&quot;&amp;gt;

        &amp;lt;TextView
            android:id=&quot;@+id/header&quot;
            android:layout_width=&quot;wrap_content&quot;
            android:layout_height=&quot;wrap_content&quot;
            app:layout_constraintStart_toStartOf=&quot;parent&quot;
            app:layout_constraintTop_toTopOf=&quot;parent&quot;
            android:layout_marginStart=&quot;24dp&quot;
            android:textSize=&quot;32sp&quot;
            android:textStyle=&quot;bold&quot;
            android:text=&quot;로그인&quot;
            android:textColor=&quot;#425563&quot;
        /&amp;gt;

        &amp;lt;TextView
            android:id=&quot;@+id/id_info_txt&quot;
            android:layout_marginTop=&quot;32dp&quot;
            android:text=&quot;아이디&quot;
            app:layout_constraintTop_toBottomOf=&quot;@+id/header&quot;
            app:layout_constraintStart_toStartOf=&quot;parent&quot;
            app:layout_constraintEnd_toEndOf=&quot;parent&quot;
            android:layout_width=&quot;match_parent&quot;
            android:textColor=&quot;#425563&quot;
            android:textSize=&quot;15sp&quot;
            android:layout_marginStart=&quot;24dp&quot;
            android:layout_marginEnd=&quot;24dp&quot;
            android:layout_height=&quot;wrap_content&quot; /&amp;gt;

        &amp;lt;EditText
            android:id=&quot;@+id/id_et&quot;
            android:layout_marginTop=&quot;12dp&quot;
            android:layout_width=&quot;match_parent&quot;
            android:layout_height=&quot;52dp&quot;
            android:hint=&quot;아이디를 입력해주세요&quot;
            android:paddingStart=&quot;20dp&quot;
            android:background=&quot;@drawable/border&quot;
            android:textSize=&quot;15sp&quot;
            app:layout_constraintStart_toStartOf=&quot;parent&quot;
            android:layout_marginStart=&quot;24dp&quot;
            android:layout_marginEnd=&quot;24dp&quot;
            app:layout_constraintEnd_toEndOf=&quot;parent&quot;
            android:textColorHint=&quot;#98A4AE&quot;
            app:layout_constraintTop_toBottomOf=&quot;@+id/id_info_txt&quot; /&amp;gt;

        &amp;lt;TextView
            android:id=&quot;@+id/id_password_txt&quot;
            android:layout_marginTop=&quot;20dp&quot;
            android:text=&quot;비밀번호&quot;
            app:layout_constraintTop_toBottomOf=&quot;@+id/id_et&quot;
            app:layout_constraintStart_toStartOf=&quot;parent&quot;
            app:layout_constraintEnd_toEndOf=&quot;parent&quot;
            android:layout_width=&quot;match_parent&quot;
            android:textColor=&quot;#425563&quot;
            android:textSize=&quot;15sp&quot;
            android:layout_marginStart=&quot;24dp&quot;
            android:layout_marginEnd=&quot;24dp&quot;
            android:layout_height=&quot;wrap_content&quot; /&amp;gt;


        &amp;lt;EditText
            android:id=&quot;@+id/password_et&quot;
            android:layout_marginTop=&quot;12dp&quot;
            android:layout_width=&quot;match_parent&quot;
            android:layout_height=&quot;52dp&quot;
            android:hint=&quot;비밀번호를 입력해주세요&quot;
            android:paddingStart=&quot;20dp&quot;
            android:background=&quot;@drawable/border&quot;
            android:textSize=&quot;15sp&quot;
            app:layout_constraintStart_toStartOf=&quot;parent&quot;
            android:layout_marginStart=&quot;24dp&quot;
            android:layout_marginEnd=&quot;24dp&quot;
            app:layout_constraintEnd_toEndOf=&quot;parent&quot;
            android:textColorHint=&quot;#98A4AE&quot;
            app:layout_constraintTop_toBottomOf=&quot;@+id/id_password_txt&quot; /&amp;gt;

        &amp;lt;Button
            android:id=&quot;@+id/submit_btn&quot;
            android:background=&quot;@drawable/btn&quot;
            android:layout_width=&quot;372dp&quot;
            android:layout_marginTop=&quot;48dp&quot;
            android:textColor=&quot;@color/white&quot;
            android:layout_height=&quot;52dp&quot;
            android:textSize=&quot;15sp&quot;
            app:layout_constraintStart_toStartOf=&quot;parent&quot;
            app:layout_constraintEnd_toEndOf=&quot;parent&quot;
            android:text=&quot;로그인&quot;
            android:textStyle=&quot;bold&quot;
            app:layout_constraintTop_toBottomOf=&quot;@id/password_et&quot; /&amp;gt;

        &amp;lt;TextView
            android:id=&quot;@+id/change_btn&quot;
            android:layout_width=&quot;wrap_content&quot;
            android:layout_height=&quot;wrap_content&quot;
            app:layout_constraintStart_toStartOf=&quot;parent&quot;
            android:layout_marginTop=&quot;20dp&quot;
            app:layout_constraintEnd_toEndOf=&quot;parent&quot;
            android:text=&quot;회원가입 하러 가기&quot;
            android:textColor=&quot;#425563&quot;
            app:layout_constraintTop_toBottomOf=&quot;@id/submit_btn&quot; /&amp;gt;


    &amp;lt;/androidx.constraintlayout.widget.ConstraintLayout&amp;gt;

&amp;lt;/androidx.constraintlayout.widget.ConstraintLayout&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 해당 프로젝트에서 Authentication을 사용 설정해주세요. (시작하기 누르기)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-06-12 오후 1.49.00.png&quot; data-origin-width=&quot;492&quot; data-origin-height=&quot;554&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/2lqjD/btsjGhuHtvr/rAiKsZer7KTlwlTDEhICS0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/2lqjD/btsjGhuHtvr/rAiKsZer7KTlwlTDEhICS0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/2lqjD/btsjGhuHtvr/rAiKsZer7KTlwlTDEhICS0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F2lqjD%2FbtsjGhuHtvr%2FrAiKsZer7KTlwlTDEhICS0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;337&quot; height=&quot;379&quot; data-filename=&quot;스크린샷 2023-06-12 오후 1.49.00.png&quot; data-origin-width=&quot;492&quot; data-origin-height=&quot;554&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5.&amp;nbsp; 기본 제공업체의 이메일/비밀번호를 누른 후, 이메일/비밀번호만 사용설정(스위치) 한 후 저장해주세요.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-06-12 오후 1.49.59.png&quot; data-origin-width=&quot;1122&quot; data-origin-height=&quot;866&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/0pHpd/btsjBuaCnTV/S3Dn33RFMLn7o09vmpHrS1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/0pHpd/btsjBuaCnTV/S3Dn33RFMLn7o09vmpHrS1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/0pHpd/btsjBuaCnTV/S3Dn33RFMLn7o09vmpHrS1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F0pHpd%2FbtsjBuaCnTV%2FS3Dn33RFMLn7o09vmpHrS1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;449&quot; height=&quot;347&quot; data-filename=&quot;스크린샷 2023-06-12 오후 1.49.59.png&quot; data-origin-width=&quot;1122&quot; data-origin-height=&quot;866&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>개발</category>
      <author>leeharam</author>
      <guid isPermaLink="true">https://edcan.tistory.com/8</guid>
      <comments>https://edcan.tistory.com/8#entry8comment</comments>
      <pubDate>Mon, 12 Jun 2023 13:50:59 +0900</pubDate>
    </item>
    <item>
      <title>EDCAN 10기 부원들을 위한 FireBase Guide</title>
      <link>https://edcan.tistory.com/7</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;안녕하세요, 10기 부원 여러분들.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 내용은 수업 참고 자료로 이용해주시면 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 아래 링크를 따라 들어가 파이어베이스에 접속하고, 콘솔로 이동해주세요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;콘솔로 이동&quot; 버튼은 우측 상단에 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a title=&quot;파이어베이스&quot; href=&quot;https://firebase.google.com/?hl=ko&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://firebase.google.com/?hl=ko&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1685974588831&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Firebase&quot; data-og-description=&quot;Firebase is an app development platform that helps you build and grow apps and games users love. Backed by Google and trusted by millions of businesses around the world.&quot; data-og-host=&quot;firebase.google.com&quot; data-og-source-url=&quot;https://firebase.google.com/?hl=ko&quot; data-og-url=&quot;https://firebase.google.com/?hl=ko&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/l96Ya/hySTLHTP5J/Lchp71XzbcT3Y0d3XZFHEK/img.png?width=1600&amp;amp;height=800&amp;amp;face=0_0_1600_800,https://scrap.kakaocdn.net/dn/bcnqk7/hySTUx4x1Z/Bp1ToAOiKR8QdoTaS00aF0/img.png?width=1600&amp;amp;height=800&amp;amp;face=0_0_1600_800,https://scrap.kakaocdn.net/dn/YSEZH/hySRTOkoCZ/veVrx2DMzM4eMkY482evb1/img.png?width=512&amp;amp;height=512&amp;amp;face=0_0_512_512&quot;&gt;&lt;a href=&quot;https://firebase.google.com/?hl=ko&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://firebase.google.com/?hl=ko&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/l96Ya/hySTLHTP5J/Lchp71XzbcT3Y0d3XZFHEK/img.png?width=1600&amp;amp;height=800&amp;amp;face=0_0_1600_800,https://scrap.kakaocdn.net/dn/bcnqk7/hySTUx4x1Z/Bp1ToAOiKR8QdoTaS00aF0/img.png?width=1600&amp;amp;height=800&amp;amp;face=0_0_1600_800,https://scrap.kakaocdn.net/dn/YSEZH/hySRTOkoCZ/veVrx2DMzM4eMkY482evb1/img.png?width=512&amp;amp;height=512&amp;amp;face=0_0_512_512');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Firebase&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Firebase is an app development platform that helps you build and grow apps and games users love. Backed by Google and trusted by millions of businesses around the world.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;firebase.google.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 새 프로젝트를 만든 뒤 구글 애널리틱스는 비활성화 시켜주세요. 사용하지 않을 기능입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-06-05 오후 11.17.34.png&quot; data-origin-width=&quot;772&quot; data-origin-height=&quot;488&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bfvXUd/btsiBMdsBur/PgwWmw462Dh4iFcrgNe5M1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bfvXUd/btsiBMdsBur/PgwWmw462Dh4iFcrgNe5M1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bfvXUd/btsiBMdsBur/PgwWmw462Dh4iFcrgNe5M1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbfvXUd%2FbtsiBMdsBur%2FPgwWmw462Dh4iFcrgNe5M1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;407&quot; height=&quot;257&quot; data-filename=&quot;스크린샷 2023-06-05 오후 11.17.34.png&quot; data-origin-width=&quot;772&quot; data-origin-height=&quot;488&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 프로젝트가 다 만들어지면 &quot;앱에 FireBase를 추가하여 시작하기&quot; 하단의 안드로이드 로고를 클릭해 새로운 앱을 만들어주세요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;패키지 이름은 MainActivity.com 최상단의 패키지명을 사용하시면 됩니다. 앱 닉네임은 원하는대로 만들어주세요.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-06-05 오후 11.18.33.png&quot; data-origin-width=&quot;1222&quot; data-origin-height=&quot;656&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bR7fb3/btsiOe03H8l/q2uxaAkKYKy9B9aYEmN0bk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bR7fb3/btsiOe03H8l/q2uxaAkKYKy9B9aYEmN0bk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bR7fb3/btsiOe03H8l/q2uxaAkKYKy9B9aYEmN0bk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbR7fb3%2FbtsiOe03H8l%2Fq2uxaAkKYKy9B9aYEmN0bk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;525&quot; height=&quot;282&quot; data-filename=&quot;스크린샷 2023-06-05 오후 11.18.33.png&quot; data-origin-width=&quot;1222&quot; data-origin-height=&quot;656&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 구성 파일을 다운로드 한 후 프로젝트의 app 폴더에 넣어주면 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 보이는 사진처럼 상단에서 Android 보기를 Project 보기로 설정하면 app 폴더를 쉽게 확인할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-06-05 오후 11.20.24.png&quot; data-origin-width=&quot;1522&quot; data-origin-height=&quot;916&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/blaPvF/btsiOjA6lTS/aQeEluusJkLa6ZKd7kYFA0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/blaPvF/btsiOjA6lTS/aQeEluusJkLa6ZKd7kYFA0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/blaPvF/btsiOjA6lTS/aQeEluusJkLa6ZKd7kYFA0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FblaPvF%2FbtsiOjA6lTS%2FaQeEluusJkLa6ZKd7kYFA0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;540&quot; height=&quot;325&quot; data-filename=&quot;스크린샷 2023-06-05 오후 11.20.24.png&quot; data-origin-width=&quot;1522&quot; data-origin-height=&quot;916&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-06-05 오후 11.21.06.png&quot; data-origin-width=&quot;776&quot; data-origin-height=&quot;598&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/boJsWq/btsiQ5u5Msm/LOZh7WLRuFMjmqZ42mH1z1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/boJsWq/btsiQ5u5Msm/LOZh7WLRuFMjmqZ42mH1z1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/boJsWq/btsiQ5u5Msm/LOZh7WLRuFMjmqZ42mH1z1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FboJsWq%2FbtsiQ5u5Msm%2FLOZh7WLRuFMjmqZ42mH1z1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;539&quot; height=&quot;415&quot; data-filename=&quot;스크린샷 2023-06-05 오후 11.21.06.png&quot; data-origin-width=&quot;776&quot; data-origin-height=&quot;598&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. google-services.json 파일이 추가되었다면 다시 안드로이드 보기로 돌아간 후 두 개의 build.gradle 파일을 열어주세요.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파이어베이스에 나와있는 내용은 예전 내용으로 코드가 많이 바뀌어 새로운 방식으로 파이어베이스를 앱에 추가시켜줘야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로젝트 단위의 gradle과 앱 단위의 gradle을 확인해주세요.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-06-05 오후 11.22.07.png&quot; data-origin-width=&quot;750&quot; data-origin-height=&quot;342&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bHJXCT/btsiQ59FPAv/3niHZaEtSkCvq24K64jX6k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bHJXCT/btsiQ59FPAv/3niHZaEtSkCvq24K64jX6k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bHJXCT/btsiQ59FPAv/3niHZaEtSkCvq24K64jX6k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbHJXCT%2FbtsiQ59FPAv%2F3niHZaEtSkCvq24K64jX6k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;537&quot; height=&quot;245&quot; data-filename=&quot;스크린샷 2023-06-05 오후 11.22.07.png&quot; data-origin-width=&quot;750&quot; data-origin-height=&quot;342&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;6. 프로젝트 단위의 gradle의 중괄호 안에 다음 한줄을 추가한 후 sync해주세요.&lt;/p&gt;
&lt;pre id=&quot;code_1685975095833&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;id 'com.google.gms.google-services' version '4.3.10' apply false&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;7. 앱 단위의 gradle의 중괄호 안에 다음 내용을 추가한 후 sync해주시고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오류가 발생할 경우 오타를 잘 확인한 후 선배를 불러주세요.&lt;/p&gt;
&lt;pre id=&quot;code_1685975324123&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 최상단 plugins를 아래처럼 바꿔주세요.

plugins {
    id 'com.android.application'
    id 'org.jetbrains.kotlin.android'
    id 'com.google.gms.google-services'
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1685975333302&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 뷰바인딩을 이용하기 위해 android 중괄호 안에 다음 코드를 넣어주세요.

viewBinding {
    enabled = true
}
buildFeatures {
    viewBinding true
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1685975339369&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 최하단 dependencies 안에 다음 코드를 추가해주세요.

implementation 'com.google.firebase:firebase-firestore-ktx:24.6.1'&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;8. 문제가 없다면 XML 파일을 아래와 같이 만들어주세요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 첫번째 EditText의 id = et1&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 두번째 EditText의 id = et2&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 세번째 EditText의 id = et3&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 버튼의 id = btn&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-06-05 오후 11.32.10.png&quot; data-origin-width=&quot;648&quot; data-origin-height=&quot;562&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bp6Qnd/btsiBLersOf/sjapRITcjNy2Spnnkaxk3K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bp6Qnd/btsiBLersOf/sjapRITcjNy2Spnnkaxk3K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bp6Qnd/btsiBLersOf/sjapRITcjNy2Spnnkaxk3K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbp6Qnd%2FbtsiBLersOf%2FsjapRITcjNy2Spnnkaxk3K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;368&quot; height=&quot;319&quot; data-filename=&quot;스크린샷 2023-06-05 오후 11.32.10.png&quot; data-origin-width=&quot;648&quot; data-origin-height=&quot;562&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;9. 최상단 코드를 뷰바인딩 사용을 위해 아래처럼 바꿔주세요.&lt;/p&gt;
&lt;pre id=&quot;code_1685975629204&quot; class=&quot;css&quot; data-ke-language=&quot;css&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
    xmlns:app=&quot;http://schemas.android.com/apk/res-auto&quot;
    xmlns:tools=&quot;http://schemas.android.com/tools&quot;
    android:layout_width=&quot;match_parent&quot;
    android:layout_height=&quot;match_parent&quot;
    tools:context=&quot;.MainActivity&quot;&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;10. 뷰바인딩 사용을 위해 액티비티의 클래스 코드를 수정해주세요.&lt;/p&gt;
&lt;pre id=&quot;code_1685975687582&quot; class=&quot;css&quot; data-ke-language=&quot;css&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class MainActivity : AppCompatActivity() {
    private lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        FirebaseApp.initializeApp(this)

        binding = ActivityMainBinding.inflate(layoutInflater)
        val view = binding.root
        setContentView(view)
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;11. 이제 본격적으로 파이어베이스를 다루어보겠습니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞의 수업에 집중해주세요.&lt;/p&gt;</description>
      <category>개발</category>
      <author>leeharam</author>
      <guid isPermaLink="true">https://edcan.tistory.com/7</guid>
      <comments>https://edcan.tistory.com/7#entry7comment</comments>
      <pubDate>Tue, 6 Jun 2023 23:04:37 +0900</pubDate>
    </item>
  </channel>
</rss>