情報は力ではない

UE4 とか Blender とか。

ハル研究所プログラミングコンテスト2015

一昨年のハル研プロコン2014に引き続き、去年もハル研プロコンに参加しました。
ハル研究所 プログラミングコンテスト2015 | TOP

今年の問題は宅配便でした。
問題の雰囲気は、車両配送問題(Vehicle Routing Problem, VRP)っぽい感じです。

開催されてからすぐに最適解らしいスコアが上位に現れ、そのスコアの人が上位に連なり、最終的には上位10人が同じスコアになり、1秒未満の戦いが上位で繰り広げられていました。
自分はそんな上には行けませんでした。うーん、悔しい。

自分は普段からコンテストに出ているような人ではないので、いろいろな解法を試してみようと思いながらちょくちょく回答を書いていました。

とかを実装してました。
動的計画法ではなぜかスコアが伸びなかったので(おそらく実装力のなさが原因)、最終的にはビームサーチに頼ってました。
評価関数どうするかがわからなくて結局スコア伸びなかったのですが。

今年度で学生が終わるのでハル研プロコンに出れるのが今回で最後。
今回のプロコンは最適解を出せて初めてスタートラインに立つようなものなので、最後のプロコンでスタートラインに立てなかったのは悔しさが残ります。
でもハル研プロコンに参加して、自分の雑魚さがよくわかったので良かったかなと思います。何より楽しかった。
ハル研プロコン実行委員会の皆さま、楽しいひと時をありがとうございました。


最終的な結果は1月29日に出るようです。

Material Design GuideのListsを読んだ。

そろそろMaterial Designについても知りたいなぁと思ってきたので、Material Designのサイトの気になるところから読んでいる。
今日はListsとLists: Controlを読んだ。
Lists - Components - Google design guidelines
Lists: Controls - Components - Google design guidelines
そこで初めて知ったり、覚えておこうと思ったものを少しメモしておく。
引用の英文を訳しているけど、雰囲気で訳しているので英文と日本語の文は同じ意味じゃないと思う。

リストの要素のテキストの行数が3行より多い場合はCardを使う

If more than three lines of text need to be shown in list tiles, use cards instead.

リストの要素の一番目立つコンテンツが画像ならグリッドリストを使う

If the primary distinguishing content consists of images, use a grid list.

リストの要素の中で最も目立つものは左に置き、最も目立つテキストは最初の行に書く

Bias the most distinguishing content in a tile towards the left of the tile. In tiles with mutli-line content, place the most distinguishing content in the first line.

とりあえず以上。
googleさんのドキュメント量はすごいなぁ。

VimConf 2015に行ってきた。

VimConf 2015に行ってきました。

発表者の方々のスライドへのリンクは次のURLにあります。
http://vimconf.vim-jp.org/2015/#agenda

セッションについては他の方々が紹介していると思うのでそちらにお任せしたいと思います。
申し訳ありません。*1

懇親会

懇親会が始まる前にピザを運ぶのを手伝わさせていただきました。
たくさんのピザを運ぶお手伝いを今までしたことがないので貴重な体験となりました。

このような懇親会に参加するのは初めてなので、どのようにたち振る舞えば良いのかわからなかったのですが
数人の方に話しかけていただきました。本当にありがとうございます。
derisさんに話しかけていただいたのですが、その時すかさずduzzle.vimが好きだということを伝えました。
懇親会ではほとんどVimについて話していないことに気づきました。
それでも非常に楽しいひと時となりました。

終わりに

今回まとめ役をしていただいた@dictavさん、運営の皆さん、発表者の皆さん、会場を貸していただいたmixiさん、ありがとうございました。
是非来年も参加したいと思います!

これで自分のVimConf 2015も終わりです。

*1:自分の不注意でセッションの感想を消してしまいました。

Android Data Bindingを使ってみた。

最近ちょこちょことtechbooster.fmを聞いているのですが、第11回でDataBindingの話をしていて、その存在を知ったのでちょっと使ってみた。
詳しい使い方についてはData Binding Guide | Android Developersに詳しく書いている(はず)です。まだ読んでないです。
以下で出てくるコードはこのサイトに載っているコードです。

準備

appモジュールのbuild.gradleにdataBinding要素を追加する

android {
  ...
  dataBinding {
    enabled = true
  }
}

これだけです。

使い方

DataBindingをするにはlayoutファイルを次のように記述するとcom.example.UserクラスのfirstNameフィールドがTextViewにバインド?される。

<!-- res/layout/main_activity.xml -->
<layout xmlns:android="http://schemas.android.com/apk/res/android">
  <data>
    <variable name="user" type="com.example.User"/>
  </data>
  <LinearLayout
    ...>
    <TextView ...
      android:text="@{user.firstName}"/>
  </LinearLayout>
</layout>

重要な点は4つ。

  1. ルートタグとして<layout>を使うこと
  2. <layout>タグの直後に<data>要素を記述すること
  3. <data>要素の中に<variable>要素を指定し、バインドしたいクラスを指定すること
  4. バインドしたクラスのフィールドを指定するには@{}構文を使用すること

あとは次のようなコードを記述すればDataBindingが行われる。

@Override
public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  MainActivityBinding binding = DataBindingUtil.setContentView(this, R.layout.main_activity);
  User user = new User("Test", "User");
  binding.setUser(user);
}

ここで出てくるMainActivityBindingクラスはDataBindingライブラリによってコンパイル時に作成されるクラスです。
先ほど、main_activity.xmlを書いたのでMainActivityBindingクラスが生成されています。
このBindingクラスの名前はlayoutファイル名をキャメルケースしたものの末尾にBindingという文字列をくっつけた名前になります。
例えばlayoutファイルの名前がitem_view.xmlであればItemViewBindingクラスが生成されることになります。

感想

すごく簡単にしか使ってないけど、結構便利そう。
下の動画でも言っているけど、RecyclerViewを使うときのAdapterやHolderの記述が簡潔に書ける。

www.youtube.com
他のDataBindingライブラリとしてButterKnifeの存在は知っていたけど、なんとなく使うのを面倒に感じていて今まで使っていなかった。
今回のtechbooster.fmがDataBindingを使うきっかけになりました。非常に感謝です。
これからも少しずつDataBindingを使っていこうと思う。

ImageButtonを使ってみた。

f:id:masahiro8080:20151116140122p:plain:w400
上の画像の再生ボタンのようなボタンを作成したかったので、そのためのメモ。

ImageButton

このようなボタンを作成するためにはImageButtonを使う。これは、その名の通り画像付きのボタンを表す。
例えばこんな感じに表示される。
f:id:masahiro8080:20151116141416p:plain:w400
このImageButtonの結果は次のようなコードで得られる。

...
    <ImageButton
        android:id="@+id/click_me_button"
        android:layout_centerHorizontal="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:contentDescription="@string/click_me"
        android:tint="@color/colorAccent"
        android:src="@drawable/ic_action_playback_play" />
...

見ての通り、通常のButtonにtextの代わりに画像を載せた感じになっている。
最初の画像のように背景を透過させたい場合には、ImageButtonのandroid:background属性にアルファ値がffの値を指定してあげれば良い。
ただ、これだとボタンをクリックした時にボタンが何も反応していないような感じになってしまうので、android:background属性には?android:selectableItemBackgroundや?android:selectableItemBackgroundBorderlessを指定してあげるとボタンをクリックした時に波紋が広がるようなアニメーションが得られる。
これを行うことで次のようにボタンの背景が透過されて表示される。
f:id:masahiro8080:20151116142651p:plain:w400

感想

Android開発では色々と学ぶことが多いので大変だけど、それなりに充実しているので、どんどん学んでいきたい。

ActivityUnitTestCaseでIllegalStateException

Androidのテストを学ぶためにCreating Unit Tests | Android Developersを読みながら、そのサイトに載っているAndroidTestFunを写経していた。その時、ちょっと詰まってしまったのでメモ。

ActivityUnitTestCaseのstartActivity()を起点にした例外

AndroidTestFunプロジェクトのlesson4にLaunchActivityTestクラスがあるのだけれど、そのtestPreconditions()を書いてテストを走らせた時に例外が発生した。testPrecondisions()のコードは次のようなもの。

   @MediumTest
    public void testPreconditions() {
        //Start the activity under test in isolation, without values for savedInstanceState and
        //lastNonConfigurationInstance
        startActivity(mLaunchIntent, null, null);
        final Button launchNextButton = (Button) getActivity().findViewById(R.id.launch_next_activity_button);

        assertNotNull("mLaunchActivity is null", getActivity());
        assertNotNull("mLaunchNextButton is null", launchNextButton);
    }

テストのログを見てみると次のようなエラーメッセージが書いてあった。

java.lang.IllegalStateException: You need to use a Theme.AppCompat theme (or descendant) with this activity.

なぜこんな例外が発生するのだろうと思って少し調べてみると、こんなサイトがあった。
Issue 128421 - android - ActivityUnitTestCase startActivity() IllegalStateException - Android Open Source Project - Issue Tracker - Google Project Hosting
どうやら同じような例外が発生している人がいるみたいだった。
このissueでは2つの解決法が提供されていた。

  1. setActivity()をオーバーライドする方法
  2. contextを明示的に設定する方法

setActivity()をオーバーライドする方法

@Override
    protected void setActivity(Activity testActivity) {
        if (testActivity != null) testActivity.setTheme(R.style.AppTheme);
        super.setActivity(testActivity);
    }

contextを明示的に設定する方法

protected void setUp() throws Exception {
   super.setUp();
      
   ContextThemeWrapper context = new ContextThemeWrapper(
          getInstrumentation().getTargetContext(), R.style.AppTheme);
   
   setActivityContext(context);

   (...)
}

自分の場合、どちらの方法を使っても例外が発生しなくなった。
原因はよくわかっていないけど、とりあえずこれでまた写経を始めることができる。

Notificationをユーザに消されないようにする

AndroidでのNotificationをユーザに消されないようにするには次のようにすれば良い。

NotificationCompat.Builder builder =
  new NotificationCompat.Builder(context)
    .setOngoing(true); // このメソッドでtrueを指定する

主な使用用途として考えられるのは、音楽の再生中とかダウンロード中のNotification。
注意としては、setOngoing(true)としている限りNotificationが消えることはないので、音楽の再生やダウンロードが終わったらsetOngoing(false)を指定したNotificationをnotifyする必要があるということ。

追記(2015.11.12)

あまり行儀は良くないのかもしれないけどNotificationクラスのflagsを直接操作してもNotificationを消されないようにできる。

Notification notification = new Notification();
notification.flags |= Notification.FLAG_NO_CLEAR;