Kotlin Android application – Glucose

People with diabetes need to take frequent blood glucose measurements on empty stomach and an hour after each major meal. This data needs to be stored and then presented to the doctor during the appointment.
I was asked to create an Android application with which the user would save his measurements in google spreadsheets. This time I have decided to use Kotlin to create a native application because of the easier integration with google.
The application has not yet reached its final shape but currently has basic functionalities and can be used. Please find below the screens:
glucose

The spreadsheet is organized in the way one can find below (random test data are used):
glucose_test_data_2
Application is being developed with Fragments and uses Model-View-ViewModel pattern and the source code can be found on this github repo.

Advent of Code 2019 in Kotlin

I have decided to solve this year’s puzzles in Kotlin and I have succeeded. Kotlin turns out to be very pragmatic programming language where you can very efficiently solve the problems. It reduces the boiler plate code to absolute minimum and this allows you to reduce the number of lines of your source code. However it needs a bit of training and patience, I had to switch from Java to Kotlin thinking.

My solutions can be found on this github repo

Solved Advent of Code 2019:
Screenshot from 2020-02-21 10-39-59

Kotlin scope functions: let, run, with, apply, and also

  • Let
  • inline fun  T.let(block: (T) -> R): R {
      return block(this)
    }
    

    Let returns the result of lambda. Lambda takes as an input parameter the object upon let is invoked. Thus the object can be referred in the function scope as it. The function returns the last statement.

    val test = "my test string"
    val res = test
      .let { it.substring(0, 3) }
      .let { it.length}
    println(res) //3
    

    Let can be used for the null check:

    val test: String? = null
    test?.let {
      println("$it is not null") //prints nothing
    }
    
  • Also
  • inline fun T.also(block: (T) -> Unit): T {
      block(this)
      return this
    }
    

    Also returns the original object and the function invokes the lambda which takes as an input parameter the object which invoked also.

    data class Draft(var id: Long, var name: String)
    val draft = Draft(1L, "test")
    val res = draft.also {
      it.id = 2L
      it.name = "test2"
    }
    println(draft) //Draft(id=2, name=test2)
    println(res == draft) //true
    
  • Run
  • inline fun  T.run(block: T.() -> R): R {
      return block()
    }
    

    Run is an extension function of the object which is invoking run. So in the scope of the function the object can be referred by this (however this can be omitted). The function returns the last statement.

    data class Draft(var id: Long, var name: String)
    val draft = Draft(1L, "test")
    val res = draft.run {
      id = 2L
      name = "test2"
      name
    }
    println(draft) //Draft(id=2, name=test2)
    println(res) //test2
    

    Run can be used for the null check:

    val draft: Draft? = null
    draft?.run {
      println(draft) //prints nothing
    }
    
  • Apply
  • inline fun T.apply(block: T.() -> Unit): T {
      block()
      return this
    }
    

    Apply is an extension function of the object which is invoking apply. In the scope of the function the object can be referred by this. Apply returns the original object.

    data class Draft(var id: Long, var name: String)
    val draft = Draft(1L, "test")
    val res = draft.apply {
      id = 2L
      name = "test2"
    }
    println(draft) //Draft(id=2, name=test2)
    println(res == draft) //true
    
  • With
  • inline fun  with(receiver: T, block: T.() -> R): R {
      return receiver.block()
    }
    

    With is invoked with the object passed as an argument then an extension function is called on it. In the scope of the function the object can be referred by this. The last expression of with function returns a result.

    data class Draft(var id: Long, var name: String)
    val draft = Draft(1L, "test")
    val res = with(draft) {
      id = 2L
      name = "test2"
      id
    }
    println(draft) //Draft(id=2, name=test2)
    println(res) //2
    

Please find the link to the Kotlin documentation regarding the conventions of using the scope functions.