2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

GPT-4にリファクタリングとコメント全部任せてみた

Last updated at Posted at 2023-03-16

環境

chat-GPT plus (GPT-4)

会話

Person:

  • 以下のコードをリファクタリングして
package com.example.myLifeLog.model.receiver

import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import com.example.myLifeLog.*
import com.example.myLifeLog.model.db.MainRoomDatabase
import com.example.myLifeLog.model.db.location.Location
import com.example.myLifeLog.model.db.location.LocationRepository
import com.example.myLifeLog.model.db.transition.Transition
import com.example.myLifeLog.model.db.transition.TransitionRepository
import com.google.android.gms.location.*
import java.time.LocalDateTime

private const val TAG = "ActivityUpdatesBroadcastReceiver"

class ActivityUpdatesBroadcastReceiver: BroadcastReceiver() {

    override fun onReceive(context: Context, intent: Intent) {
        if (ActivityTransitionResult.hasResult(intent)) {
            val result = ActivityTransitionResult.extractResult(intent)!!
            myLog(TAG, "receive ${result.transitionEvents.size} transition events")
            val dB: MainRoomDatabase = MainRoomDatabase.getInstance(context)
            val locationRepository = LocationRepository(dB.LocationDao())
            val transitionRepository = TransitionRepository(dB.TransitionDao())
            val locationClient = LocationServices.getFusedLocationProviderClient(context)

            for (event in result.transitionEvents) {
                myLog(TAG, "get event: ActivityType=${event.activityType}, TransitionType=${event.transitionType}")
                val dateTimeNow = LocalDateTime.now().toMilliSec()
                if (
                    event.activityType == DetectedActivity.STILL &&
                    event.transitionType == ActivityTransition.ACTIVITY_TRANSITION_ENTER
                ) {
                    doSomethingWithLocation(
                        context, locationClient,1, 5,
                        onSuccess = { location ->
                            val nearLocation =
                                locationRepository.getNearLocation(location.latitude, location.longitude)
                            val locationId: Int
                            if (nearLocation != null) {
                                locationId = nearLocation.id
                            } else {
                                locationRepository.insertLocation(
                                    Location(
                                        name = "",
                                        latitude = location.latitude,
                                        longitude = location.longitude
                                    )
                                )
                                locationId = loadSharedPrefInt(context, "locationNum")
                                saveSharedPref(context, "locationNum", "${locationId+1}")
                            }
                            transitionRepository.insertTransition(
                                Transition(
                                    activityType = event.activityType,
                                    transitionType = event.transitionType,
                                    locationId = locationId,
                                    dateTime = dateTimeNow,
                                    latitude = location.latitude,
                                    longitude = location.longitude
                                )
                            )
                        },
                        onFailure = {
                            transitionRepository.insertTransition(
                                Transition(
                                    activityType = event.activityType,
                                    transitionType = event.transitionType,
                                    locationId = null,
                                    dateTime = dateTimeNow,
                                    latitude = null,
                                    longitude = null
                                )
                            )
                        }
                    )
                } else {
                    transitionRepository.insertTransition(
                        Transition(
                            activityType = event.activityType,
                            transitionType = event.transitionType,
                            locationId = null,
                            dateTime = dateTimeNow,
                            latitude = null,
                            longitude = null
                        )
                    )
                }
            }
        }
    }


    companion object {
        const val ACTION_PROCESS_UPDATES =
            "com.example.myLifeLog.action.TRANSITION_UPDATES"
    }
}

ChatGPT:

  • 以下のようにコードをリファクタリングしてみました。主な変更点は、クラス内にメソッドを分割し、見やすくした点です。
package com.example.myLifeLog.model.receiver

import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import com.example.myLifeLog.*
import com.example.myLifeLog.model.db.MainRoomDatabase
import com.example.myLifeLog.model.db.location.Location
import com.example.myLifeLog.model.db.location.LocationRepository
import com.example.myLifeLog.model.db.transition.Transition
import com.example.myLifeLog.model.db.transition.TransitionRepository
import com.google.android.gms.location.*
import java.time.LocalDateTime

private const val TAG = "ActivityUpdatesBroadcastReceiver"

class ActivityUpdatesBroadcastReceiver : BroadcastReceiver() {

    override fun onReceive(context: Context, intent: Intent) {
        if (ActivityTransitionResult.hasResult(intent)) {
            val result = ActivityTransitionResult.extractResult(intent)!!
            myLog(TAG, "receive ${result.transitionEvents.size} transition events")

            val dB = MainRoomDatabase.getInstance(context)
            val locationRepository = LocationRepository(dB.LocationDao())
            val transitionRepository = TransitionRepository(dB.TransitionDao())
            val locationClient = LocationServices.getFusedLocationProviderClient(context)

            for (event in result.transitionEvents) {
                processEvent(context, event, locationClient, locationRepository, transitionRepository)
            }
        }
    }

    private fun processEvent(
        context: Context,
        event: ActivityTransitionEvent,
        locationClient: FusedLocationProviderClient,
        locationRepository: LocationRepository,
        transitionRepository: TransitionRepository
    ) {
        myLog(TAG, "get event: ActivityType=${event.activityType}, TransitionType=${event.transitionType}")
        val dateTimeNow = LocalDateTime.now().toMilliSec()

        if (event.activityType == DetectedActivity.STILL && event.transitionType == ActivityTransition.ACTIVITY_TRANSITION_ENTER) {
            processStillTransition(context, event, locationClient, locationRepository, transitionRepository, dateTimeNow)
        } else {
            insertTransition(transitionRepository, event, dateTimeNow)
        }
    }

    private fun processStillTransition(
        context: Context,
        event: ActivityTransitionEvent,
        locationClient: FusedLocationProviderClient,
        locationRepository: LocationRepository,
        transitionRepository: TransitionRepository,
        dateTimeNow: Long
    ) {
        doSomethingWithLocation(
            context, locationClient, 1, 5,
            onSuccess = { location ->
                val locationId = getLocationId(context, location, locationRepository)
                insertTransition(transitionRepository, event, dateTimeNow, locationId, location.latitude, location.longitude)
            },
            onFailure = {
                insertTransition(transitionRepository, event, dateTimeNow)
            }
        )
    }

    private fun getLocationId(
        context: Context,
        location: android.location.Location,
        locationRepository: LocationRepository
    ): Int {
        val nearLocation = locationRepository.getNearLocation(location.latitude, location.longitude)

        return if (nearLocation != null) {
            nearLocation.id
        } else {
            locationRepository.insertLocation(
                Location(
                    name = "",
                    latitude = location.latitude,
                    longitude = location.longitude
                )
            )
            val locationId = loadSharedPrefInt(context, "locationNum")
            saveSharedPref(context, "locationNum", "${locationId + 1}")
            locationId
        }
    }

    private fun insertTransition(
        transitionRepository: TransitionRepository,
        event: ActivityTransitionEvent,
        dateTime: Long,
        locationId: Int? = null,
        latitude: Double?

Person:

  • つづけて

ChatGPT:

  • 続きは以下のとおりです。
longitude: Double? = null
    ) {
        transitionRepository.insertTransition(
            Transition(
                activityType = event.activityType,
                transitionType = event.transitionType,
                locationId = locationId,
                dateTime = dateTime,
                latitude = latitude,
                longitude = longitude
            )
        )
    }

    companion object {
        const val ACTION_PROCESS_UPDATES =
            "com.example.myLifeLog.action.TRANSITION_UPDATES"
    }
}

リファクタリングにより、onReceiveメソッドの処理が複数のメソッドに分割され、コードが読みやすくなりました。各メソッドが具体的なタスクを実行するようになり、それぞれの役割が明確になっています。

Person:

  • さらにコメントを付けて

ChatGPT:

  • コメントを追加し、各メソッドの説明を提供しました。
package com.example.myLifeLog.model.receiver

import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import com.example.myLifeLog.*
import com.example.myLifeLog.model.db.MainRoomDatabase
import com.example.myLifeLog.model.db.location.Location
import com.example.myLifeLog.model.db.location.LocationRepository
import com.example.myLifeLog.model.db.transition.Transition
import com.example.myLifeLog.model.db.transition.TransitionRepository
import com.google.android.gms.location.*
import java.time.LocalDateTime

private const val TAG = "ActivityUpdatesBroadcastReceiver"

class ActivityUpdatesBroadcastReceiver : BroadcastReceiver() {

    // Handle incoming broadcast messages
    override fun onReceive(context: Context, intent: Intent) {
        if (ActivityTransitionResult.hasResult(intent)) {
            val result = ActivityTransitionResult.extractResult(intent)!!
            myLog(TAG, "receive ${result.transitionEvents.size} transition events")

            val dB = MainRoomDatabase.getInstance(context)
            val locationRepository = LocationRepository(dB.LocationDao())
            val transitionRepository = TransitionRepository(dB.TransitionDao())
            val locationClient = LocationServices.getFusedLocationProviderClient(context)

            for (event in result.transitionEvents) {
                processEvent(context, event, locationClient, locationRepository, transitionRepository)
            }
        }
    }

    // Process a single activity transition event
    private fun processEvent

Person:

  • さらに日本語のコメントを付けて

ChatGPT:

  • 日本語のコメントを追加しました。
package com.example.myLifeLog.model.receiver

import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import com.example.myLifeLog.*
import com.example.myLifeLog.model.db.MainRoomDatabase
import com.example.myLifeLog.model.db.location.Location
import com.example.myLifeLog.model.db.location.LocationRepository
import com.example.myLifeLog.model.db.transition.Transition
import com.example.myLifeLog.model.db.transition.TransitionRepository
import com.google.android.gms.location.*
import java.time.LocalDateTime

private const val TAG = "ActivityUpdatesBroadcastReceiver"

class ActivityUpdatesBroadcastReceiver : BroadcastReceiver() {

    // 受信したブロードキャストメッセージを処理する
    override fun onReceive(context: Context, intent: Intent) {
        if (ActivityTransitionResult.hasResult(intent)) {
            val result = ActivityTransitionResult.extractResult(intent)!!
            myLog(TAG, "receive ${result.transitionEvents.size} transition events")

            val dB = MainRoomDatabase.getInstance(context)
            val locationRepository = LocationRepository(dB.LocationDao())
            val transitionRepository = TransitionRepository(dB.TransitionDao())
            val locationClient = LocationServices.getFusedLocationProviderClient(context)

            for (event in result.transitionEvents) {
                processEvent(context, event, locationClient, locationRepository, transitionRepository)
            }
        }
    }

    // アクティビティ遷移イベントを一つずつ処理する
    private fun processEvent(
        context: Context,
        event: ActivityTransitionEvent,
        locationClient: FusedLocationProviderClient,
        locationRepository: LocationRepository,
        transitionRepository: TransitionRepository
    ) {
        myLog(TAG, "get event: ActivityType=${event.activityType}, TransitionType=${event.transitionType}")
        val dateTimeNow = LocalDateTime.now().toMilliSec()

        if (event.activityType == DetectedActivity.STILL && event.transitionType == ActivityTransition.ACTIVITY_TRANSITION_ENTER) {
            processStillTransition(context, event, locationClient, locationRepository, transitionRepository, dateTimeNow)
        } else {
            insertTransition(transitionRepository, event, dateTimeNow)
        }
    }

    // DetectedActivity.STILL の遷移イベントを処理する
    private fun processStillTransition(
        context: Context,
        event: ActivityTransitionEvent,
        locationClient: FusedLocationProviderClient,
        locationRepository: LocationRepository,
        transitionRepository: TransitionRepository,
        dateTimeNow: Long
    ) {
        doSomethingWithLocation(
            context, locationClient, 1, 5,
            onSuccess = { location ->
                val locationId = getLocationId(context, location, locationRepository)
                insertTransition(transitionRepository, event, dateTimeNow, locationId, location.latitude, location.longitude)
            },
            onFailure = {
                insertTransition(transitionRepository, event, dateTimeNow)
            }
        )
    }

    // 現在位置のIDを取得する
    private fun getLocationId(
        context: Context,
        location: android.location.Location,
        locationRepository: LocationRepository
    ): Int {
        val nearLocation = locationRepository.getNearLocation(location.latitude, location.longitude)

        return if (nearLocation != null) {
            nearLocation.id
        } else {
            locationRepository.insertLocation(
                Location(
                    name = "",
                    latitude = location.latitude,
                    longitude = location.longitude
                )
            )
            val locationId = loadSharedPrefInt(context, "locationNum")
            saveSharedPref(context, "locationNum", "${locationId + 1}")
            location

Person:

  • つづけて

ChatGPT:

  • 続きは以下のとおりです。
locationId
        }
    }

    // 遷移イベントをデータベースに挿入する
    private fun insertTransition(
        transitionRepository: TransitionRepository,
        event: ActivityTransitionEvent,
        dateTime: Long,
        locationId: Int? = null,
        latitude: Double? = null,
        longitude: Double? = null
    ) {
        transitionRepository.insertTransition(
            Transition(
                activityType = event.activityType,
                transitionType = event.transitionType,
                locationId = locationId,
                dateTime = dateTime,
                latitude = latitude,
                longitude = longitude
            )
        )
    }

    companion object {
        // アクティビティ遷移アップデートのアクション
        const val ACTION_PROCESS_UPDATES =
            "com.example.myLifeLog.action.TRANSITION_UPDATES"
    }
}

これで、コード全体に日本語のコメントが追加され、各メソッドの説明が提供されました。これにより、コードの読みやすさが向上し、メソッドの目的がより明確になります。

まとめ

スパゲッティコードが見事に整理されてわかりやすくなった。GPT-3に比べてとても高速、正確な気がする。

追記

Person:

  • もう少し詳細にコメントが欲しい

ChatGPT:

  • より詳細な日本語のコメントを追加しました。
package com.example.myLifeLog.model.receiver

import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import com.example.myLifeLog.*
import com.example.myLifeLog.model.db.MainRoomDatabase
import com.example.myLifeLog.model.db.location.Location
import com.example.myLifeLog.model.db.location.LocationRepository
import com.example.myLifeLog.model.db.transition.Transition
import com.example.myLifeLog.model.db.transition.TransitionRepository
import com.google.android.gms.location.*
import java.time.LocalDateTime

private const val TAG = "ActivityUpdatesBroadcastReceiver"

class ActivityUpdatesBroadcastReceiver : BroadcastReceiver() {

    // このレシーバがブロードキャストメッセージを受信したときに呼び出されるメソッド
    override fun onReceive(context: Context, intent: Intent) {
        // ActivityTransitionResult の結果がある場合に処理を行う
        if (ActivityTransitionResult.hasResult(intent)) {
            val result = ActivityTransitionResult.extractResult(intent)!!
            myLog(TAG, "receive ${result.transitionEvents.size} transition events")

            // データベースとリポジトリの初期化
            val dB = MainRoomDatabase.getInstance(context)
            val locationRepository = LocationRepository(dB.LocationDao())
            val transitionRepository = TransitionRepository(dB.TransitionDao())
            val locationClient = LocationServices.getFusedLocationProviderClient(context)

            // すべての遷移イベントを処理する
            for (event in result.transitionEvents) {
                processEvent(context, event, locationClient, locationRepository, transitionRepository)
            }
        }
    }

    // アクティビティ遷移イベントを処理するメソッド
    private fun processEvent(
        context: Context,
        event: ActivityTransitionEvent,
        locationClient: FusedLocationProviderClient,
        locationRepository: LocationRepository,
        transitionRepository: TransitionRepository
    ) {
        // イベントの詳細をログに出力
        myLog(TAG, "get event: ActivityType=${event.activityType}, TransitionType=${event.transitionType}")
        val dateTimeNow = LocalDateTime.now().toMilliSec()

        // イベントが静止状態で、遷移タイプがエンターの場合、位置情報を処理する
        if (event.activityType == DetectedActivity.STILL && event.transitionType == ActivityTransition.ACTIVITY_TRANSITION_ENTER) {
            processStillTransition(context, event, locationClient, locationRepository, transitionRepository, dateTimeNow)
        } else {
            // それ以外の場合、遷移イベントをデータベースに挿入する
            insertTransition(transitionRepository, event, dateTimeNow)
        }
    }

    // DetectedActivity.STILL の遷移イベントを処理するメソッド
    private fun processStillTransition(
        context: Context,
        event: ActivityTransitionEvent,
        locationClient: FusedLocationProviderClient,
        locationRepository: LocationRepository,
        transitionRepository: TransitionRepository,
        dateTimeNow: Long
    ) {
        // 位置情報を取得し、成功時と失敗時にそれぞれ対応する処理を行う
        doSomethingWithLocation(

Person:

  • つづけて

ChatGPT:

  • 続きは以下のとおりです。
context, locationClient, 1, 5,
            onSuccess = { location ->
                // 位置情報が取得できた場合、位置IDを取得して遷移イベントをデータベースに挿入する
                val locationId = getLocationId(context, location, locationRepository)
                insertTransition(transitionRepository, event, dateTimeNow, locationId, location.latitude, location.longitude)
            },
            onFailure = {
                // 位置情報が取得できなかった場合、遷移イベントをデータベースに挿入する(位置情報なし)
                insertTransition(transitionRepository, event, dateTimeNow)
            }
        )
    }

    // 現在位置のIDを取得するメソッド
    private fun getLocationId(
        context: Context,
        location: android.location.Location,
        locationRepository: LocationRepository
    ): Int {
        // 近くの位置情報をデータベースから取得する
        val nearLocation = locationRepository.getNearLocation(location.latitude, location.longitude)

        // 既存の位置情報があればそのIDを使用し、なければ新たに位置情報をデータベースに挿入してIDを取得する
        return if (nearLocation != null) {
            nearLocation.id
        } else {
            locationRepository.insertLocation(
                Location(
                    name = "",
                    latitude = location.latitude,
                    longitude = location.longitude
                )
            )
            val locationId = loadSharedPrefInt(context, "locationNum")
            saveSharedPref(context, "locationNum", "${locationId + 1}")
            locationId
        }
    }

    // 遷移イベントをデータベースに挿入するメソッド
    private fun insertTransition(
        transitionRepository: TransitionRepository,
        event: ActivityTransitionEvent,
        dateTime: Long,
        locationId: Int? = null,
        latitude: Double? = null,
        longitude: Double? = null
    ) {
        // 遷移イベントのデータを作成し、データベースに挿入する
        transitionRepository.insertTransition(
            Transition(
                activityType = event.activityType,
                transitionType = event.transitionType,
                locationId = locationId,
                dateTime = dateTime,
                latitude = latitude,
                longitude = longitude
            )
        )
    }

    companion object {
        // アクティビティ遷移アップデートのアクション定数
        const val ACTION_PROCESS_UPDATES =
            "com.example.myLifeLog.action.TRANSITION_UPDATES"
    }
}

これで、コード全体により詳細な日本語のコメントが追加されました。これにより、コードの読みやすさがさらに向上し、各メソッドの目的がより明確になります。

追記まとめ

ところどころ、ん?となるところもあるが、こちらのコードの意図を大体汲み取ってくれている。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?