OmniAICreator/Qiita-1.07M huggingface dataset:
「Twitterのめっちゃ高度な検索」でTwitter検索を楽にしました

1年前くらいに [Twitterを使いこなす！検索オプションまとめ](https://qiita.com/afonomics/items/98a6b7dd011844ed797b) という記事を書いた者です。その後、サーバーなどをレンタルして、Twitter検索を楽にするページ「[Twitterのめっちゃ高度な検索](https://app.afonomics.com/TwitterMoreSearch/)」というページを作ったので紹介させてくださいm(_ _)m

# 「Twitterのめっちゃ高度な検索」とは

Twitterには、様々な検索オプションが用意されています。その一部は、冒頭の記事で述べていますが、実際に検索するときに都度都度コピペするのは、使う側としても教える側としても非常に手間でした。そこで、簡単なHTMLとJavaScriptで複雑なオプションを手軽に使えるようにしたのが「Twitterのめっちゃ高度な検索」です。

名前は、[高度な検索](https://twitter.com/search-advanced?lang=ja)というTwitter社の公式ページをもじりました。

# ざっくりと仕組みについて

HTMLで`form`を作って、検索ボタンを押せばJavaScriptが走ってクエリをTwitterのURLに投げるだけという、至ってシンプルな仕組みです。とてもシンプルですが、一応コードを載せます。

```javascript:search.js
$(document).on('click', "[id='submit']", function () {

//Twitter検索のベースを格納
    var baseURL = 'https://twitter.com/search?f=tweets&q=';
//ボタンが押されてたら、対応するクエリを入れる。
    if (document.form.qqq.value != "") {
        baseURL += form.qqq.value;
    }
    if (document.form.from.value != "") {
        baseURL += " from:" + form.from.value;
    }
/～中略～//
    if (document.form.follows.checked) {
        baseURL += ' filter:follows';
    }
//最後にエンコード等してあげて、Twitterに投げる
    baseURL += '&src=typd';
    var encodeURL = encodeURI(baseURL);
    var searchURL = encodeURL.replace('#', '%23');
    console.log(searchURL);
    window.open(searchURL);

})
```

# 一度使ってみてください:grinning:

仕組みについては以上の通りです。特に書くことがなくすみませんが、よくTwitterを使われる方はぜひ「[Twitterのめっちゃ高度な検索](https://app.afonomics.com/TwitterMoreSearch/)」を使ってみてくださいませ！
[![TwitterMoreSearch.png](https://qiita-image-store.s3.amazonaws.com/0/121869/86d6c88a-025e-a688-640b-d2bb1f3af8e6.png)](https://app.afonomics.com/TwitterMoreSearch/)
KotlinのSpringBootエラー対応

# 1. Gralde設定エラー

[Spring Initializr](https://start.spring.io) でプロジェクトを作成。
IntelliJ IDEで開き、SpringBootは起動するがサンプルで作ったHelloControllerにアクセスすると例外が発生。

```kotlin
java.lang.NoClassDefFoundError: kotlin/jvm/internal/Intrinsics
	at com.example.demo.HelloController.hello(HelloController.kt) ~[classes/:na]
```

build.gradle で次のエラーが出ているのを発見。

```kotlin
only buildscript {} and other plugins {} script blocks are allowed before plugins {} blocks, no other statements are allowed

```

buildscript {} の後ろに plugins {} を記述後に再起動したら無事に動きました。

**References**
- [Gradle の基本的な使い方 (Java)](https://www.qoosky.io/techs/cb27845e6f)

# 2. アプリ起動時のBeanDefinitionParsingException

Eclipse に Kotlin プラグインをインストールしてアプリを起動すると、BeanDefinitionParsingException が発生。ちなみに、IntelliJ IDE での起動時には発生しませんでした。

```java
org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: @Configuration class 'ExampleApplication' may not be final. Remove the final modifier to continue.
```
エラーメッセージより、起動クラスが、final なのが問題らしい。
class の前に、open を付けて起動すると例外が消えました。

```java
package com.example.app

import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication

@SpringBootApplication
class ExampleApplication

fun main(args: Array<String>) {
	runApplication<ExampleApplication>(*args)
}
```

**References**
- [The Journey of a Spring Boot application from Java 8 to Kotlin: The Application Class](http://engineering.pivotal.io/post/spring-boot-application-with-kotlin/)
超初心者webpack,npmメモ

# 超初心者webpack,npmメモ

## 環境

```
npm --version
6.5.0-next.0
```

```
npx webpack --version
4.28.3
```

## npm

### ローカルにnpm installしたコマンドを呼び出す

```
npx webpack
```

## webpack

### jsファイルを更新したら自動でビルドする（webpack単体）

```
webpack -w
```
* webpack.config.jsが用意されてる前提
* ちなみにファイル更新するたびに何かのファイルが出来る

### jsファイルを更新したら自動でビルドする（webpack-dev-server）

```
webpack && webpack-dev-server --mode development
```
* サーバが立つので、`http:localhost:8080` へアクセスする
* ファイルを更新すると、`http:localhost:8080` を開いているブラウザが自動でリロードされる
atcoder ABC112 C問題

今回は方針は立ちやすく簡単
https://atcoder.jp/contests/abc112/tasks/abc112_c#方針

#方針
中心座標が101*101通りくらいしかないので全探索で、確定できる。この時、Hを情報iから求め、全部の情報と照合することで確定できる。注意点として、高度が0の時を、Hとしてしまうと、間違った答えになるので注意。
atcoder ABC110 C問題

今回は方針は立ちやすかったが、中々色々なパターンが存在し、全てに対応できる解法を思いつくのが難しかった。
https://atcoder.jp/contests/abc110/tasks/abc110_c
#方針
文字列S,Tが与えられSの文字の中のある文字c1とc2をスワップしていき、最終的にTになるかという問題。方針としては、S,Tについて左から文字を見ていき、次の2パターンについて考える。
(1)Sのi文字目とTのi文字目が一緒の時
ok
(2)Sのi文字目とTのi文字目が違う時
Tについて、i文字目より後ろの文字を見ていき、Tのi文字目と同じ時、何文字目かを配列などで記録。その後、Sについてi文字目より後ろを見ていき、先ほど記録した文字目では、Sのi文字目と一緒か判定。また、それ以外の文字目では、Sのi文字目と違うかを判定していく。一度判定が終わったら、そのアルファベットは関与しないので消していくことで、TLEを防げる。
lsコマンドの色を変更する

lsコマンドで表示されるディレクトリの文字色が青だと見辛い時があります。
そんな時に変更する方法を紹介します。

## linuxでの変更方法
1. ターミナルの色に関するファイルを取得　`dircolors -p > ~/.colorrc`
2. `.colorrc`の中の, ディレクトリの色を指定しているところを変更
3. 変更した`~/.colorrc`をlsの時に反映されるように~/.bashrcに追記

- ディレクトリの色を指定しているところはこんな感じになってます。  

```sh:.colorrc
### 中略 ###

RESET 0 # reset to "normal" color
DIR 01;34 # directory
LINK 01;36 # symbolic link. (If you set this to 'target' instead of a
# numerical value, the color is as for the file pointed to.)

### 中略 ###
```
- `.bashrc`に追記する内容は以下です

```sh:.bashrc
eval `dircolors ~/.colorrc`
alias ls='ls --color=auto'
```



色と番号の対応は下の表のようになってます。

|番号|色|
|---|---|
|30|黒|
|31|赤|
|32|緑|
|33|黄|
|34|青|
|35|紫|
|36|水|
|37|白|

[https://www.gfd-dennou.org/arch/morikawa/memo/ls_colors.txt](https://www.gfd-dennou.org/arch/morikawa/memo/ls_colors.txt)


## macで変更する場合
LSCOLORSという環境変数に色のパラメータを指定してあげます。

```sh:config.fish
set -x LSCOLORS  exfxcxdxbxegedabagacad
```
```sh:.bashrc
export LSCOLORS=exfxcxdxbxegedabagacad
alias ls='ls -G'
```

一番先頭(例ではex)がディレクトリの文字色を設定するパラメータです。
色とパラメータの対応は下の表のようになってます。

|パラメータ|色|
|---|---|
|a|黒|
|b|赤|
|c|緑|
|d|茶|
|e|青|
|f|マゼンタ|
|g|シアン|
|h|明い灰|

[ls の結果に色をつける - ねもぷらす](http://nemoplus.hateblo.jp/entry/20090119/1232373540)
railsのディレクトリでbundleコマンドエラー

bundleコマンドでエラーにハマったのでメモ。

# 症状
特定のディレクトリでbundleコマンドを打つとエラーになる。

```
$ bundle
Traceback (most recent call last):
	2: from /Users/<username>/.rbenv/versions/2.5.3/bin/bundle:23:in `<main>'
	1: from /Users/<username>/.rbenv/versions/2.5.3/lib/ruby/2.5.0/rubygems.rb:308:in `activate_bin_path'
/Users/<username>/.rbenv/versions/2.5.3/lib/ruby/2.5.0/rubygems.rb:289:in `find_spec_for_exe': can't find gem bundler (>= 0.a) with executable bundle (Gem::GemNotFoundException)
```

# 調査
切り分けにより、Gemfile.lockがあるディレクトリでbundleを打つとエラーになることを確認。
Gemfile.lockを確認すると、bundlerのバージョンが古い。

```
$ gem list bundler

*** LOCAL GEMS ***

bundler (2.0.1)
```

```Gemfile.lock(修正前)
(前略)

BUNDLED WITH
   1.17.1
```

# 対策
Gemfile.lockのbundlerのバージョンを修正したらなおった。

```Gemfile.lock(修正後)
(前略)

BUNDLED WITH
   2.0.1
```

```
$ bundle -v
Bundler version 2.0.1
```
phpMyAdminを日本語化する方法

# 環境
MAMP 5.2
phpMyAdmin 4.8.3

# 日本語化する方法
まず、phpMyAdminのトップページを表示します。（左上にあるphpMyAdminのロゴ、または家のアイコンをクリックしたらトップページが表示されます）

次に、`Appearance settings（外観の設定）` > `Language（言語）` の値を、
`English` から `日本語 - Japanese` に変更します。

![スクリーンショット 2019-01-04 22.59.20.png](https://qiita-image-store.s3.amazonaws.com/0/317569/bd4a64fe-c2da-2fd3-e52a-96f35fa80e6b.png)
↓
![スクリーンショット 2019-01-04 22.53.28.png](https://qiita-image-store.s3.amazonaws.com/0/317569/f2171601-553e-1500-7769-cae0c638ed4e.png)

これで、phpMyAdminを日本語で使用することができます。
Lubuntu 18.10でprocessingのフォント設定

Lubuntu 18.10にprocessingをインストールした際にフォント設定に引っかかったのでその対処法を共有します。
# 環境
- OS: Lubuntu 18.10 (64-bit AMD64)
- Processing 3.4 (Linux 64-bit)
    - ダウンロードしたzipを解凍して適当なディレクトリに置き、install.shで.desktopファイルを作成 (ここらへんは割愛します)

# 引っかかった現象
File > PreferenceからLanguageに日本語を選び、Editor and Console fontでフォントを変えるわけですが、このフォント選択プルダウンのリストが表示されません（グレーアウトされてる）。
![processing_preference.jpg](https://qiita-image-store.s3.amazonaws.com/0/336571/5de4c2e7-429f-ea0a-3fae-b392dcb3aa1d.jpeg)

したがってデフォルトのSource Code Proからフォントを変更できず、Languageを日本語にしてもコメントが文字化けしてしまいます。

# 対処
- 日本語に対応したフォントを用意
下記ディレクトリに表示させたいフォントファイル(*.ttf)を配置します。 
/opt/processing-3.4/lib/fonts
私はここにipag.ttf (IPAゴシックフォント)を置きました。

- preference.txt(設定ファイル)を直接修正
設定ファイルを直接修正します(processingを起動している場合は一旦落としてください)。設定ファイルはユーザーディレクトリ直下の.processingにあります。
/home/userName/.processing/preference.txt
このファイルの中のフォントファミリーをしている部分を修正します。
修正前
`editor.font.family=Source Code Pro`
修正後
`editor.font.family=IPAGothic`
修正したファイルを保存して、processingを起動すると期待したフォントで文字が出力されます。
ただしあいかわらずPreference画面(GUI)上では設定フォントがSource Code Proのままグレーアウトされています。が、とりあえず日本語でコメントできるようになったので私は気にしないことにしました。

そもそもLubuntuでprocessingやってる人が少ない気がしますが…。
他にもっと良い方法があれば、教えていただけると嬉しいです。
ゼロから作るDeep Learning② １章 自分用まとめ

#### Matrix Multiply (MatMul) 行列の積

アフィンの元となる計算式。

**Forward** (P30)

```math
y=xW
```

```python
return x*W
```

**Backward** (P31)

```math
\frac{\delta{L}}{\delta{x}}=\frac{\delta{L}}{\delta{y}}W^T
```

```math
\frac{\delta{L}}{\delta{W}}=x^T\frac{\delta{L}}{\delta{y}}
```

```python
dx = np.dot(dout, W.T)
dW = np.dot(x.T, dout)
```

#### Affine アフィン

ニューロンの値に、重みWを掛け、バイアスbを足す。

**Forward** (P10)

```math
h=xW+b
```

```python
return np.dot(x, W) + b
```

**Backward**

数式はMatMul参考

```python
dx = np.dot(dout, W.T)
dW = np.dot(x.T, dout)
db = np.sum(dout, axis=0)
```

#### Sigmoid function シグモイド関数

活性化関数の一部。アクティベーションを求める。
各クラスのスコアを出力する。スコアは0〜1の値となる。
スコアとは「確率」になる前の値。スコアが高ければ高いほど、そのニューロンに対応するクラスの確率も高くなる。ソフトマックスとは違い、それぞれの入力値は独立して0〜1の範囲に収まるよう計算される。

**Forward** (P12)

```math
σ(x) = \frac{1}{1+exp(-x)}
```

```python
return 1 / 1 + np.exp(-x)
```

**Backward** (P36)

```math
\delta{x} = \frac{\delta{L}}{\delta{y}}y(1-y)
```

```python
return dout * (1.0 - out) * out
```

#### Softmax function ソフトマックス関数

出力の各要素は0〜1の値を取り、全ての要素の合計は1になる。つまり、「確率」と解釈できる。

**Forward** (P19)

```math
y_k = \frac{exp(s_k)}{\sum_{i=1}^{n}exp(s_i)}
```

```python
x = np.exp(x)
x /= x.sum(axis=1, keepdims=True)
return x
```

**Backward** (P38)

特に数式はない。

#### Cross Entropy Error 交差エントロピー誤差

入力が、確率（要素合計が1となるリスト）と教師ラベル（ont-hotベクトル）を取り、その誤差（１つの数値）を出力する。
数式を見ると、教師ラベルが0（tk=0）の要素は、出力結果に影響しないので、実質的には正解ラベルが1の要素に対応する出力の自然対数(log)を計算するだけになる。

**Forward** (P20)

```math
L=-\sum_{k}t_k\log y_k
```

ミニバッチを考慮した場合

```math
L=-\frac{1}{n}\sum_{n}\sum_{k}t_{nk}\log y_{nk}
```

```python
r = t * np.log(y)
return - r.sum() / r.ndim
```

**Backward** (P38)

特に数式はない。


**参考**
https://qiita.com/PlanetMeron/items/63ac58898541cbe81ada
AristaNetworks cEOS-labのインストールと起動(Docker for Windows)

## はじめに

[AristaNetworks社](http://www.arista.com)の製品について業務で少し関わっており、気軽に触りたい環境を作りたいと考えていた。
Arista社にはハイパーバイザー上で利用できるvEOS※という仮想版がリリースされてはいるものの、必要とされるメモリが2G程度で少々自宅のパソコンにいれるには厳しかったが、コンテナ環境で利用できるcEOSがリリースされている(メモリは600M程度で動く)のでそれを試しに入れてみた際のメモである。
本当はLinuxサーバマシンで試そうと思ったのだが、Windows10マシンを新規に購入したのでDocker for Windowsでも動くのかまず試すことにした。

※正確にいうとlab版とそうでないものに分かれている。簡単には以下。

|名称 |説明  |
|---|---|
|vEOS|商用版。購入の必要あり。|
|vEOS-lab|評価用。Arista.comからダウンロード可能。  |
|cEOS|商用版。購入の必要あり。
|cEOS-lab|評価用。Arista.comからダウンロード可能。|


##インストール手順

###1.Arista社のサイトからcEOS-labのイメージダウンロード(ユーザ登録が必要)。

<img src="https://docs.google.com/drawings/d/e/2PACX-1vTe_XiQ4waIOs35wxOKbVVMy4t3p3UkeHD1iKY3s1Tyvu93LgV0jPMDycXiP5Y1v513tIzuO6s5F5rc/pub?w=461&amp;h=278">


今回はcEOS-lab4.21.1Fを利用。

###2.import※

※Docker for Windowsをインストールしていること前提で記載しています。自分はWindows10Proの64bitマシンを使用した。

<img src="https://docs.google.com/drawings/d/e/2PACX-1vTkF5URCjbjWBI7oknR-brri1tiWYa4n-ZV0nBP3VcGtQpQRRvqrRSwc3WQquDiBHqNhr2r-yl9_KQX/pub?w=652&amp;h=225">
docker import cEOS-lab.tar ceos:latest

###3.create

<img src="https://docs.google.com/drawings/d/e/2PACX-1vTlMPnbEJGM4j5l0VzxV6XdUJUiNDoY-RxuSTNrd8jOfpxAoaS-BvT1KXbGS5FxW9J_kx8l5b62rXGs/pub?w=1207&amp;h=200">
docker create --name=ceos --privileged -p 443:443 -e CEOS=1 -e container=docker -e EOS_PLATFORM=ceoslab -e SKIP_ZEROTOUCH_BARRIER_IN_SYSDBINIT=1 -e ETBA=1 -e INTFTYPE=eth -i -t ceos:latest /sbin/init


###4.ネットワークの作成

EOS Centralにも以下記述が記載されているのですが、eth0は使えないようなのでeth1以降を設定することにする。

Note: Connection to docker0 is created by default when no network parameters are specified in `docker create`. Ethernet0 interface cannot be used and is not available inside the Cli shell.

<img src="https://docs.google.com/drawings/d/e/2PACX-1vQ8_0-i-motRmKkMX3y5TdO9qges40INKQUT6zMO510zhDPTmuBJqQ0S3oSUg6pXI1H23c0DlnbNbDp/pub?w=804&amp;h=208">
docker network create net1
docker network create net2
docker network connect net1 ceos
docker network connect net2 ceos

###5.コンテナ起動

<img src="https://docs.google.com/drawings/d/e/2PACX-1vRpOEV9UpjOICKCgqsHh8DT_jWxXUb1--N74wRDlkBO_z8cJfB--baqTzdKQ9JxwZci-g48fG-OKVA2/pub?w=802&amp;h=142">
docker start ceos

###6.EOSのCLI

先ほど作ったコンテナネットワークのnet1とnet2につながっているEthernet1とEthernet2が作成されている。

<img src="https://docs.google.com/drawings/d/e/2PACX-1vSAASwbysXVNYrfc7Ay5dtkaCrxlJpEPfVZUOiLEQd5MFqiP1t9CWh9qhGzoXhNl7t-uVRPPhvx3G0m/pub?w=805&amp;h=594">

##まとめと今後やりたいこと

Docker for Windowsでちゃんと動くのかなぁという好奇心もあり、ひとまずWindowsマシンでcEOSを建ててみました。
今回は単純に1ノードのみ作成しましたが、マルチノードやAPI叩いたりやっていきたいです。
もっと早くにチャレンジしたかったのですが、年明けてからの実施になってしまった・・・。

本記事はすでにcEOSについて記載されている以下の記事も参考にさせて頂きました。

https://qiita.com/arashi1977/items/1f728035670c0a57dffd

https://tekunabe.hatenablog.jp/entry/2018/12/17/arista_cEOS-lab_one
./configure でどんなオプションを指定していたかを思い出せない時

# 背景

Rust実装のEmacsの[remacs](https://github.com/Wilfred/remacs)をビルドしているが、頻繁にビルドしていないので、
./configureで使用しているオプションを忘れてしまう

```history``` コマンドでもちょっと前のコマンドならCtrl+Rで検索出来るが、
日にちが経ってしまってhistoryで追えない状況の場合、毎度、オプションをググるのは効率が悪い。

# 前回の./configureのオプションを調べるには

```bash
head config.log 
```

## remacsでの例

```txt
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.

It was created by GNU Emacs configure 27.0.50, which was
generated by GNU Autoconf 2.69.  Invocation command line was

  $ ./configure --without-makeinfo --with-ns --prefix=/opt/remacs
```

# 関連記事

- [RemacsのCocoa GUI版で文字が表示されない問題の解決の糸口が見つかった](https://abrakatabura.hatenablog.com/entry/2018/12/10/213217)
obnizでRCWL-0516のレーダーの信号をみてみる

# はじめに

[Googleのレーダー技術によるジェスチャー入力方式SoliをFCCが認可、電波妨害問題をクリア](https://jp.techcrunch.com/2019/01/03/2019-01-02-us-fcc-approves-google-soli-project/)という記事をみて以前から関心していたSoliが実用化に近づいたことをワクワクした一方、税関チェックで2週間遅れくらいで届いた超安いマイクロ波レーダーセンサRCWL-0516がちょうど手元にあったのでなんかやってみようかと思った。同じレーダーセンサだし。

で、なんかおもしろいネタはないかしらと検索していたら[RCWL-0516マイクロ波レーダー少し改造 (5)](https://plaza.rakuten.co.jp/v62000/diary/201801200000/)という記事が興味深かった。ちょっと手を加えてレーダーが感知した信号をアナログ出力できるとか。なんかSoliっぽいことができるかも。ということでやってみた。

# やってみた

![IMG_20190104_222402.jpg](https://qiita-image-store.s3.amazonaws.com/0/61995/4bccef6d-3b84-357c-16bc-fefaaa74d2a6.jpeg)

こんな感じで記事の青い配線のほうと同じにオペアンプとピンをつないでobnizの0ピンに接続する。このピンをアナログで読めばOKのはず。コードは以下

```RCWL-0516-wave.html
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <script src="https://obniz.io/js/jquery-3.2.1.min.js"></script>
  <script src="https://unpkg.com/obniz@1.14.1/obniz.js" crossorigin="anonymous"></script>
</head>
<body>

<div id="obniz-debug"></div>
<h1>obniz instant html</h1>
<p id="vol">0</p>
<p id="arr">[]</p>
<div id="chart-area">
  <canvas id="chart"></canvas>  
</div>

<script>
var obniz = new Obniz("OBNIZ_ID_HERE");
obniz.onconnect = async function () {

  var v = 0;
  var arr = [];
  
  obniz.io2.drive('5v');
  obniz.io2.output(true);

  obniz.ad0.start(function(voltage){
    document.getElementById('vol').innerHTML = voltage;
    v = voltage;
  });

  obniz.io4.output(false);
  
  setInterval(function() {
    arr.push(Math.floor(v));
    if(arr.length === 35) {
      arr.shift();
    }
    document.getElementById('arr').innerHTML = arr.join(',');
  }, 10);
  
}

</script>
</body>
</html>
```

`obniz.ad0.start()` でレーダー波が感知した信号の電圧を読んでいる。`io2`がVIN、`io4`がGNDになっている。

電圧の変化がわかりやすいように0.1秒毎に電圧の整数値をサンプリングして配列にスタックして表示してみた。

# 実行する

実行結果はこちら。センサーの上で手を移動させたり指をくるくる動かしたりしたのに応じて信号が変わっているのがわかる。基準電圧はだいたい1.5〜1.9くらいで、近づくと上昇し、離れると下降するようだった。

![rcwl-0516-wave.mov.gif](https://qiita-image-store.s3.amazonaws.com/0/61995/b778d15b-7a39-d37c-e451-f43447994ae2.gif)

実行開始後、20秒くらいは電圧が安定しないので、しばらく待って基準電圧に安定してから試してみるとよい。

# まとめ

思ったよりセンシティブに感知していておもしろいと思った。RCWL-0516は人感センサー用途なのでOUTでHIGH/LOWのデジタル値だけみるような仕様だけどアナログ信号取ったほうが面白いんじゃないだろうか。Soliくらいの解像度は出ないにしろ波形の解析で近づいた、遠ざかった、通り過ぎたくらいは検知できるかもしれない。レーダーセンサーってなんか可能性を感じる。

あとobnizはやっぱ配線しなくて便利だな。教育に特化している感があってPoCの運用などには制限がありすぎて不向きだと思っていたけど、こういうちょっとしたセンサーを試用するという用途には使いやすいと思いました。
Javaで九九を出力してみた

お正月に実家に帰省中に小二の姪っ子が宿題で九九の勉強をしているのを横で聞きながら「Javaで書いてみよう」と思ったので書いてみた。

```java:for文で九九
  for (int col = 1; col <= 9; col++) {
    for (int row = 1; row <= 9; row++) {
      System.out.println(col + " × " + row + " = " + (col * row));
    }
  }
```

これだけだと面白くないので、勉強中のStreamAPIで書いてみた。

```java:StreamAPIで九九
  IntStream.rangeClosed(1, 9)
    .forEach(col -> IntStream.rangeClosed(1, 9)
      .forEach(row -> System.out.println(col + " × " + row + " = " + (col * row)))
    );
```

「単純なfor文をStreamAPIでどう書けばいいか」と「for文のネストとStreamAPIのネスト」が理解できた。
GoでEnumを定義する 〜intやstringよりも厳密に〜

# よくあるやつ
```simpleSeason.go
package enum

type SimpleSeason int

const (
	_ SimpleSeason = iota
	Spring
	Summer
	Autumn
	Winter
)

var simpleSeasonStrings = [4]string{"未定義", "春", "夏", "秋", "冬"}

func (s SimpleSeason) String() string {
	return simpleSeasonStrings[s]
}
```

```main.go
package main

import (
	"fmt"

	"github.com/ikngtty/playground/enum"
)

func main() {
	fmt.Println(enum.Summer) // -> 夏
}
```

# 問題点
```main.go
func printSeason(s enum.SimpleSeason) {
	fmt.Println(s)
}

func main() {
	// enum.Autumnじゃなくても無理やりautumnを作れてしまう
	var autumn enum.SimpleSeason = 3

	// 0〜4以外のありえない値を入れられる
	printSeason(64) // runtime error: index out of range
}
```

```simpleSeason.go
var simpleSeasonStrings = [5]string{"未定義", "春", "夏", "秋", "冬"}

func (s SimpleSeason) String() string {
	// なので、SimpleSeasonを扱うときは必ずありえない値が来る可能性を
	// 考慮しないといけない。
	if s < 0 || s > 4 {
		return "お前そういうことすんのやめろよマジで。"
	}

	return simpleSeasonStrings[s]
}
```

# ぼくの考えたすごいやつ
```season.go
package enum

type Season struct{ value string }

var Spring = Season{"春"}
var Summer = Season{"夏"}
var Autumn = Season{"秋"}
var Winter = Season{"冬"}

// String()をわざわざ定義しなくても {春} とか出るので十分わかりやすい
func (s Season) String() string {
	if s.value == "" {
		return "未定義"
	}
	return s.value
}
```

```main.go
package main

import (
	"fmt"

	"github.com/ikngtty/playground/enum"
)

func main() {
	fmt.Println(enum.Winter) // -> 冬

	// パッケージの外からは、enum.Spring〜enum.Winterを使わない限り、
	// ゼロ値しか作ることができない。
	mySeason := enum.Season{}
	fmt.Println(mySeason) // -> 未定義
}
```

フィールドを小文字にしてアクセス制限するのがポイント。
欠点を見つけた方は教えてください。

# おまけ：列挙値の変数名が被る件
enum毎にいちいちpackage切りたくない時。
構造体を名前空間代わりにできそうです。

```variousEnums.go
package enum

type ProgrammingLang struct{ value string }

var ProgrammingLangs = struct {
	Perl   ProgrammingLang
	Ruby   ProgrammingLang
	Python ProgrammingLang
}{
	Perl:   ProgrammingLang{"Perl"},
	Ruby:   ProgrammingLang{"Ruby"},
	Python: ProgrammingLang{"Python"},
}

type Jewelry struct{ value string }

var Jewelries = struct {
	Perl   Jewelry
	Ruby   Jewelry
	Garnet Jewelry
}{
	Perl:   Jewelry{"Perl"},
	Ruby:   Jewelry{"Ruby"},
	Garnet: Jewelry{"Garnet"},
}
```

```main.go
package main

import (
	"fmt"

	"github.com/ikngtty/playground/enum"
)

func main() {
	fmt.Println(enum.ProgrammingLangs.Ruby) // -> {Ruby}
	fmt.Println(enum.Jewelries.Ruby)        // -> {Ruby}
}
```
Jupyter Notebookの初期ディレクトリを変更できなかったときの対処法

# この記事を書くまでの経緯

[Jupyter Notebookの初期ディレクトリを変更する](https://qiita.com/nigimitama/items/a8129e50afcc462e02d6)
を参考にして、Jupyter Notebookの初期ディレクトリを変更しようとしてもうまくいかなかったので。（多分、Windowsだけの問題？）

# 対処法

Aanaconda Promptで以下を入力します

```sh
jupyter notebook --generate-config
```

`C:\Users\username\.jupyter\jupyter_notebook_config.py`が生成されているはずなので、
それを開き、`c.NotebookApp.notebook_dir`を検索し、コメントを外します

```py
## The directory to use for notebooks and kernels.
c.NotebookApp.notebook_dir = 'path'
```

上のように設定したいパス名を指定します。
本来なら、うまくいくはずです。
細かいことは「[Jupyter Notebookの初期ディレクトリを変更する](https://qiita.com/nigimitama/items/a8129e50afcc462e02d6)」を参照のこと。

# もしうまくいかなかったら

![image.png](https://qiita-image-store.s3.amazonaws.com/0/196882/3495a602-bf4d-be75-3b8b-c04b14bf6d84.png)
ご覧の通り、3行目のディレクトリのパスが変更したはずなのに`C:\Users\skytomo`のままになっています。
こういうときは、起動ているアプリのショートカットのプロパティを開きます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/196882/17dcf440-7192-25c7-ff4d-a713d8ba3aa9.png)

すると、`%USERPROFILE%`とか`%HOME%`がリンク先の末尾に追加されているはずです。
これを消して、再起動すると…
![image.png](https://qiita-image-store.s3.amazonaws.com/0/196882/bd0c5af5-7249-7881-cf6f-a4352a4d767d.png)
変更されました。やったね。

# 参考サイト

[Jupyter Notebookの初期ディレクトリを変更する](https://qiita.com/nigimitama/items/a8129e50afcc462e02d6)
[JupyterNotebookの初期ディレクトリが指定できなくなった](https://teratail.com/questions/70182)
[Jupyter Notebook does not launch. (Anaconda 4.3.0 in Windows) #1480](https://github.com/ContinuumIO/anaconda-issues/issues/1480)
【SAP Fiori】Design Guidelinesの主要なコンセプトについて

##Fiori Design Guielinesとは
SAP Fioriは、デザイン思想にかなりこだわりがあるようです。
FioriのアプリとはFioriのDesign Guielineを踏襲したアプリのことであり、そうでないアプリはただのFiori-likeなアプリだ、とOpen SAPのコースで言っていました。
なので、Fiori Appの開発をするにあたってDesign Guielineを知っておくことは不可欠です。
今回は[Fiori Design Guidelines](https://experience.sap.com/fiori-design-web/)から基礎となる部分を1ページにまとめます。
※私自身はFioriの開発にかかわったことはなく、上記ページの情報およびOpen SAPのコースの内容にもとづいた記載となります。

##5つの原則
SAP Fioriのデザイン哲学は以下の5つの原則にもとづいています。

**1. Role-based（ロールベース）**
その人の役割に応じて必要な機能を提供すること
**2. Delightful（使って楽しい）**
わかりやすい、ストレスがない、使って楽しいこと
**3. Coherent（一貫性）**
すべてのアプリは同じ原則に従って作られること
**4. Simple（シンプル）**
トレーニングを受けなくても使えるぐらい簡単であること
**5. Adaptive（どんな環境にも適応できる）**
どんな場所、デバイスでも使えること

##開発サイクル
SAP Fioriの開発サイクルでは、開発の前工程に重点が置かれています。
前工程はDiscoverとDesignという2つのフェーズに分けられます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/276021/7d064643-95ff-7c27-94e1-1409ce3a4755.png)
[Design-Led Development Process](https://experience.sap.com/fiori-design-web/design-led-development-process-external/)より引用


###Discoverフェーズ
ユーザを理解するフェーズです。ユーザはどのような作業をしていて、どんな要求があるのかに着目します。
このフェーズでは実際に現場を訪れてユーザにインタビューしたり、異なるステークホルダーを招いたデザインシンキングのワークショップを開催したりします。
「ペルソナ」という概念もここで登場します。ペルソナとは、実際のデータにもとづく架空の人物のことです。その人がどんなバックグラウンドを持ち、どんな作業をどのような状況で行うのかを具体的に想定します。
ペルソナを中心にに議論すると、メンバーの間で要求に対する共通の理解が深まります。
###Designフェーズ
要求をもとに最初のプロトタイプを作ります。
出来上がったものをユーザに評価してもらいます。
Designフェーズで活用できるツールとして[Build](https://www.build.me/)があります。

###Developフェーズ
開発、テストを行います。
このフェーズの成果物と、前工程の結果の整合性が取れていることが重要です。
（ずれがある場合は、前工程に戻って整合をとることが望ましい）
##Mobile First
Mobile、すなわちスマートフォン用の設計を最初にやりましょうという考え方です。
これには3つのメリットがあります。

**1. 必要な機能にフォーカスできる**
スマートフォンは画面が小さく、できることが制限されるため、本当に必要な機能にフォーカスできる。
作ってから機能を削るより、小さく作ってあとから拡張したほうがよいという考え方。
**2. スマホ固有の機能を最初から考えられる**
スマートフォン固有の機能（センサー、カメラ、音声認識等）の利用を最初から考えられる。
**3. ユーザの置かれる状況を想像しやすい**
スマートフォンの場合、ネットワークに接続できないこともありうる。
そうしたケースを想定すれば、たとえばオフラインでも作業を続行できるような作りにしておくことも可能になる。

##マルチデバイス対応のアプローチ
5つの原則の5番目の"Adaptive"にも関係しますが、マルチデバイス対応のアプローチが2種類あります。
###Responsive Design
Responsive Designでは、異なるデバイスでも同じ作業を行えるようにします。
操作性を高めるために、スマートフォンではマージンを大きくに取ってタッチしやすくするなどの調整を行う必要があります。
このために、FioriのUIコントロール（部品）はデバイスの種類や提供される機能に合わせて、自動的にサイズなどを調整する仕組みがあります。

###Adaptive Design
Adaptive Designでは、デバイスの特性に応じて異なる機能を提供します。
たとえば、デスクトップでは大量のデータを見られる一方、スマートフォンでは入力したデータのみ見られるようにするなどです。
こちらのアプローチでは、開発者がデバイスごとのユースケースをもとに機能を設計する必要があります。

2つのアプローチの対比として、わかりやすい例がDesign Guidelinesに載っています。
https://experience.sap.com/fiori-design-web/responsiveness-adaptiveness/
Laravelでajax(POST)を使うときに気をつけること

#0.前提条件
環境：cloud9、laravel 5.3、PHP7.0
resorces/view/~.blade.php　からajaxでpostするときにこんなエラーメッセージがでた。

```
POST https://laravel-knhj-test/test 419 (unknown)
```

どうやらLaravelではデフォルトでPOST通信には全てCSRFトークンをつけてやる必要があり、ajaxでの通信でもつける必要があるらしい。
#1.XMLHttpRequestにCSRFトークンを入れる

JavascriptでCSRFトークンをリクエストヘッダーに入れるためには以下の記載が必要になる。

```html:index.blade.php
<meta name="csrf-token" content="{{ csrf_token() }}">
(中略)
<script>
　　　　var formdata = new FormData();
      formdata.append('name', 'knhj');

     var xhttpreq = new XMLHttpRequest();
     xhttpreq.onreadystatechange = function () {
        if(xhttpreq.readyState == 4 && xhttpreq.status == 200) { alert(xhttpreq.responseText);}
        if(xhttpreq.readyState == 4 && xhttpreq.status != 0) {alert("アップロード完了");}
     };
     var token = document.getElementsByName('csrf-token').item(0).content; 
     xhttpreq.open("POST", "ポスト先", true);
     xhttpreq.setRequestHeader('X-CSRF-Token', token); 
     xhttpreq.send(formdata);
</script>
```
ポイントは２点。
①metaタグでCSRFトークンを作成して、getElementsByNameでトークンを取得する。
②openした後（xhttpreq.openをxhttpreq.setRequestHeaderより後に書くとエラーが出る）、setRequestHeaderメソッドを使ってCSRFトークンをリクエストヘッダーに入れる。


#2.参考URL
http://kayakuguri.github.io/blog/2017/12/06/laravel-ajax-csrf/
https://stackoverflow.com/questions/28524485/xmlhttprequest-throwing-invalidsateerror-saying-object-state-must-be-opened
https://readouble.com/laravel/5.5/ja/csrf.html#csrf-x-csrf-token
https://re-engines.com/2018/05/31/javascript-csrf/
https://stackoverflow.com/questions/46466167/laravel-5-5-ajax-call-419-unknown-status
http://repenguin.hateblo.jp/entry/2016/09/26/124056
AndroidStudio&cmakeでcocos2d-xをビルドする

#実行環境
Windows 10 Home 64bit
Android Studio 3.2.1
cocos2d-x v3.17.1

#はじめに
先日、cocos2d-xのv3.17.1がリリースされました。
現在作ってるゲームのcocos2d-xのバージョンをこの3.17.1にしようと、プロジェクトを作り直しAndroid Studioでビルドしたところ、エラーが出ました。

[リリースノート](https://discuss.cocos2d-x.org/t/cocos2d-x-v3-17-1-released/45046)を見ると
>Android use CMake as default PROP_BUILD_TYPE value

とのことで、Androidのビルドに使われるツールをデフォルトでCMakeに設定されるようになったようです。

[公式ドキュメント](https://docs.cocos2d-x.org/cocos2d-x/en/installation/CMake-Guide.html?h=cmake)に書かれていますが、プロジェクトにあるproj.android/app/gradle.propertiesというファイルを見ると以下のように書かれています。

```properties:gradle.properties
# android native code build type
# none, native code will never be compiled.
# cmake, native code will be compiled by CMakeLists.txt
# ndk-build, native code will be compiled by Android.mk
PROP_BUILD_TYPE=cmake
```

ここの`PROP_BUILD_TYPE`の値を`ndk-build`にすれば今まで通りのビルドに戻せそうです。

しかし、せっかくですのでcmakeでビルドする方法を試してみることにします。

#方法
gradle.propertiesのコメントから察するに、Android.mkに書いていた内容をCMakeLists.txtに書けばよさそうです。

Android.mkではコンパイルするソースコードを列挙していましたので、CMakeLists.txtでもそのような記述ができるか探してみた結果、以下のような記述がありました。（CMakeLists.txtはプロジェクトフォルダのルートにあります）（50行付近に書かれています）

```cmake:CMakeLists.txt
# add cross-platforms source files and header files 
list(APPEND GAME_SOURCE
     Classes/AppDelegate.cpp
     Classes/HelloWorldScene.cpp
     )
list(APPEND GAME_HEADER
     Classes/AppDelegate.h
     Classes/HelloWorldScene.h
     )
```

この、**GAME_SOURCE**と**GAME_HEADER**という変数にソースファイルとヘッダーファイルを追加していけばよさそうです。

本来ならば全てのファイルを手動で追加していくのがいいのでしょうけど、それは骨が折れるのでCMakeLists.txtでワイルドカードのようなものが使えないかと調べていたら次のような書き方ができました。

```cmake:CMakeLists.txt
# add cross-platforms source files and header files 
# list(APPEND GAME_SOURCE
#      Classes/AppDelegate.cpp
#      Classes/HelloWorldScene.cpp
#      )
file(GLOB_RECURSE GAME_SOURCE RELATIVE ${CMAKE_SOURCE_DIR} CONFIGURE_DEPENDS "Classes/*.cpp")

# list(APPEND GAME_HEADER
#      Classes/AppDelegate.h
#      Classes/HelloWorldScene.h
#      )
file(GLOB_RECURSE GAME_HEADER RELATIVE ${CMAKE_SOURCE_DIR} CONFIGURE_DEPENDS "Classes/*.h")
```

`GLOB`は指定されたパターンにマッチするファイルを探索する機能で、`GLOB_RECURSE`でサブディレクトリも含めて探索します。
`RELATIVE`で`${CMAKE_SOURCE_DIR}`からの相対パスとして取得します。
`CONFIGURE_DEPENDS`はファイルが変更されたかどうかを取得してビルドシステムを再生成するもののようです。（新しい機能で情報が少なくよくわかっていません…）
[CMakeのドキュメント](https://cmake.org/cmake/help/latest/command/file.html#filesystem)には、`CONFIGURE_DEPENDS`フラグは正しく動作しない場合があると書かれていましたが、Android Studioでは確認できる限りでは有効となっているようです。

ともあれ、上記のようにCMakeLists.txtを変更したところ無事に以前と同じようにAndroid Studioでビルドができました。

#おわりに
推測や、よく知らないCMakeのことでの解決でしたので、不確かな部分もあるかもしれません。
毎度のことで申し訳ありませんが、何か間違ってる・もっといい方法がある等あれば教えてください！
ねこさんカレンダ作ったよ。毎日ねこ、ネコ、ぬこ(=^・^=)

どうき
---

2019年になりました。毎年クリーニング店から**わんにゃんカレンダ**をもらっていたのですが、2019年分はもらえなかったので、自分で**ねこさんカレンダ**を作ってみました。
**ねこさんカレンダ**と言っても、日付とランダム画像を表示するだけですが。

こんなかんじ
---

グレースケールだといい味でますよ。ねこさん、かわゆす。(=^・^=)

|<img src="https://qiita-image-store.s3.amazonaws.com/0/63318/8b58ce42-1eb5-bc78-9e27-414c472accf7.png">|<img src="https://qiita-image-store.s3.amazonaws.com/0/63318/92ed1218-2fe7-a09c-79b7-168f13c942da.png">|<img src="https://qiita-image-store.s3.amazonaws.com/0/63318/fa304b4a-d9cc-990c-e8a7-e17d15359f76.png">|
|:--:|:--:|:--:|
|<img src="https://qiita-image-store.s3.amazonaws.com/0/63318/132f77f2-ccee-5c15-4927-962bd6eaadc2.png">|<img src="https://qiita-image-store.s3.amazonaws.com/0/63318/be46beee-3606-dbbf-fae3-62578f3b6758.png">|<img src="https://qiita-image-store.s3.amazonaws.com/0/63318/a3fac712-cc45-1ddd-911f-5f15c69a054d.png">|

せつめい
---

プログラムは Raspberry Pi、Raspbian GNU/Linux 9.4 (stretch) で動作確認が取れています。
cat_calendar.rb を Supervisor などでデーモン化してください。
KindleやKobo等のブラウザで **http://IPアドレス:1313/** を指定すると、一定時間ごとランダムでねこさんが表示されます。
ブラウザのバージョンが古いときちんと表示されない場合があります。スクリーンセーバは無効にしてください。

```ruby:cat_calendar.rb
require 'sinatra'

set :port, 1313
set :bind, '0.0.0.0'

keyword    = 'cat'
httpurl    = 'https://loremflickr.com/640/480/' + keyword + '?'
refreshsec = 600

get '/' do
 
  timenow   = Time.new
  titledate = timenow.strftime("%Y年%m月%d日") + '(' + %w(日 月 火 水 木 金 土)[timenow.wday] + ')'
  unixtime  = timenow.to_i

<<STRING
<html>
  <head>
    <meta http-equiv="Refresh" content="#{refreshsec}">
    <style>
      body {font-family: arial, sans-serif;}
      p {padding-top: 0; paddding-bottom: 0; margin-top: 0; margin-bottom: 0;}
    </style>
  </head>
  <body>
    <p style="font-size: 260%">#{titledate}</p>
    <img src="#{httpurl}random=#{unixtime}">
  </body>
</html>
STRING

end
```

参考：

- [Remarks from DIY projects - Share Messages via Kindle on Fridge](https://petervojtek.github.io/diy/2015/07/28/share-messages-with-kindle-on-fridge.html) ... プログラムを参考にしました。
- [LoremFlickr - Free placeholder images](https://loremflickr.com/) ... 無料で画像をランダム表示できます。
- [Qiita - @wintyo - Kindle Paperwhiteでスリープをオフにする](https://qiita.com/wintyo/items/784f7ddffbcc2d0472ea)
- [Qiita - @somainit - 第8世代Kindle(無印)をjailbreakしたけどscreensaverを無効にできないので何とかしてみた](https://qiita.com/somainit/items/efeae63cb894d9f14f05)

さらに
---
ねこさん以外にも、変数 keyword に関連した画像が一定時間ごとに表示されます。
どんな画像が表示されるか楽しみですね。

参考：

- [ねこちゃんホンポ - 猫の癒し効果がすごい！何故猫といると癒されるのか、科学的に解明された事](https://nekochan.jp/cat/article/3257)
Google Apps Script×FixerAPIで外国為替レートを取得する

海外旅行での支払い記録ツールを作ろうと思い、GASを使い[Fixer.io](https://fixer.io/)から外国為替レートを取得してみました。

## Fixer.ioとは
世界中の通貨の交換レートを取得・提供するサービスです。

データは毎分15以上のデータソースから取得され、ビットコイン・金・銀を含む170の通貨の交換レートが配信されています。

[FAQ - Fixer](https://fixer.io/faq)

無料アカウントでは対EURレートのみ利用できます。
今回は大まかな値でいいため、(USD vs EUR)/(JPY vs EUR)のように計算して擬似的に対JPYのレートを取得してみました。

## 必要なもの
- Fixerアカウント
- Googleアカウント

## サンプルコード
通貨レートの取得（対ユーロ）

```javascript
// 指定した通貨の対EURレートをJSONで取得する
function getJSON(currency) {
  const endpoint = 'http://data.fixer.io/api/latest',
        api_key = API_KEY,
        symbols = currency+',JPY'; //symbolsを指定しない場合、全通貨のデータを取得
  
  const url = endpoint+'?access_key='+api_key+'&symbols='+symbols;
  
  const json = UrlFetchApp.fetch(url,{
    'Content-Type': 'application/json; charset=UTF-8',
    'method': 'get'
  });
  return json;
}
```

対円レートへの換算

```javascript
// fixer APIから取得した対EURレートから対JPYレートを計算する
function getJpyRate(currency) {
  const json = getJSON(currency);
  const rates = JSON.parse(json).rates;
  if (rates[currency] > 0) {
    const rate_JPY = rates.JPY / rates[currency];
    return rate_JPY;
  }
  return
}
```

## まとめ
通貨レートはカード会社や証券会社なども配信していますが

- マイナー通貨まで網羅している
- 口座開設など必要なく簡単に実装できる

といった点がFixerのメリットに思います。
反面、無料プランでは

- 呼び出し回数制限が月間1000回
- 更新が1時間毎
- 対EURレートしか取得できない

といった制限があり、更新頻度や正確性が必要な用途では使えなさそうです（FXとか）。
マイナー通貨のレートを大まかに知りたい場合に便利。
CentOS7 に最新版の Git をインストールする方法

## 概要
CentOS7 のサーバに Git を導入する時の備忘録。
`yum install git` で入る Git は少し古いので、新しいバージョンを入れる方法を記載する。

## 手順

### 依存関係のあるライブラリをインストール

依存関係があるライブラリ（curl、zlib、openssl、expat、libiconv あたり）を導入する。
真っさらなサーバだと、コンパイルするのに必要な gcc がそもそも入ってないパターンもあるのでこれも入れる。

```bash
sudo yum -y install gcc curl-devel expat-devel gettext-devel openssl-devel zlib-devel perl-ExtUtils-MakeMaker autoconf
```

### ダウンロード対象を確認

https://mirrors.edge.kernel.org/pub/software/scm/git/ で Git の落としたいバージョンを確認し、アドレスのリンクをコピーする。
（今回は `git-2.9.5.tar.gz` のリンクをコピーした。）
※ もしかしたら、最新の Git がここにない可能性もあるので、[Gitの公式サイト](https://git-scm.com/) からリンク先情報等を探してみてくださいませ。。。

<img width="665" alt="スクリーンショット 2019-01-04 21.23.06.png" src="https://qiita-image-store.s3.amazonaws.com/0/199602/6437f33a-8bd5-da4a-84d7-9f052583521c.png">

### Git パッケージをダウンロード

```bash
# インストールに適切な場所に移動
cd /usr/local/src/

# サイトから Git の圧縮ファイルをダウンロード
sudo wget https://mirrors.edge.kernel.org/pub/software/scm/git/git-2.9.5.tar.gz

# ファイルを解凍
sudo tar xzvf git-2.9.5.tar.gz
```

※ もし wget が入ってなかったら `sudo yum install wget` でインストールできる

ダウンロードが完了したら、tar.gz ファイルは不要なので消してもいい

```bash:/usr/local/src
# 圧縮ファイルを削除
sudo rm -rf git-2.9.5.tar.gz
```

### Git をインストール

```bash:/usr/local/src
# 解凍した Git ディレクトリに移動
cd git-2.9.5/

# make コマンドでインストール
sudo make prefix=/usr/local all
sudo make prefix=/usr/local install
```

### 確認

インストールされたか確認

```bash
# バージョン確認コマンド
$ git --version
git version 2.9.5
```
以上で完了。
大きなDataFrameで次に条件を満たす行を抽出する

本来のDataFrameの使い方では行の順番に依存しない方がよいと思いますが、pandasで時系列に関連したデータをあつかっていると、条件を満たす次の行を選び出したいことがたまにあります。

pandas公式ではそれに該当するようなmethodがなく、大きなDataFrameではすぐ近くに条件を満たす行があることは分かっていてもかなり時間がかかってしまいます。

#先に結論
windowのgeneratorを自作すると速い。
手軽に試したいなら```df[(df条件式)&(df.index条件式)]```が良い。

なお、numbaやCythonなどを使った高速化はおこなっていません。

#実験環境
windows10, i7-4600U, python3.6.7, pandas 0.23.4, jupyter-notebook

#問題設定

```python:DataFrameの作成
import pandas as pd
import numpy as np

np.random.seed(0)
df = pd.DataFrame(np.random.rand(100000000), columns=['A']) 

df.iat[10000,0]
>> 0.7482679812896987
```

この1億行のDataFrameから、10000行目以降で0.9999を上回る行を見つけたいとします。実際には、15000行目くらいにあります。
なお、各試行前にdel dfして作りなおしています。

# 方法1：windowのgeneratorを自作する
```python:方法1
%%time
def window_generator(_series, window):
    l=_series.shape[0]
    i=0
    while i *  window < l:
        yield _series.iloc[slice(i*window, min((i+1)*window, l))]
        i+=1

gen = window_generator(df.iloc[10000:,0], 10000)

for _se in gen:
    temp = _se[_se > 0.9999]
    if not temp.empty:
        print(temp.iat[0])
        break
    else:
        pass
>> 0.9999620173413053
>> Wall time: 13.9 ms
```

ということで本命。そこそこ速いです。seriesをwindow幅ごとに切って、1個ずつyieldしてます。見つかれば吉、見つからなければもう1個yield。これはwindow幅を10000と見つかる幅に設定しているのがポイントで、この幅の設定を誤るとかえって遅くなります。for文だけで書いてあげても良いですが、他でも使い回せるので。

ただ、generatorをつくるオーバーヘッドがあるので、100万行くらいまでだと下記のワンライナーに対する優位性が失われます。

# 方法2～6
```python:方法2,3
%%time
df[(df['A']>0.9999)&(df.index>10000)].iat[0,0]
>> Wall time: 685 ms
>> 0.9999620173413053

%%time
df.loc[(df['A']>0.9999)&(df.index>10000), 'A'].iat[0]
>> Wall time: 654 ms
>> 0.9999620173413053
```
どちらも大差ないですね。ワンライナーで書けますし、100万～1000万行くらいまでならこれで良いような気がします。
　　

```python:方法4,5
%%time
df.loc[10000:, 'A'].pipe(lambda x:x[x>0.9999]).iat[0]
>> Wall time: 936 ms
>> 0.9999620173413053

%%time
df.loc[10000:, :].query('A > 0.9999').iat[0,0]
>> Wall time: 1.78 s
>> 0.9999620173413053
```
10000行以降、という条件を先に抽出してみますが、かえって遅くなりました。Seriesにはqueryメソッドが使えないのでpipeにしています。DataFrameのままquery文で処理するよりは、先にseriesにしてしまったほうがまだマシっぽい。
　　

```python:方法6
%%time
for i, v in df.iloc[10000:,0].iteritems():
    if v > 0.9999:
        print(i,v)
        break
>> 14988 0.9999620173413053
>> Wall time: 6.34 s
```
お試しに。10000行目から1行ずつ回してみるという方法。5000行目くらいで見つかるがかなり遅い。ただこれ、何行目で見つかるときもあまり変わらなかったので、おそらく最初のiteritemsを準備するときにかなりの時間がかかっていそうです。
　　




#もう一度結論
windowのgeneratorを自作すると速い。
手軽に試したいなら```df[(df条件式)&(df.index条件式)]```が良い。
tmuxのペインのステータスラインに「最後に実行したコマンド」を表示する

# はじめに

最近以下の記事を見てtmuxのペイン毎にステータスラインを表示できることを知りました。

- [tmuxのペインのステータスラインにgitのブランチとかディレクトリとか表示する(プロンプトはもう古い)](https://qiita.com/arks22/items/db8eb6a14223ce29219a)
- [SSH接続先のホスト名をtmuxのペインに表示する(大事件)](https://qiita.com/arks22/items/7bf7da1433ef9c57b457)

リンク先の記事の通り、ssh先ホスト名やgitブランチなどを表示するのもいい感じなのですが
個人的に表示したかったのは「最後に実行したコマンド」です。
特に`make`など長時間かかってログが流れて行ってしまうようなコマンドで、後から「どのオプションを付けたっけ？」と思うことがたまにあります。
tmuxのhistoryにプロンプトが残っていればいいのですが、そうでなかった場合`ps`かシェルの履歴で探すしかないですし、同じコマンドをオプション変えながら複数流していたらお手上げです。
というわけで「最後に実行したコマンド」を表示できるようにしてみました。

# 方法

最低限の設定としては以下を`.tmux.conf`に追加すればOKです。

```.tmux.conf
set -g pane-border-format "#(ps --no-headers -t #{pane_tty} -o args kstart_time | grep -v '^-.*' | head -n 1)"
```

実際には"[tmuxのペインのステータスラインにgitのブランチとかディレクトリとか表示する(プロンプトはもう古い)](https://qiita.com/arks22/items/db8eb6a14223ce29219a)"に書かれている通り、スクリプトを呼ぶ形にした方がいろいろ便利です。

あと、ステータスラインの更新間隔をある程度短くした方がいいかもしれません。

```.tmux.conf
set -g status-interval 1
```

ステータスラインの更新は`tmux refresh-client -S`コマンドを実行することでもできるので、
シェルのhookを使ってこのコマンドを呼ぶのが一般的です。
しかし、長時間のコマンドを実行してしまった場合、シェルに制御が返ってこないので呼べるhookがありません。
そのためtmuxが自力で更新するしかなく、`status-interval`が長いとなかなか反映されないことになります。

# 解説

一応コマンドの解説です。
まず`#{pane_tty}`がそのペインのttyになるので

```
ps --no-headers -t #{pane_tty} -o args kstart_time
```

でそのペインのプロセス一覧が得られます。
`-o args`で引数付きのコマンド出力に、`kstart_time`で起動順にソートされます。
ソートなしだと、例えば`make`が内部で`gcc`を呼ぶような場合にどれが最初のコマンドか分かりません。

あとはソートされた先頭コマンドを表示すればいいのですが、
プロセス一覧にはログインシェルも含まれるので先頭は必ずログインシェルになってしまいます。
そのため以下でログインシェルを除いています。

```
grep -v '^-.*' | head -n 1
```

`ps`によるプロセス一覧のうちログインシェルは行頭に`-`がつくので`grep`で除外できます。
あるいは以下のように単に1行目を除外でもいいかもしれません。

```
head -n 2 | tail -n 1
```

# 実際の設定

最後に、私が使っている設定全体へのリンクを張っておきます。

- [.tmux.conf](https://github.com/dalance/dotfiles/blob/master/.tmux.conf)
- [tmux-pane-border(.tmux.conf内で呼んでいるスクリプト)](https://github.com/dalance/dotfiles/blob/master/bin/tmux-pane-border)

`tmux-pane-border`スクリプトは"[SSH接続先のホスト名をtmuxのペインに表示する(大事件)](https://qiita.com/arks22/items/7bf7da1433ef9c57b457)"のものを改変させていただきました。
ありがとうございます。
"gem install bundler"で"bundler requires Ruby version"というエラーが出てきたときの対応方法

`gem install bundler`を実行すると`bundler requires Ruby version >= x.x.x`というエラーが出てきたときの対応方法です。
結論をいうと、**利用しているRubyのバージョンをアップデートする**か、**利用するbundlerのバージョンを下げるか**で解決できます。


例えば、2019年1月現在、Ruby 2.2.2を利用してbundlerをインストールすると以下のようなエラーがでます。

```
$ gem install bundler

Fetching: bundler-2.0.1.gem (100%)
ERROR:  Error installing bundler:
	bundler requires Ruby version >= 2.3.0.
```

引数になにも指定しないとbundler 2.0.1をインストールしようとしていることがわかります。そして、2.0.1の場合、Rubyは2.3.0以上でないといけません。

bundlerのバージョンは`-v`オプションで指定することができます。
例えば、1.16.0を指定すると以下のように無事にbundlerをインストールできます。

```
$ gem install bundler -v 1.16.0

Successfully installed bundler-1.16.0
Parsing documentation for bundler-1.16.0
Done installing documentation for bundler after 4 seconds
1 gem installed
```

業務アプリの環境をローカルに作るときなど、Rubyのバージョンをあげることが難しい場合は上記の方法で解決してみてください。
Factory Method(ファクトリーメソッド)パターン

![image.png](https://qiita-image-store.s3.amazonaws.com/0/257568/db0965ff-f01e-08f8-45fd-23d9d71433aa.png)

1つずつデザインパターンをまとめ

## 総論
パターンそのものと使い所を理解する

## Factory Method(ファクトリーメソッド)パターン
セットとなる(製品)オブジェクトを容易に生成してくれるパターン。
ある作成者オブジェクトを選択することが、製品オブジェクトの「クラスの選択」をも決定づけるパターン。
 
## Factory Methodのテンプレート

```SuperProduct.rb

class SuperProduct
  def initialize(product)
    @product = product
  end

  def template_method()
    abstract_method()
  end

  def abstract_method()
    raise 'Abstract method'
  end
end
```
```SubProduct1.rb
require './SuperProduct'

class SubProduct1 < SuperProduct
  def initialize(product1)
    super
  end

  def abstract_method()
    puts "#{@product}の特徴1"
  end
end
```
```SubProduct2.rb
require './SuperProduct'

class SubProduct2 < SuperProduct
  def initialize(product2)
    super
  end

  def abstract_method()
    puts "#{@product}の特徴2"
  end
end
```

```SuperCreator.rb
require './SubProduct1'
require './SubProduct2'

class SuperCreator

  def initialize(args)
    @product1 = new_product(:type1, args[:name1])
    @product2 = new_product(:type2, args[:name2])
  end

  def factory_method()
    @product1.template_method()
    @product2.template_method()
  end

  def new_product(type name)
    return SubProduct1.new(name) if type == :type1
    return SubProduct2.new(name) if type == :type2
    raise "Unknown product type #{type}"
  end
end
```

```Main.rb
require './SuperCreator'

class Main
  creator = SuperCreator.new(:name1 => '製品1', :name2 => '製品2')
  creator.factory_method()
end
```
### 使い所
〇〇と△△に適した□□を作り、××したい
例) アヒルとスイレンに適した池を作り、1日の生体観察をしたい

- 製品が「アヒル」、「スイレン」(サブクラス)
- 作成者が「池」(スーパークラス)
- 池クラスの生成時に、作るべきオブジェクトの型を知らせるパラメータを渡す。(new_product()が呼び出され、製品クラスの型が決定。)
- 「1日をシュミレーションする」時に行う基本ステップを抽象メソッド(abstract_method())として定義し、テンプレートメソッドで呼び出すようにする
  - 動物が鳴く
  - 動物が食事をする..
  - 植物が成長をするetc..
- 「(池の)1日をシュミレーションする」メソッド(ファクトリーメソッド)を実行
- アヒルやスイレンが、それぞれの1日の活動を行う

### 特徴
- ファクトリーメソッド ＝ テンプレートメソッド 
  - 新しいオブジェクトの作成の問題に適用しただけ
- オーソドックスなFactory methodの問題は、パターンが作るオブジェクトの型ごとに別々のサブクラスを必要とすること(追加したい製品オブジェクトが増えていくと、作成者オブジェクトのサブクラスも組み合わせだけ倍々ゲームのごとく作ることになる)
  - なので上記の例はその欠点を補った**パラメータ化されたファクトリーメソッド**

### 考え方 
- このパターンの「作成者」、「製品」とはオブジェクトの関係性を表す表現
  - 「作成者」オブジェクトが、「製品」オブジェクトを作るという動きのため(「作成者」の生成と同時に「製品」が決まる)
- オーソドックスなFactory methodはサブクラスの「作成者」オブジェクトを生成する
  - 製品化させたいオブジェクトが1、2個なら問題ないが、それ以上なら実用的とはいえなそう

## 手順
1. 必要な製品オブジェクトを検討しクラスを作成
2. 共通な性質をもつ製品オブジェクトがあるか検討しスーパークラスを作成してテンプレートメソッドを実装
3. 製品オブジェクトを呼び出す作成者クラスを作成
4. 製品オブジェクトを呼び出す組み合わせが2つ以上ある場合はファクトリーメソッドを実装し、組み合わせの1つを実現するサブクラスの作成者クラスを作成
5. 製品オブジェクトを呼び出す組み合わせが2 ~ 4程ある場合は製品オブジェクトを作成者のスーパクラスにパラメータで渡す方法にし、サブクラスを削除
6. 作成者クラスを生成し、ファクトリーメソッドを実行

### ポイント
- 製品オブジェクトを呼び出す組み合わせが最初から5以上くらい or 今後も増え得るのであればAbstract Factoryを使った方が適切
- アジャイル的に進めるのであればFactory Method -> Abstract Factoryと段階的に利用するのが良さそう
- 全てのオブジェクトをファクトリから生成する必要があるわけではない(はず)

## 書籍情報
Russ Olsen, Rubyによるデザインパターン
https://amzn.to/2PFKt6m

## 雑感
この本の随所にYAGNI原則を出してくる理由が分かる。デザインパターンを知るとすげーと思うのと同時につい使いたくなる。なにに効果が高いのかをしっかり考えて使う
あなたの命の値段しっていますか？

終末期医療は止めたらどうかと落合陽一さんが発言されていたりして話題になっていますよね．もちろん賛否両論があるでしょうね．
その前に実際どれくらい金がかかっているのか，この本で知ることができました．

「医者の本音」中山裕次郎　２３７ページに書いてあります．
中山さん，なかなか勇気がある方です．ありがとうございます．
値段を知りたい方は買って読んで下さいね．
厚生労働省諮問会議で行われた議論の引用もされいますので，根拠のある数字のようです．

もちろん他にも，読んで良かったなと思えることがたくさん書いてあります．
印象に残った部分をいくつか
## がんになった時，医者に聞いておいたほうが良い３つのこと
 * 何例くらいこの手術をしたことがあるか？
 * 治療計画はどのようなものか？
 * 自分や家族にできることはなにか？
![honne1000.jpg](https://qiita-image-store.s3.amazonaws.com/0/232519/7fe9db3e-6a8a-e07d-fe1a-683b015d43f9.jpeg)
特に１番目は聞きづらそうですが，これにちゃんと答えてくれないような医者は止めておいたほうが良いそうです．

## 医者は死をコントロールできない
どうして，いつガンになるのか，ハッキリしたことは結局わかっていない．
１０００例以上も大腸ガンと戦ってきた現場のお医者さんの言葉は重いです．

わたしたちはあと何年生きられるのか？
分かっているのは統計的なデータから得られる余命だけであって，個々人のはなしになれば，明日ガンが発病する可能性もあるわけです．

浴びるほど死を目撃してきた中山さんの結論は
## 突然不条理にやってくる死の瞬間までを，だいじに生きる
だそうです．言われてみれば当たり前ですが，日常的に死を見つめているお医者さんにそう言われると，インパクトがあります．

他にも医者と製薬会社の関係とか，看護師と結婚する医者がなぜ多いかなど，興味深いことを知ることができました．

ここまで本音を書くのは，なかなか勇気が必要だったと思われます．
８２０円は安いなと感じましたね．
Advanced Multi-Scene 完全に理解した

![6d2d803f-6d47-47d2-93a7-0338caea94c9.jpg](https://qiita-image-store.s3.amazonaws.com/0/6047/2eda2867-27e2-bfd5-de0b-c06651d53f28.jpeg)

Unityのマルチシーン作業の効率を上げるために購入したものの、日本語の新しめの記事が全然見当たらなくて、放置してた。

しかしなるほど、当たって砕けろ精神で、試してみたらとても簡単で神アセットでした。

> Unity2018.2でも問題なく動き、Warningもゼロ。メンテナンスもよくされてる印象。

## 導入手順 & 挙動観察

- AssetStoreからImport（Doumentation.txt以外不要なAssetないので、気にせず全ImportでOK）
- 以降、Sceneを開くと、AmsMultiSceneSetup オブジェクトが自動生成されるようになる。
- その状態で、Editor上で他のSceneを読ませて、普通にMultiSceneEditingする。
- すると、読んだシーンが上記オブジェクトに自動で登録される。
- 以降、シーンを開き直すたびに、登録されたシーンが自動で仮ロードされるように（ぉぉぉ！！）。
- 再生時にシーンを自動でロードするかしないか、同期か非同期かは、登録されたコンポーネント内で設定が可能。
- 自動ロードの場合、スクリプトからは何もしなくても、再生時のシーンロード時に一緒にロードされる（ぉぉぉ！！）。

## あとがき

食わず嫌いでした。冬コミ前に入れておけばよかったと後悔してる...
（自力でロードしてた処理とかを除去する無駄な作業が増えちまったぜ！）

## さらにあとがき（数日つかってみて）

ダメですね。プロジェクトから消しました。

- シーンを開く/閉じるをフックとした外部拡張と相性がゲロで、シーンが壊れる問題
- 3つ以上のシーンを同時に触った時の依存関係処理が怪しい
- 相互参照以外のマルチシーンの扱いが不得手というか、壊れる

軽く触ると神だけど、実際に使うと糞オブ糞なのはUnityAssetあるあるなので、なんとも思わないけど、こういう時間の無駄の使い方させられるのが、Untiyまじ糞
【Rails5】helperって何なのかが今頃わかったってだけの記事

いや〜〜知らなかった。。

本当に知らなかった。。

今まで「helperってなんだろう？viewに変数とか渡せるの？」とか疑問に思っており、

自分の中では「controllerにたくさんメソッド書くと汚くなるから、可読性をあげるためにメソッドを変わりに書く場所」と勝手に解釈していましたが。

<br>

なんと今日、その答えがわかりました。

<br>

# そもそも

solidusの実装で詰まってたんですよね。

何に詰まっていたかというと、
before_actionで読み込んだメソッドをviewで呼ぼうとしたときに
`Error : undefined method`が出てしまう。。

binding.pryを挟むとコンソール上では呼べるのになぜ呼べない？？？？
ここで詰まってました。

こういうときのために、やっぱりメンターがほしいなって思って、
先月からMENTA経由でメンターさんと契約してたんですよね。

<br>

そこで質問して言われたのが

<br>

#「メソッドはViewでは呼べないよ！」

<b>「Helperに書いてたら別だけどね。」</b>

<br>

えーーーーっ！！！！そうなの！？！

まさかこんなところで長年の疑問が晴れるとは…（Rails始めて1年経ってない

<br>

いやあ〜〜〜〜マジか。これ、Tutorial5周ほどやってましたがそこでもわからなかったんですよね。

<br>

#てなわけで

```
Controller 
↓
↓
↓
　Helper
↓　
↓
↓　
View
```
<br>
メソッドに関して言えばこういうことですよね？？
<br>

以下はメンターさんに聞いた話なんですが、
Viewでメソッドを呼んだり、メソッドの戻り値を使いたい場合、
`1. メソッドをHelperに書く`
もしくは、
<b>`2. Controllerでメソッドの戻り値を@ローカル変数に入れ、viewにわたす`</b>


で解決できるらしいです。
自分は2.の方法を使って解決しました。

<br>

#いやーーーマジか。。

いやーーー。。

ちょっと衝撃でした。。

聞くだけだと超基本的なことなのに、今までそこすらわかっていなかったなんて。。

落ち込むことはないですが、ちょっとショックですね笑笑


けど今日知れたので、めっちゃラッキーでした。本当に良かったです。

<br>

しかし、、、本当にメンターって重要ですねえ。（twitterにも書いた

毎月お金を払う価値は十二分にありますね。

もっとがんばろー。

<br>
TypeScriptのtsconfig.jsonをあれこれしてみた その２

# 前回の記事

[TypeScriptのtsconfig.jsonをあれこれしてみた その１](https://qiita.com/Nekonecode/items/a791e8d5854bd84954e4)

# tsconfig.jsonを触る前に

このように、`tsc`になんのオプションも指定しないで実行するとどうなるのか実験

```
npx tsc
```

> Version 3.2.2
> Syntax:   tsc [options] [file...]
> 
> Examples: tsc hello.ts
          tsc --outFile file.js file.ts
          tsc @args.txt
          tsc --build tsconfig.json
> 
> Options:
> ...

というわけでヘルプが表示され、コンパイルは何もされませんでした。


# tsconfig.jsonを用意してみる。

`root/tsconfig.json`を作成(中身はとりあえず空で)して再チャレンジ。

> error TS6053: File '/Users/nekonecode/work/lab/ts/tsconfig.json' not found.

挙動が変わりました。エラーになるんですね。

# tsconfig.jsonを少しだけ編集

```tsconfig.json
{}
```

空のオブジェクトを描いてみました。
さぁ`npx tsc`だ、どうなる。

<del>結果はエラーも表示されないし、コンパイルもされないでした。
これはちょっと予想外の結果。</del>

コンパイルされてました。
単純に`.ts`と同じ階層にコンパイルされたファイルが作られます。


# 雛形だけ描いたtsconfig.jsonにしてみる。

```tsconfig.json
{
  "compilerOptions": {
    
  }
}
```

<del>おそらく何も起こらないだろうと予想してやってみましたが
予想通り、エラーにもならず、コンパイルもされませんでした。</del>

こちらも前述と同様、コンパイルされていた。


# さて、何を書けばコンパイルされるのか

とりあえずコマンドで指定していた`--outDir`を指定してみます。

```tsconfig.json
{
  "compilerOptions": {
    "outDir": "./build"
  }
}
```

これを描いて`npx tsc`をしたらコンパイルが実行されました。
`npx ./src/index/ts --outDir ./build`としていた時と同じ結果になりました。

## --outDir
> Redirect output structure to the directory.

翻訳すると「出力構造をディレクトリにリダイレクトします」
意味がわからんけど、まぁ普通にコンパイルした結果を入れるディレクトリを指定するオプション。
これをしてすればコンパイルはされるようです。

# どのファイルがコンパイルの対象になるのか？

今回はsrcの中にあるtsが全てコンパイルされていた。

```
root
 ┣━ build
 ┃   ┣━ index.js
 ┃   ┗━ util.js
 ┗━ src
     ┣━ index.ts
     ┗━ util.ts
```

じゃぁこうしたらどうなるのか(root/index.tsを準備)

```
root
 ┣━ index.ts
 ┗━ src
     ┣━ index.ts
     ┗━ util.ts
```

buildの中身はこうなりました

```
build
 ┣━ index.js
 ┗━ src
     ┣━ index.js
     ┗━ util.js
```

`root`配下にある全ての`.ts`がコンパイル対象になっているみたいですね。

## --rootDirオプションを指定してみる。

```tsconfig.json
{
  "compilerOptions": {
    "rootDir": "./src",
    "outDir": "./build"
  }
}
```

これで`npx tsc`をやってみた結果は:
> error TS6059: File '/Users/nekonecode/work/lab/ts/index.ts' is not under 'rootDir' '/Users/nekonecode/work/lab/ts/src'. 'rootDir' is expected to contain all source files.

`rootDir`で指定したフォルダに全てのソースコードを入れなさいと怒っておられます。
ただ地味にコンパイルはされていました。(エラーは出るけどコンパイルはされるという半端な結果に)

# 他の設定も試してみる

とりあえず`.ts`はこんな感じで存在しているとして

```
root
 ┣━ index.ts
 ┗━ src
     ┣━ index.ts
     ┗━ util.ts
```

## filesを指定してみる その１

```tsconfig.json
{
  "compilerOptions": {
    "outDir": "./build"
  },
  "files": [
    "./src/index.ts"
  ]
}
```

結果:

```
build
 ┣━ index.js
 ┗━ util.js
```

- `root/index.ts`はコンパイルされない
- `index.ts`しか指定してないけど、`index.ts`で参照してる`util.ts`もコンパイルされる。

## filesを指定してみる その２

```tsconfig.json
{
  "compilerOptions": {
    "outDir": "./build"
  },
  "files": [
    "./src/util.ts"
  ]
}
```

結果:

```
build
 ┗━ util.js
```

- `util.ts`だけがコンパイルされた(これは他のファイルを参照してないからね)

## includeを指定してみる

```tsconfig.json
{
  "compilerOptions": {
    "outDir": "./build"
  },
  "include": [
    "src/**/*"
  ]
}
```

結果:

```
build
 ┣━ index.js
 ┗━ util.js
```

とまぁ結果は同じだけどいろんな方法でコンパイル対象を限定できることがわかりました。
こんな感じでいろんなオプションを試していきたい。