Li::Feel

りとるす的雑記帳。

MacBook Pro (Late 2016/with TouchBar)を買って使い始めた話

りとるすです。ご無沙汰してます。 実はMacBook Pro(Late 2016/with TouchBar)を購入しました。

f:id:litols0816:20161206124102j:plain

気がついたらTouchBarありのMacBook Proを発表日に予約してから早一ヶ月、遂に自宅に到着しました。 ただ、タイミングが悪く、自分が終日拘束されている日に来やがった来たので、ようやく日曜日に開封し、日曜日を設定で溶かしました。

スペースグレイを選んだのですが、やっぱりかっこいいです。

スペック的には、

  • 13インチ with TouchBar
  • 2.9GHzデュアルコアIntel Core i5プロセッサ (Turbo Boost使用時最大3.3GHz)
  • 16GB 2,133MHzメモリ
  • 512GB PCIeベースSSD
  • JISキーボード

という最上級ベースモデルのメモリ構成のみいじったような感じになっています。 これは、Macがメモリ食いなのを考慮してのことだったりします。

お値段は学割ストアで税込¥223,452でした。 お財布が寂しい…

永久不滅.comとかが使えるので、Apple Storeで買い物する人はポイントがちょっと多くたまります。 MacBook Proくらいの高額商品を買うときは通しておくことをお勧めします。

よかったこと

TouchIDが便利

TouchIDは反応が早くてとても便利です。App Storeとかで一からパスワードを入力しなくていいのは非常に楽で便利です。 開いてすぐにセンサーに指をのせるだけというお手軽さは非常に便利です。

今までのWindowsより安定している

(完全に僕の感覚ではありますが…)

僕は前代にはVAIO Fit 13Aを使っていたのですが、スペック的には申し分ありませんでした。 ただ、使っているうちに3時間しかバッテリーが持たなかったり、Windows10にしてからというものブルスクが頻発するなど、結構ひどい目にありました。 作業もそこそこやりましたが、それよりもイベントビュアーを眺めている時間のほうが長かったのではないかレベルで酷かったりしました。(4回入院させています)

MacBook Proにしてから比較的システムが安定しているので、その点はVAIOから変えたのはすごいよかったのではないかと勝手に思っている次第です。

小さい

結構フットプリントが小さいです。

なので、13インチのケースだとぶっかぶかになります。

というわけで、僕はZEROSHOCKの11.6インチのものを使用しています。

このサイズが一番ちょうどよいです。

エレコム インナーバック 衝撃吸収 ZEROSHOCK スリム 11.6インチ ブラック ZSB-IBUB03BK

エレコム インナーバック 衝撃吸収 ZEROSHOCK スリム 11.6インチ ブラック ZSB-IBUB03BK

TouchBarが地味に便利

TouchBar、ほとんど使わないのではとか思っていたのですが、使ってみると地味に便利です。 特に、TouchBarだけでスクリーンショットの制御ができるのはデフォルトにはなっていないものの結構便利です。

問題は、Office for macがまだTouch Bar対応していないことですが、気長に待ちたいと思います。

きになること

バッテリー

一部のブログでもちょっと話題になっていますが…

iphone-mania.jp

バッテリーは、わりともたないです。 具体的には、作業内容にもよりますが、5時間〜6時間程度という雰囲気です。

なんかmacOS 10.12.2で改善されるらしいみたいな話を聞いたことがあるので、改善されればいいなーとは思っています。 本体のCPUやらファンがありそうな部分がかなり熱くなってビビるので、それが改善されれればいいなと思っています。

キーボード

まず、キーボードの打ち心地はかなりいい感じです。 心配している人は心配するぐらいならとっとと買ってしまった方がいいくらいかも。

(僕は浅いキーボードの方が好きなので大丈夫なほうですが、メカニカルとか好きな人にはやっぱり厳しいかとは思います)

ただし、ちょっと勢いよく打とうとすると非常にうるさいです。 取り急ぎキーボードカバーを買ったので、とりあえずつけて見て、どうなるかわかりませんがそれで様子を見て見たいと思います。

TouchBarの日本語入力

ちょっと対応が中途半端です。 TouchBarにF7キーに相当するようなカナ変換機能などが、動くアプリと動かないアプリがあります。 なので、今後の対応に期待したいと思います。

あと、ATOKがないのはかなりしんどいので、はやくTouchBarに対応して出して欲しいです。

おわりに

前々からMacに変えたいと思っていて、某インターンを経てMacを買うことを決心してからずいぶん時間がかかってしまいましたが、初めてのMacは概ね満足して使っています。 少なくとも3年以上は丁寧に扱っていきたい次第です。

GradleでSpark Frameworkを使ったAppを実行するとWarnが出てキモいので直した話

フツーにdependenciesにcompile "com.sparkjava:spark-core:2.5.2"を書くと、こんなエラーが出る。

SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.

なんかないって言われてる。ググるとあるあるらしいことが判明。 ログ関係のライブラリだそうで。

とりあえずGradleの依存関係をぱっぱと調べて適当に対応することにする。 やることはdependenciesにもう一つ行を足すだけ。

compile "org.slf4j:slf4j-simple:1.7.13"

いじょ。これでちゃんとログも出るようになります。

Python3.4 + matplotlib + numpy + PyQt5のセットでPyInstallerを使ってexeファイルを作る

Pythonで作ったmatplotlib + numpy + PyQt5なGUIアプリをPyInstallerでexe化しようと思ったら3時間溶かしたのでメモ。

実行環境

  • Python3.4.5 32bit
    • Python3.5.x系だとうまくいかない。
  • Windows10 Pro 64bit
    • 64bitだけどPythonは32bitで。

numpyとscipyはこのサイトからダウンロード&インストール

http://www.lfd.uci.edu/~gohlke/pythonlibs/www.lfd.uci.edu

ファイルダイアログの読み込みの解決

PyQt5でファイルダイアログ等を使用する場合、tkinterのインポートも必要です。 PyInstallerはimportのあたりを解析してパッケージに含めるものを決めているようです。 インポートは結局こんな感じに。

from PyQt5.QtWidgets import (QMainWindow, QApplication, QWidget,
                             QGridLayout, QVBoxLayout, QHBoxLayout,QFileDialog,
                             QLabel, QLineEdit, QPushButton)

from window import Ui_Form
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt5 import NavigationToolbar2QT as NavigationToolbar

from matplotlib.figure import Figure
import matplotlib.pyplot as plt
import numpy as np
import random
import seaborn as sns
import copy

import tkinter
import tkinter.filedialog as FileDialog

hook-numpyを作成する

問題はこのままでは動きません。実行時に次のようなエラーが吐かれます。

Intel MKL FATAL ERROR: Cannot load mkl_intel_thread.dll.

そこで、StackOverflowの神々が書いたhook-numpy.pyというスクリプトをPyInstallerに追加します。 追加先は、C:\[Python34の位置]\Lib\site-packages\PyInstaller\hooksで、次のようなスクリプトを追加します。

from PyInstaller import log as logging 
from PyInstaller import compat
from os import listdir

mkldir = compat.base_prefix + "/Lib/site-packages/numpy/core" 
logger = logging.getLogger(__name__)
logger.info("MKL installed as part of numpy, importing that!")
binaries = [(mkldir + "/" + mkl, '') for mkl in listdir(mkldir) if mkl.startswith('mkl_')] 

stackoverflow.com

exe化のコマンド

ここまでやって、以下のようなコマンドで実行。

pyinstaller --hidden-import="tkinter" main.py

やっと動いた!寝る!

Android開発:RxJavaのお勉強記事まとめ

なんで急にRxJavaなんて始めたのか

夏休みに某所にインターンシップに行ったとき、初めてRxJavaの存在を教えてもらったのがきっかけで、ちょっと気になって調べてだいぶよさそうだったので、今作っている某アプリに組み込むことにしました。

理解するのにだいぶ苦労したので、お勉強するときに見た記事を書いておきます。

さわりだけまとめる

RxJavaは、ReactiveXJava用の実装で、Observerパターンの拡張にあたります。 Observableから値やらが同期・非同期で流れてくるので、それを関数型プログラミングのノリで加工したり、処理の状況をSubscriberに通知したりといったことができます。

Android開発において特に有用なのが、RxJavaを用いた場合、悪名高きAsyncTaskやAsyncTaskLoaderのコールバック地獄を解消できる上にエラーハンドリングがだいぶ楽になるといった点で、AsyncTask系さっさと滅びてくれと思っていた自分的には絶対に得だと思った次第です。

あとは、Android界隈の神、JakeWharton氏の所属するSquare印のRetrofitが対応しており、Androidの非同期処理は大抵ネットワーク接続な気がしていることから、これをやっておけば当分大丈夫なのではという打算があります。

基本はこの記事

この記事が非常によくまとまっており、勉強する上で楽でした。

qiita.com

Observableの生成について

ReactiveXの提供するドキュメントはわりとしっかりしている(気がする)ので、そこを見れば大抵わかります。

ReactiveX - Operators

ただ、RxJavaで同期処理を非同期で書こうとすると、Observable.create()を使うことが多いと思いますが、ドキュメント上は

advanced use only! create an Observable from scratch by means of a function, consider fromEmitter instead

Creating Observables · ReactiveX/RxJava Wiki · GitHub

となっており、実装にはちょっと注意が必要です。

RxJavaの項目を見ればわかりますが、

It is good practice to check the observer’s isUnsubscribed state from within the function you pass to create so that your Observable can stop emitting items or doing expensive calculations when there is no longer an interested observer.

ReactiveX - Create operator

とか書いてあります。ただ、日本語のブログでこれをしっかり守ってisUnsbscribed()でのステータスチェックをしている例は見かけなかったので十分に注意が必要かと思います。

unsbscribeについて

メモリリークしないようにOnDestroyとかでunsubscribeしておきましょう。 NullPointerExceptionにならないように、Subscription.empty()とかで初期化しておきましょう。

qiita.com

さいごに

ほかにも、これは勉強しておいたほうがいいよ!とか、この解釈ちょっと違うよ!とかあれば教えていただければ幸いです。

Android開発:Dagger2でDI(Dependency Injection)する備忘録

DIってなんだ

Dependency Injectionの略で、依存性の注入と訳すらしいです。なんか依存性注入って訳すんじゃないよって記事を見た気がしますが、話がややこしいのでスルーします。 Dと呼ばれるモノは基本的にはライブラリがなくても、外からモジュール等を注入できる構造になっていればいいようですが、プログラムの構造に影響を与えたり、AndroidのActivityやFragmentなどの癖の強いオブジェクトの類だとしんどそうな印象です。

Daggerは、DIコンテナと呼ばれるDIのお助けツールで、@OverrideなどでおなじみのJavaアノテーションと一部のクラスの追加でお手軽にDIができてしまうという代物です。 google.github.io

DIコンテナは、リフレクションに置き換えて実行時にリフレクションしまくるという方法で実装されているものがありますが、リフレクションなので基本的に負荷が高めのようです。 Daggerでは、ビルド時に一部のコードを自動生成することによってDIを実現しているので、リフレクションを使ったDIよりも負荷が低く、高速にDIができるようです。 特に、Dagger2はGoogle謹製なので、Androidでは重宝されているようです。 その他、Dagger以外にはSpring FrameworkとかDIコンテナらしいですね(よく知らない)。

DI、一体何がうれしいのか

システム設計の評価基準で、モジュール結合度というのがあるのはIPAの春と秋にやる試験で出てくるので学生でも聞いたことがあるという人は多いはず。 簡単に言えば、DIを使うことでモジュール結合度が下がり、単品でテストがしやすくなるって思っておけばたぶん大丈夫なのでは。 後述のprovideで提供するインスタンスをすっと差し替えてあげれば、あっさり単体テストができるようになるわけです。 個人的に、AndroidにおけるContextとかは神インスタンスという感じの割には、別にプログラマーが生で触れることってあまりないので、外から注入できるのは非常にありがたい気がします。

早速使う

Dagger2でのDIは全部で3種類Injectionの方法がある。

この記事では、Constructor Injectionの方法と、Field Injectionの方法だけメモっておくことにします。

DaggerでDIするための準備

注入内容の用意

Daggerでは、注入内容をModuleというクラスで用意します。 このModule内のprovideHogeメソッドでインスタンスを生成し、依存性があるインスタンスに注入します。 ここでは、ちょっとググってもあまり日本語の情報がない2種類の書き方を紹介します。

@Module
public class InfraModule {

    @Provides
    @Singleton
    public AuthInfoRepository provideAuthInfoRepository(Application application){
        return new AuthInfoRepositoryImpl(application);
    }

    @Provides
    @Singleton
    public ApiClient provideApiClient(){
        ApiClient cl= ApiClientFactory.getSingleton();
        cl.setOAuth(BuildConfig.CONSUMER_KEY, BuildConfig.CONSUMER_SECRET_KEY);
        return cl;
    }

}

基本的には、@Moduleを付けることで、こいつがModuleであることをDaggerに明示します。

また、インスタンスを提供するメソッドは、provideAuthInfoRepositoryや、provideApiClientといったような名前で命名する規則があるほか、@Providesアノテーションを付ける必要があります。 Daggerの機能で、@Providesと一緒に@Singletonを付けておくと、シングルトンインスタンスになるため、Singletonパターンの実装をサボれたりします。

注入する依存性が更に依存性を持つような場合、メソッドの引数に他のモジュールでprovideされているものであれば、勝手にDaggerが依存性を注入して良きようにしてくれます。

その他、型さえ合っていれば中の処理は気にしないので、外側に提供するインターフェースと、実装をわけるといったことももちろんOKです。

こんなこともあり、ModuleクラスはFactoryMethodパターンの集合に近い実装になるかと思います。

AndroidのApplicationインスタンスを依存性として提供するなら、こんな感じの実装に。

@Module
public class AppModule {
    private Application app;

    public AppModule(Application app){this.app=app;}

    @Provides
    @Singleton
    public Application provideApplication(){return app;}

}

Componentの用意

Daggerでは、Moduleと実際の注入先の橋渡しとして、Componentを用意する必要があります。

@Singleton
@Component(
        modules={
                AppModule.class,
                InfraModule.class
        }
)
public interface AppComponent{
        void inject(LoginActivity activity);
}

このComponentでは、@Componentアノテーションでモジュールを指定し、HogeComponentという名前のインターフェースにinjectメソッドを定義するだけでOKです。 injectメソッドの引数には、依存性の注入先のクラスを指定します。 その他、依存性を注入したいクラスが増えたらオーバーロードすればOKです。

Applicationクラスに細工する

Componentインターフェースなどをそのままにしても何も起こらないので、Androidで一番上位のライフサイクルを持つApplicationインスタンスを継承して、独自のApplicationを作ります。

public class MyApp extends Application {

    private AppComponent appComponent;

    @Override
    public void onCreate() {
        super.onCreate();
        // AppComponentでdeprecatedエラーが出るとき
        // そのモジュールが使用されていないため、no-opになる。無視可
        appComponent=DaggerAppComponent
                .builder()
                .appModule(new AppModule(this))
                .infraModule(new InfraModule())
                .build();
    }

    public AppComponent getAppComponent(){
        return appComponent;
    }
}

このApplicationでは、AppComponentのインスタンスを持つようにします。DaggerAppComponentはビルドすると自動的に作成されますので、builder()を用いてインスタンス化したモジュールを指定し、最後にbuild()すれば準備はOKです。後でComponentを使って依存性をActivityに注入をするので、Componentを取り出せるようにアクセサメソッドを用意しておきます。

ちなみに、自作のApplicationを使用する場合は、AndroidManifest.xmlのapplicationタグのandroid:name属性をいじる必要があります。

    <application
        android:name=".MyApp"
        ....

ここまでがDIコンテナの依存性注入のための準備になります。 ここから先は、実際に依存性を注入する方法について見ていきます。

Daggerで実際にDIする

Field Injection

Field Injectionをする場合は、注入先のフィールドに対して、@Injectアノテーションをつけ、Applicationインスタンスが保持しているAppComponentのinjectメソッドを呼び出すことによって、フィールドに対して依存性注入を行います。 AndroidのActivityなど、コンストラクタにアクセスできないものについては、Field Injectionを用いてDIするのが推奨されているようです。

public class LoginActivity extends AppCompatActivity {

    @Inject
    ApiClient apiClient;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);

        ((MyApp)getApplication()).getAppComponent().inject(this);
    }
}

Constructor Injection

Constructor Injectionをする場合は、コンストラクタに@Injectアノテーションをつけ、依存するクラス型の変数を引数にとることで、依存性の注入を行うことができます。 コンストラクタ内で注入した内容は、フィールドに保存することによってインスタンス内で自由に使えるようになるわけですね。

public class LoginActivityUtil {
    private LoginActivity activity;
    private ApiClient apiClient;

    @Inject
    public LoginActivityUtil(ApiClient apiClient) {
        this.apiClient=apiClient;
    }
    …
}

Constructor Injectionの場合は、Componentインターフェースへのinjectメソッドの追加は不要のようです。

DIの使いどころは?

Androidは、ActivityやらFragmentがなんでもできすぎるせいで、Fatになりやすい傾向があるので、DIコンテナを使ってしっかりと層分けをすると、かなり見通しがよくなる気がします。 Android-CleanArchitectureはDaggerを使って実現されていますが、ちょっとそのままだと冗長で、言うほど大きくないアプリを作るときは必要なモノだけ抜粋したものをつかうのが良いんじゃないでしょうか。 ちょうどこのサイト掲載のやつとかはサイズ感が良い感じで読みやすいです。 tech.recruit-mp.co.jp

さいごに

備忘録で自分の分かったことをノート代わりに書いているだけなので、間違ってたら教えて欲しいです。 Daggerにはその他にも便利機能が山ほどあるので、少しずつ勉強していきたい次第です。 あとはてなブログMarkdownで書けるのはやっぱり最高ですね。

References

Dagger2を味見してみたkazucocoa.wordpress.com