Java Rubik's Cube

On the Thunkable site, "Thunkable App of the Month - July 2018" had been announced. It is an application to explain the solution of Rubik's Cube. I have a special Rubik's cube called Java Rubik's Cube. It was distributed as a souvenir at Sun Tech Days 2007 in Tokyo more than 10 years ago. I completely forgot the solution, but this app should lead me well.

Rubik’s Cube Solving Guide by Winston Riggs

Java Rubik's Cube (on the left)

Java Rubik' Cube is somewhat more difficult than general Rubik's Cubes in the first stage. When a surface is filled with the same images, they must be arranged in the same direction as in the following figure. However, after overcoming this constraint, the latter half of the solution might become rather easy.








A JSON Decoding Extension for App Inventor (2)

In the previous article, I introduced a JSON Decode Extension to easily extract the necessary information from the JSON file received from a Web service. This time, in order to test this Extension, I created a simple book search application. There are many applications of this type, but the concern here is how easy it is to decode JSON files.

Results from the book search app
The created application is as shown above. It shows the search results of one English book and two Japanese books. Giving a few keywords, Google Book Search searches for books and returns the results in JSON text as shown below. In this example, I set to receive only one book out of hit books.

JSON text sent back from the web service (a part)
For example, in the first search, "Galois" and "Groups" were given as keywords. The resulting Json text is shown above. "title", "authors", "publishedDate", "thumbnail" and "description" are extracted and displayed from this data. The program is shown in the figure below. This is all of the source program. Therefore, it can be said that this is made quite compact.

Complete App Inventor source program of the book search

However, there is still room for improvement. For example, the current Extension receives the following list individually as a search instruction string.

query for title -> "items,volumeInfo,title"
query for authors -> "items,volumeInfo,authors"
query for publishedDate -> "items,volumeInfo,publishedDate"
query for thumbnail -> "items,volumeInfo,imageLinks,thumbnail"
query for description -> "items,volumeInfo,description"

This is a little inefficient. The values ​​of tags at the same hierarchical level should be collectively received as follows. In the near future, we plan to revise the extension so that we can respond to this. That way, you can make this application even easier.

query for several items -> "items,volumeInfo,[title,authors,publishedDate,description]"
query for thumbnail -> "items,volumeInfo,imageLinks,thumbnail"


A JSON Decoding Extension for App Inventor (1)

[This Extension and  its doc are available. Please see the bottom of this article.]

JSON format is commonly used when receiving data from Web services, etc. With App Inventor, JsonTextDecode in the web block can convert JSON to list structures. Then, the conversion result can be manipulated by the selectItem and lookUpInPairs of the list block. However, as Evan W Patton (MIT) pointed out in the paper [1], these list processes are generally very complicated. And he also suggested a more readable and compact Extension block to alleviate this. 

I independently developed an Extension for JSON decode based on his new block idea. This Extension might be intuitive and easy to understand because it can hierarchically acquire necessary information with the tag names (properties) without using complicated operations on nested lists. The outline is shown in the figure below. (please enlarge and see the figure.)

This Extension takes two arguments. One is JSON data that was converted into list structure. The other is a search instruction list for hierarchically specifying the value of a specific tag (property). In this example, JSON text holds the values ​​of four kinds of sensors as "healthData". In the above figure, the name of the third sensor is specified. Note that in the query list, a number such as "3" indicates the element index of the JSON array structure.

Query List : John, healthData, 3, sensor
Result : Systolic pressure

JSON data used here is a modified version of the health data published in the following document [2]. The following figure shows the part of listing up all four sensors and their values ​​using this Extension. I think that it is written concisely. Operations for complicated list processing are not appeared here.

Collecting values of the four sensors

An example of running this application is shown below. For details, please see the files shown below.

Result of the test program on Android

Within this Extension, the list structure is iteratively processed using the function of YailList [3]. I think that YailList makes somewhat relaxation of complicated data type conversion (casting)  in JAVA. This Extension is still in beta. Although some of the JSON structures have been tested, all the structures are not covered, so bugs may be included. However, it is shown below for your reference. It was tested with Nexus 6 (Android 7.1.1). This extension was created using AppyBuilder Code Editor [4].


[1] JSON Interoperability in MIT App Inventor
[2] http://georgepavlides.info/ehealth-made-simple/
[3] http://3nportal.com/AIBridge/API/com/google/appinventor/components/runtime/util/YailList.html

[4] AppyBuilder Code Editor


Make a mini calendar app for Android, celebrating the New Year

Celebrate the New Year and make a small app! As you can see from the calendar, there are several months with the same day of the week. So, let's make an application that groups months by the day of the week on the 1st day as a key.

[ For Japanese version, please click here.]

grouping months by the day of the week on the 1st day

Although this mini app is not so practical, I will make it with the following five goals:

[1] Make the application logic in Java for Android.
[2] Use lambda expressions, streams, and the new date classes provided by Java 8.
[3] Create a GUI with App Inventor and call Java from there.
[4] Create as a general-purpose framework applicable to other applications.
[5] Customize the ActivityStarter to create a new block.

First, I will talk about [1] and [2]. With the recent Android, we can use Java 8 features. So, I'm going to write this app as concisely as possible using lambda expressions and streams. The logic part is as follows. The essential part is only one assignment statement to a Map object named "mp". The element of this object is a pair of "day of the week" and "a list of months whose first day matches that day of the week".

Next is [3] and [4]. Java programs like the above can be called using App Inventor 's Activity Starter function (block). I will use it, but in order to make it a general-purpose framework, I prepared a template for both the App Inventor side and the Java side. On the Java side, I prepared an input processing part and an output processing part beforehand so that users can complete it by rewriting only the application logic. Also, the App Inventor side has been designed to be applicable to many other applications as shown below. 

A generic App Inventor application that calls Java programs

With regard to the last item [5], I wanted to slightly change the input data and parameters passing to Activity Starter, as a result of considering the versatility as described above. So, I customized ActivityStarter and created new blocks shown below, using AppyBuilder Code Editor. I / O with the Java side was designed to do via a text file. Regarding the input, I provide two ways, passing the path of the input file and passing the text data directly. The boolean parameter "isFile" in the Setup block blow makes this selection possible.

Newly created App Inventor block (customized version of Activity Starter)

The entire App Inventor program created using this new block is as follows.

App Inventor program with newly created block

[Note] About Android and Java 8
Under Android 5.0 (API level 22), it is Java 7 compliant and Java 8 cannot be used. Android 6.0 (API level 23) can use part of lambda expressions etc., but seems to require Android 8.0 (API level 26) or higher in order to use full functions including streams.







【3】GUIはApp Inventorで作り、そこからJavaを起動する。

まず、【1】と【2】ですが、最近のAndroidでは、Java8の機能が使えることが分かりました。そこで、ラムダ式とストリームを使って、できるだけ簡潔にこのアプリを書いたつもりです。そのロジック部は、以下の通りです。曜日や月の名前は英語ではなく、日本語にすることもできました。本質的な部分は、Mapオブジェクトmpへの代入文1つだけで済んでいます。このmpの要素は、 [曜日, 初日がその曜日である月のリスト]のペアとなります。

次に、【3】と【4】です。上記のようなJavaプログラムは、App InventorのActivity Starter機能(ブロック)を使って、App Inventorから呼び出すことができます。ここでも、それを使うのですが、できるだけ、汎用的な枠組みにするため、App Inventor側とJava側の両方のひな形を用意しました。Java側には、入力処理部と出力処理部を予め備えておき、上図のようなロジックの記述部だけを書き換えるだけで、ほぼ済むようにしました。また、App Inventor側も、下図のような、他の多くのアプリにも適用できるデザインにしました。

Javaプログラムを呼び出す汎用的なApp Inventorアプリ

最後の【5】ですが、上記の汎用性を考えたことにより、Activity Starterに対して、入力データやパラメータの受け渡しを多少変えたくなりました。そこで、それらに関するカスタマイズを行い、新たなブロックを作りました。以下がそれらのブロックです。Java側との入出力は、テキストファイルを介して行うことにしていますが、入力関しては、入力ファイルのパスを渡す場合と、テキストデータを直接渡す場合の2とおりを選べるようにしました。以下にあるSetupブロックの"isFile"でその選択ができます。

新規作成App Inventorブロック(Activity Starterのカスタマイズ版)
この新規ブロックを使って作ったApp Inventorのプログラムの全体は以下のとおりです。

新規作成ブロックを使ったApp Inventorプログラム

Android 5.0(APIレベル22)以下では、Java7対応であり、Java8は使えません。Android 6.0(APIレベル23)ではラムダ式の一部などは使えますが、ストリームも含めたフル機能を使うには、Android 8.0(APIレベル26)以上が必要のようです。