Play sound on Android

Resource files shall be placed under app\src\main\res\raw

import android.media.AudioManager
import android.media.SoundPool
import android.os.Build
import android.os.Bundle
import android.util.Log
import android.view.View
import androidx.appcompat.app.AppCompatActivity


class MainActivity : AppCompatActivity() {
    private var mCSoundOne: Int = 0
    private lateinit var mSoundPool: SoundPool
    private var mLoaded = false

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        mSoundPool = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            Log.d("SoundPoolTest", "Building Soundpool")
            SoundPool.Builder().setMaxStreams(1).build()
        } else {
            SoundPool(1, AudioManager.STREAM_MUSIC, 1)
        }
        mSoundPool.setOnLoadCompleteListener(SoundPool.OnLoadCompleteListener { soundPool, sampleId, status ->
            Log.d("SoundPoolTest", "Load Completed")
            mLoaded = true
        })
        Log.d("SoundPoolTest", "Loading wav")
        mCSoundOne = mSoundPool.load(applicationContext, R.raw.eins, 1)

    }

    fun play_one(view: View?) {
        Log.d("SoundPoolTest", "Button Clicked")
        if (mLoaded) {
            Log.d("SoundPoolTest", "Playing wav")
            mSoundPool.play(mCSoundOne, 1.0f, 1.0f, 0, 0, 1.0f)
        }
    }
}

Android: Fix Unauthorized Devices on macOS

  1. Disconnect USB connection between Mac/MacBook and Android device
  2. On the device: Revoke USB debugging authorization in Settings -> Developer Options
  3. cd /Users/<user_name>/Library/Android/sdk/platform-tools
  4. ./adb kill-server
  5. cd ~/.android/
  6. rm -rf adbkey
  7.  Reconnect device
  8. Re-authorize computer to device
  9. cd /Users/<user_name>/Library/Android/sdk/platform-tools
  10. check with ./adb devices that device is authorized

Log4j2 PatternLayout Cheatsheet

In Log4j2 for Kotlin I’ve showed you how to configure a basic logger with log4j2.

If you use a PatternLayout like this

appender.console.layout.type = PatternLayout
appender.console.layout.pattern = %m%n

you can customize the appearance of the output.

eg.

appender.console.layout.pattern = %d{yyyy-mm-dd-HH:mm:ss.SSS} %-4p %C{1}.%M [%t] - %m%n%ex

Parameter

Parameter Meaning
%m The log message
%n line break
%d timestamp
%p priority
%t thread
%C class

Timestamps

 

%d{yyyy-mm-dd-HH:mm:ss.SSS}
2021-50-27-10:50:32.701
Parameter Meaning
yyyy year in four digits
MM

MMM

month in two digits

Name of month three characters wide

dd day
HH hour
mm minutes
ss seconds
SSS milliseconds

Log4j2 for Kotlin

Motivation

Logging is a common good practice in software engineering. It enables you to monitor applications in production to gather information about crashes and other malfunctions for further analysis. It is the “little brother” of debugging and often a precursor for setting up test cases which can lead to reproducing the bugs on the developers machine.

Log4j2 is version 2 of the very famous Apache logging library log4j from the Java ecosystem.

This article describes a minimal working solution for log4j2 with Kotlin and Gradle.

Dependencies

To get started with log4j2 add the following lines to your build.gradle file in the dependency section:

compile "org.apache.logging.log4j:log4j-api-kotlin:1.0.0"
compile "org.apache.logging.log4j:log4j-api:2.11.1"
compile "org.apache.logging.log4j:log4j-core:2.11.1"

Configuration

Continue reading “Log4j2 for Kotlin”

Kotlin Scripts with Gradle

If you are using gradle and you want to run a Kotlin script you have to add the following to your build.gradle file

dependencies {
     implementation "org.jetbrains.kotlin:kotlin-stdlib"
     compile group: 'org.jetbrains.kotlin', name: 'kotlin-script-runtime', version: '1.4.32'
}

Argparse

Primer: Arguments vs Parameters

I’m sometimes confused. Is it an argument or a parameter? So here it goes:

A parameter is a variable in a function definition.

When a function is called, the arguments are the data you pass into the function’s parameters.

The same goes for a program: A program has parameters, you call a program with arguments.

Argparse Module

Batteries included! The argparse module provides a nice way to parse your program arguments:

import argparse

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('positional_param')
    parser.add_argument('-o', '--optional_param')
    parser.add_argument('-r', '--required_param', required=True)
    args = parser.parse_args()
    print(args.positional_param)
    print(args.optional_param)
    print(args.required_param)

Positional Parameters

Positional arguments are useful for shorter programs. These parameters do not have a name. You could call them “unnamed parameters” as well.

It is important that you keep the right sequence when calling the program:

parser = argparse.ArgumentParser()
parser.add_argument('positional_param_one')
parser.add_argument('positional_param_two')
args = parser.parse_args()
print(args.positional_param_one)
print(args.positional_param_two)
$ python positional_args.py foo bar
foo
bar

Optional Parameters

Optional parameters have a name you have to use when providing an argument to the program

parser.add_argument('--optional_param')

The double dash indicates an optional parameter

You can provide a shorthand for an optional parameter as well

parser.add_argument('-o', '--optional_param')

When you leave out an optional argument, the value will be defaulted to None

Two ways of calling a program with optional arguments:

$python optional_args.py
None
$python optional_args.py --optional_param foobar
foobar

Required “Optional” Parameters

Now it gets a bit weird: You can make an optional parameter required.

(another strong argument that these should be named “named parameters”)

parser.add_argument('-r', '--required_param', required=True)

If you don not provide the argument you will get:

$ python required_params.py
usage: required_params.py [-h] -r REQUIRED_PARAM
required_params.py: error: the following arguments are required: -r/--required_param
$python required_params.py -r foobar
foobar

Command Line Help

When you start your script with the -h or –help parameter, you will get a nice overview of the usage

$ python main.py -h
usage: main.py [-h] [-o OPTIONAL_PARAM] -r REQUIRED_PARAM positional_param

positional arguments:
positional_param

optional arguments:
-h, --help show this help message and exit
-o OPTIONAL_PARAM, ---optional_param OPTIONAL_PARAM
-r REQUIRED_PARAM, --required_param REQUIRED_PARAM

Android Asynchronous Http Client

Gradle Dependency

dependencies {
    ...
    implementation 'com.loopj.android:android-async-http:1.4.9'
}

AsyncClient

AsyncHttpClient client = new AsyncHttpClient();
client.get(URL, params, new JsonHttpResponseHandler(){
    @Override
    public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
        super.onSuccess(statusCode, headers, response);
    }
});

Build Request Params

RequestParams params = new RequestParams();
params.put("lat", latitude);
params.put("lon", longitude);
params.put("appid", APP_ID);

k-fold crossvalidation with sklearn

from sklearn.model_selection import KFold

kf = KFold(n_splits=2)

kf.split(df_train)

step = 0 # set counter to 0
for train_index, val_index in kf.split(df_train): # for each fold
    step = step + 1 # update counter

    print('Step ', step)

    features_fold_train = df_train.iloc[train_index, [4, 5]] # features matrix of training data (of this step)
    features_fold_val = df_train.iloc[val_index, [4, 5]] # features matrix of validation data (of this step) 

    target_fold_train = df_train.iloc[train_index, 6] # target vector of training data (of this step)
    target_fold_val = df_train.iloc[val_index, 6] # target vector of validation data (of this step) 

    print("VALIDATE:", val_index)
    print('Dimensions features matrix for validation: ', features_fold_val.shape)
    print("TRAIN:", train_index)
    print('Dimensions features matrix for training: ',features_fold_train.shape, '\n')