OmniAICreator/Qiita-1.07M huggingface dataset:
Houdiniのジャンプリストを設定する

## ジャンプリスト(Jump List)とは

`$HIP` や `$JOB` のようなもの。
いわゆる環境変数(Environment Variables)みたいなもので、Linuxの `$~` に相当する。

![houdini_jump_list_new.PNG](https://qiita-image-store.s3.amazonaws.com/0/51857/b2372c83-eef5-ef54-4a2d-4af7de56199d.png)


## どうやって設定すればいいのだろうか？

この `$HIP` や` $JOB` 、かなり使い勝手がよく、アーティストからも使用を好まれる。
しかしながら、パイプライン上でこれを使用したい場合には `$HIP` や `$JOB` 以外にも使いたい項目が増える場合がある。

そこで、設定するために使用するのが `jump.pref` 。

これを `HOUDINI_PATH` か `HOUDINI_USR_PREF_DIR` の直下に置く。


ディレクトリわからない時には、Command Line Toolで `hconfig -p` と叩くと、設定されてるパスが表示される。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/51857/d158cdfb-03dc-4999-9b07-f0db60e4c57b.png)

## 中身

例えば、

```
$SHOT
$TEXTURE
```

これらをパイプライン上で縛っておけば、パイプライン上の長いパスコントロールが可能になるので、気持ちくアーティストに使ってもらえると思う。

このファイルはHoudiniの起動時に呼ばれるので、編集したらHoudiniの再起動を行う。

ちなみに、HoudiniのFile Dialogウィンドウでもジャンプリストが作成可能だが、これの設定ファイルは基本 `HOUDINI_USER_PREF_DIR` の直下に作成されていく。

## スクリプトでジャンプリストにパスを設定する

結果的に正攻法を書くと、現状では多分これ。

```python
import os

project_root = 'E:/project_a'
shot = 's001'
cut  = 'c001'

shot_path = os.path.join(project_root, 'work', shot, cut).replace(os.path.seq, '/')
texture_path = os.path.join(shot_path, 'texture').replace(os.path.seq, '/')

cmd = 'setenv {}={}'.format('SHOT', shot_path)
hou.hscript(cmd)

cmd = 'setenv {}={}'.format('TEXTURE', texture_path )
hou.hscript(cmd)
```

これで、それぞれ次のところに変数が通る。
`SHOT => E:/project_a/work/s001/c001`
`TEXTURE => E:/project_a/work/s001/c001/texture`

実のところ、Houdini Object Modelにはちゃんと次の関数が用意されている。

* [hou.putenv(name, value)](http://www.sidefx.com/docs/houdini/hom/hou/putenv.html)
* [hou.getenv(name, default_value=None) -> str](http://www.sidefx.com/docs/houdini/hom/hou/getenv.html)
* [hou.unsetenv(name)](http://www.sidefx.com/docs/houdini/hom/hou/unsetenv.html)

しかしながら、ことこの変数設定に関してはHScriptの方を利用した方がいいと思う。

というのも、なぜかHOMを使った場合だとVariablesウィンドウ(Edit->Aliases and Variables...)に表示されないから。
ちゃんと値としては入っているので問題なく使えるのだが、「見えなくなる」というのは、それは恐怖であるもので。。 :sweat_smile:

![image.png](https://qiita-image-store.s3.amazonaws.com/0/51857/8f29814c-57cc-45c5-1673-32cae30426c2.png)
bootstrapの利便性

今回も備忘録的に。
サービスを作る上で、今回はバックエンド側を作り込みたいので、
フロントはなるべく工数削減。フレームワークを使って後からカスタマイズしていきます。

今回使うのはbootstrap。
twitterが提供しているフレームワークらしく、
1.htmlにclassを当てるだけでcssが当たり、綺麗なデザインが出来上がる
2.レスポンシブ、クロスデバイス対応を自動で行ってくれるのでPC・SPどちらのデザインにも有効
とのこと。

もう少し使ってみてからアップデートします！
Macでターミナルの背景をポケモンにする(iTerm) 

![ガーディ](https://camo.githubusercontent.com/3b2e91ca14fffde23e1c954267216a788cc6f8f3/68747470733a2f2f692e696d6775722e636f6d2f736d76437848472e706e67)

最近ギークハウス界隈で流行ってるので、この機会にやってみようと思い導入してみました。
生産性上がった（気がする）

↓githubはこちら。
https://github.com/LazoCoder/Pokemon-Terminal



↓こちらを参考にしてみるも、homeに.hyper.jsが表示されずできなかった。
https://qiita.com/chanuu/items/b5c3d11e089ad0c7356d



パイソニアンが隣でご飯食べてたので、適宜質問しながらgithubを参考にpipから入れてみました。
**MacにはデフォルトでPython2が入っていますが、Python3を入れないと（たぶん）だめ。**
※Python3がすでに入ってる人はここは飛ばしてください。


↓入力してバージョンが表示されなかったらPython3が入ってないので入れてください。
`$ python3 --version`
`Python 3.6.0`　←バージョン

↓Python3の入れ方はこちらから
https://qiita.com/ms-rock/items/6e4498a5963f3d9c4a67


# 1. pipをインストールする

pipのインストール
`$ sudo pip3.6 install git+https://github.com/LazoCoder/Pokemon-Terminal.git`



#2. PATHを適用する

PATHを通さないと適用されない（はず）。iTerm再起動せずにやったので自動適用されるかはわからないです。念のため。
`$ source ~/.bash_profile`



#3. 適当にポケモンを入力してみる
例:ピカチュウ
`$ pokemon pikachu`

![ピカチュウ](https://camo.githubusercontent.com/7dac1ea2d62591d70200305c8641a58060a6ebdc/68747470733a2f2f692e696d6775722e636f6d2f6e3334665879702e706e67)

ポケモンの名前は[Hyper Pokemon](https://klauscfhq.github.io/hyper-pokemon/)でお好きなポケモンをどうぞ！

#番外. iTerm起動時にポケモン適用させる
iTermの設定で起動時の初期背景をポケモンにできます。

###### 1. iTermを選択状態でナビゲーションバーのiTerm2(画面左上)をクリック
###### 2. Preferences > Profiles >  Generalを順にクリック
###### 3. Command内のSend text at start:に `pokemon pikachu; clear`と入力

<img width="915" alt="スクリーンショット 2018-02-27 3.12.42.png" src="https://qiita-image-store.s3.amazonaws.com/0/209758/676a24e2-98e2-7644-b382-f866706f4815.png">

これで起動した瞬間にポケモンが見れて幸せになれます。
iTerm2の外観をポケモンにする

## 前提
Python3.5以降が必須のため、入っていない場合はインストールします。
※手順は、[前回記事](https://qiita.com/mzmiyabi/items/0e5ef874bad0b35d5a56)参照。

## githubから取得する
githubから取得します。

```bash
$ git clone https://github.com/LazoCoder/Pokemon-Terminal $HOME/.Pokemon-Terminal
```

## 環境設定ファイルへ追加する
.bash_profileが無い場合は、以下のコマンドで作成します。

```bash
$ touch .bash_profile
```

以下のコマンドで書き込み、反映します。

```bash
$ echo PATH="$HOME/.Pokemon-Terminal:${PATH}" >> ~/.bash_profile
$ source ~/.bash_profile
```

## テーマを変更する
例えばピカチュウに変更します。

```bash
$ pokemon pikachu
```
変更可能なポケモンのリストは、以下の場所のpokemon.txtで確認できます。

```bash
$ cat $HOME/.Pokemon-Terminal/pokemonterminal/Data/pokemon.txt
```
pyenvを入れてPythonのバージョンを切り替えられるようにする

## 前提
Homebrewを入れていない場合は、入れます。

```bash
$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
```

念のため、以下のコマンドで環境をチェックします。
エラーが出る場合は、適宜対応します。

```bash
$ brew doctor
```

## pyenvをインストールする

```bash
$ brew install pyenv
```

## 環境設定ファイルへ追加する
.bash_profileが無い場合は、以下のコマンドで作成します。

```shell-session
$ touch .bash_profile
```

以下のコマンドで書き込み、反映します。

```bash
$ export PATH="$HOME/.pyenv/shims:$PATH"
$ source .bash_profile
```

## pyenvで必要なバージョンをインストールする
以下のコマンドでインストール可能なバージョンを確認します。

```bash
$ pyenv install -l
```

Python3.6.4をインストールしたい場合は、以下のコマンドを実行します。

```bash
$ pyenv install 3.6.4
```
## 利用するPythonをセットする
実際に利用したいPythonを指定します。グローバルで指定する場合は`pyenv global`、ローカルで指定したい場合は`pyenv local`で指定します。

```bash
$ pyenv global 3.6.4
```

Pythonのバージョンを確認する場合は、以下のコマンドを実行します。

```bash
$ python -V
```

## Pythonをアンインストールする

```bash
$ pyenv uninstall 3.6.4
```
【MySQL】 group_concatでjsonを作る

とある事情で複数行のレコードを一つのjsonに押し込みたかったので`group_concat`でjsonを作成しました。

## やりたいこと
|Authors||
|:--|:--|
|id|name|
|1|author1|

|Books|||
|:--|:--|:--|
|id|name|author_id|
|1|book1|1|
|2|book2|1|
以上のAuthorsテーブルとBooksテーブルから

|id|name|books|
|:--|:--|:--|
|1|author1|[{"id":1,"name":"book1"},{"id":2,"name":"book2"}]|

のような配列型のjsonを含むデータを作ります。

## SQL
```.sql
select 
Authors.id, 
Authors.name, 
concat('[', trim(trailing ',' from group_concat('{"id":', Books.id, ',"name":"', Books.name, '"},')), ']')
from Authors inner join Books on Books.author_id = Authors.id
group by Authors.id;
```

## 解説
`group_concat`は連結した文字列を返す集約関数です。
これを使って、複数行のレコードを一つの文字列にまとめます。
イメージとしては、1レコードに対する`concat`を集約されたレコードに対して繰り返して全部繋げる感じです。

これだけだと最後のカンマが余るので`trim`関数に`trailing`オプションをつけて一番右のカンマを削除します。

最後にconcatで`[]`で囲って完了です。

## 参考リンク
`trim`関数や`group_concat`関数の詳細については以下のリンクを参考にしてください。
trim
https://dev.mysql.com/doc/refman/5.6/ja/string-functions.html#function_trim
group_concat
https://dev.mysql.com/doc/refman/5.6/ja/group-by-functions.html#function_group-concat
Fortran 2008 Quick Reference

#Fortran 2008 Quick Reference 
Fortran 2008 の Quick Reference を作ってみました。自分が良く忘れて、MFE (Modern Fortran Explained)で何度も調べる所などをまとめました。また、かつてひどい目にあった落とし穴なども忘れないように書き加えておきました。

今までの経験では、説明よりもコード断片がある方が便利だったので、コード断片中心にしてみました。コード断片は出来るだけ動くことを確かめました。Intel Fortran v18.0.1 および gfortran ver.7.1.1 で実行してみましたが、どちらも微妙に実装上の謎や未実装機能がありました。

形式としては A4 横三段組にして、昔ながらの三つ折り版にしてみました。A4 一枚裏表にはまとまらなかったのですが、複数枚になっても、最近百円ショップなどで売られている A4 三つ折りフォルダーにまとめられるのではないかと思います。

###今後の予定
誤りは出来るだけ無くすように努めましたが、見返すたびに新たな誤りが見つかるので、大目に見て下さい。

構成・章立ては暫定です。徐々に修正してゆきたいと思います。
今後は色付きカラー化できたらと思っています。

##github　
https://github.com/cure-honey/Fortran2008QuickReference
https://github.com/cure-honey/Fortran2008QuickReference/blob/master/F2008QuickRef.pdf

##画像
![ダウンロード.png](https://qiita-image-store.s3.amazonaws.com/0/44522/a537f31c-d35c-b0d9-3096-65490f4b29f0.png)
![ダウンロード (1).png](https://qiita-image-store.s3.amazonaws.com/0/44522/2efc79ff-06ef-fcfc-99f8-0ce6cd79cac7.png)
![ダウンロード (2).png](https://qiita-image-store.s3.amazonaws.com/0/44522/0595c68e-581a-ee7b-5476-ed96d1123be6.png)
![ダウンロード (3).png](https://qiita-image-store.s3.amazonaws.com/0/44522/cafb66a6-cb98-614e-51e6-5a0cad56a727.png)
React Native初心者が実装前に学んだ Redux Store vs Component State

#気持ち
Laravel + Vue.jsエンジニアもスマホアプリを作りたいと思い、React Nativeに手を出しました。
FluxやReduxも流行ってるみたいなので、React Native + Reduxでアプリを作ってやろうと思いました。
ReactNative公式チュートリアルやRedux入門記事を読み終え、アプリの仕様をざっくり考えてUIを組み、ロジックの設計及び実装フェーズに入りました。

これから実装していくのはチュートリアルのような小規模なものではなく中規模レベルのものであるため、Reduxという枠組みがあるとは言え、実装途中でコードが複雑にならないか心配になりました。
やり方は色々あると思うのですが、Reactの素人なりに色々ググってみると以下の記事が面白そうだったので、頑張って英語を読んで自分の言葉でまとめました。

[Component State vs Redux Store](https://medium.com/netscape/component-state-vs-redux-store-1eb0c929277)


#記事概要
上記記事の筆者は1年半のReact+Reduxでの開発経験から、React+Reduxの初心者は大抵**「どのcomponentをRedux Storeに依存させるべきで、どのcomponentを自身の内部stateにのみ依存させるべきかの判別で混乱する問題」**に直面しがちだということを知ったそうです。そしてその判別を簡単にする試みとしてこの記事を書いた、とのことです。

記事の内容を以下にまとめました。記事内の用語はそのまま使いつつも、自分が理解しやすい形でまとめているため文章の構成が入れ替わったりしています。

#記事まとめ
Component/this.state/Redux Store間での依存関係で混乱しないためには
**①データをどこに格納すべきか**
**②componentファイルをどのようなディレクトリ構成にすべきか**
の２つの切り口から、判別を行うとよい。それぞれ以下解説。
##①データをどこに格納すべきか
**・複数のcomponentやpage間で共有される必要のあるデータは`Redux Store`に格納すべき**
　記事内の例では、ヘッダーに表示されるログイン情報やショッピングカート情報は複数page間で共有される情報なので、`Redux Store`に格納している。　

**・そのcomponentでしか使わない情報は`this.state`に格納すべき**
　記事内の例では、商品一覧情報は「ProductsContainer」componentでしか使われないため、`ProductsContainer.state`に格納している。
##②componentファイルをどのようなディレクトリ構成にすべきか
![1_elgGRAH17xJdjApjmbobEg.png](https://qiita-image-store.s3.amazonaws.com/0/31318/608040c7-b309-9722-838b-04d0795cf3ae.png)

・components/Presentational/
・components/Smart/
・containers/
の３つが注目すべきディレクトリである。

**・components/Presentational/ には`Dumb Components　(Presentational Componentsとも呼ぶ)` のファイルを保存すべき。**（Dumb=物の言えない, Presentational=表現の）
　`Dumb(Presentational) Components`とは親コンポーネントから受け取ったデータをthis.props.~~で表示することだけが責務であるcomponent。
　Smartでなく物の言えないComponentのため、`this.state`を持たない。

**・components/Smart/ には`Smart Components`のファイルを保存すべき。**
　`Smart Components`とは`this.state`を持っているcomponentのこと。
　内部に情報やロジックを持っているのでSmart。

**・containers/ には`Container Components`のファイルを保存すべき。**
　`Container Components`とは`Redux Store`と連携するcomponentのこと。
【Unity】子同士の関係にあるメンバ変数の値をコピーするエディタ拡張

子同士の関係にあるメンバ変数の値をコピーするエディタ拡張。
ContextMenuにあるPaste Componentでは異なるクラス間の値のコピーができない。
例え同じ親を継承していても...。親クラスのメンバ変数部は同じ値やコンポーネントにしたいことがある。
一々Inspectorで編集するのが面倒なのでエディタ拡張でコピーする機能を作った。

# 使い方
1. メニューのWindow/ComponentFieldCopyerを選択
2. コピー元とコピー先のコンポーネントをドラッグ・アンド・ドロップ
3. Copyを押す
4. 実行される

# コード
```csharp
using System;
using System.Reflection;
using UnityEditor;
using UnityEngine;

/// <summary>
/// メンバ変数のコピーを行う
/// EditorWindowでコピー元とコピー先のコンポーネントを指定する
/// </summary>
public class UniCopyField : EditorWindow
{
    private UnityEngine.Object fromObj;
    private UnityEngine.Object toObj;

    [MenuItem("Window/ComponentFieldCopyer")]
    private static void OpenWindow()
    {
        EditorWindow.GetWindow<UniCopyField>("ComponentFieldCopyer");
    }

    void OnGUI()
    {
        fromObj = EditorGUILayout.ObjectField("From", fromObj, typeof(UnityEngine.Object), true);
        toObj = EditorGUILayout.ObjectField("To", toObj, typeof(UnityEngine.Object), true);

        if(GUILayout.Button("Copy")) {
            copy(fromObj.GetType());
        }
    }

    private void copy(Type fromType)
    {
        if(fromType == typeof(MonoBehaviour)) return;
        foreach(var from in fromType.GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance)) {
            var other = fromType.GetField(from.Name, BindingFlags.SetField | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
            if((other != null)) {
                try {
                    other.SetValue(toObj, from.GetValue(fromObj));
                } catch(Exception e) {
                    Debug.Log(e);
                }
            }
        }
        // fromの親クラスからコピー
        copy(fromType.BaseType);
    }
}


```

# 仕組み
## 設定Window
UnityのEditorWindowでコピー元とコピー先のコンポーネントを取得する。
UnityEngine.Object型で取得するためほぼ全てのコンポーネントに対応できる。
Inspectorから「コンポーネントを」ドラッグアンドドロップで設定すること。
EditorGUILayout.ObjectFieldで設定されたコンポーネントを取得しておく。

## メンバ変数の取得
[Reflection](https://qiita.com/dolls/items/c7b3cf2520baae158a3a)を用いて2つのクラスの共通のメンバ変数を取得する。
GetFieldおよびGetFieldsで指定したTypeのメンバ変数が取得できる。
BindingFlagsで取得するメンバ変数の条件を設定する。
両方に共通して持つフィールドのみSetValueで値を代入。
コピー先がメンバ変数を持っていない場合は例外を吐かせることにした。
GetFieldsでは親クラスのprivateメンバは取得できないため、Type.BaseTypeで今度は親クラスのメンバ変数の取得を行う。


# GitHub
https://github.com/tetsujp84/UniCopyField
別サーバでLet's Encrypt証明書を作成する

# 証明書を別サーバで作成する
* （独自ドメインの証明書の場合、）ドメインレジストラの設定画面などでDNSを設定して、証明書作成用のサーバにドメイン名でアクセスできるようにする。

* 80ポートへインターネットからアクセスできるようにNSGやファイアウォールをオープンする

```bash:bash
#install
wget https://dl.eff.org/certbot-auto
chmod a+x certbot-auto
./certbot-auto #注意：関連するyumやaptのパッケージが実行時にアップデートされる

#証明書の取得
./certbot-auto certonly --standalone -d <your domain ex. www.example.com>
# E-Mailアドレスの入力
# 80ポートのオープンが必要

#取得した証明書の確認 (liveは最新の証明書へのシンボリックリンク)
sudo ls /etc/letsencrypt/archive/
sudo ls /etc/letsencrypt/live/

```

* 再度NSGやファイアウォールを閉じる
* 作成した証明書を対象サーバに配置する
* DNSを正規のサーバに向ける
* 
  参考: [Let's encrypt運用のベストプラクティス \- Qiita](https://qiita.com/tkykmw/items/9b6ba55bb2a6a5d90963)


  参考：[Let's Encrypt の使い方 \- Let's Encrypt 総合ポータル](https://letsencrypt.jp/usage/)
slack hubotを使って天気予報を取得する

[slack hubotを使ってみる](https://qiita.com/hf7777hi/items/8ce1522b4e1618f73f10)
[slack hubotを使って遅延情報を取得する](https://qiita.com/hf7777hi/items/9d62a3ac19e28268738a)
の続々編。

今回は、[openweathermap](https://openweathermap.org/)APIを使って天気予報を取得してみたいと思います。

ほんと色々参考になるサイトがあって楽勝にできました（ほんとありがたい！）。
今回参考にしたのは以下のサイト。
[【Hubot】天気を教えてくれるBot](http://miko.info/?p=178)

#API Keyを取得
[openweathermap](https://openweathermap.org/)
に登録して、↓からAPI Keyを取得しましょう。
![スクリーンショット 2018-02-27 1.11.18.png](https://qiita-image-store.s3.amazonaws.com/0/86605/97b1955b-cceb-fe27-e78d-c9e7708443fa.png)


都市一覧はここから取れるみたいです。
http://openweathermap.org/help/city_list.txt

#コードを書く
scripts/ にコードを書きます。
apikeyには取得したAPIkeyを入れるだけ。
↓な感じ。横浜と東京の天気を毎朝8時にお知らせしてくれます。また、「weather Yokohama」と尋ねるといつでも教えてくれる感じなってます。

```javascript
cronJob = require('cron').CronJob

module.exports = (robot) ->

  robot.respond /weather (.+)/i, (msg) ->
    target = msg.match[1]
    apikey = ""
    params = "q=#{target},jp&appid=#{apikey}&units=metric"
    searchWeather(params, target, msg)
    
  searchWeather = (url, place, msg) ->
    request = robot.http("http://api.openweathermap.org/data/2.5/weather?#{url}").get()
    stMessage = request (err, res, body) ->
      json = JSON.parse body
      if json['cod'] != 200
        #APIerror
        msg.send ":warning:" + json['message']
        return
      weatherName = json['weather'][0]['main']
      icon = json['weather'][0]['icon']
      temp = json['main']['temp']
      temp_max = json['main']['temp_max']
      temp_min = json['main']['temp_min']
      msg.send "今日の#{place}の天気は「" + weatherName + "」です。\n気温:"+ temp + "℃ 最高気温："  + temp_max+ "℃ 最低気温：" + temp_min + "℃\nhttp://openweathermap.org/img/w/" + icon + ".png"

  new cronJob('0 0 8 * * *', () ->
    apikey = ""
    #東京
    tokyo = "q=Tokyo,jp&appid=#{apikey}&units=metric"
    #横浜
    yokohama = "q=Yokohama,jp&appid=#{apikey}&units=metric"
    searchWeatherCron(yokohama, "横浜")
    searchWeatherCron(tokyo, "東京")
  ).start()
  
  searchWeatherCron = (url, place) -> 
    request = robot.http("http://api.openweathermap.org/data/2.5/weather?#{url}").get()
    stMessage = request (err, res, body) ->
      json = JSON.parse body
      weatherName = json['weather'][0]['main']
      icon = json['weather'][0]['icon']
      temp = json['main']['temp']
      temp_max = json['main']['temp_max']
      temp_min = json['main']['temp_min']
      sendMessage = "今日の#{place}の天気は「" + weatherName + "」です。\n気温:"+ temp + "℃ 最高気温："  + temp_max+ "℃ 最低気温：" + temp_min + "℃\nhttp://openweathermap.org/img/w/" + icon + ".png"
      robot.send {room: "#weather_info"}, sendMessage
      
```

#実行
実行するのみ〜

```
$ HUBOT_SLACK_TOKEN=<HUBOT_SLACK_TOKEN>./bin/hubot --adapter slack
```

![スクリーンショット 2018-02-27 1.17.49.png](https://qiita-image-store.s3.amazonaws.com/0/86605/53b05f27-efda-a487-44f4-ccec1c910b48.png)

きました〜今回は以上です。
Super Reduced StringをPHPで挑戦!! 文系学生がやってみた!!

##はじめに
インターン先でプログラミング勉強中の文系学生。

「最近、勢いが良いね」
「はい!!」
「じゃあ、Super Reduced Stringやろうか」
「はい?」

##Super Reduced Stringとは
いつも通り提示されたHackerrankのチャレンジ。
今回は[こちら](https://www.hackerrank.com/contests/miraidenshi/challenges/reduced-string)。

Google先生に翻訳してもらうと、「スーパー短縮文字列」。

さすがの~~ガバガバ~~翻訳。

要するに、文字列を短縮する仕組みか。

##実践
###推測
今の時点で必要になりそうなのは、
　1.大小のループ(1つの配列を比較するから)
　2.配列の要素を失くす仕組み(文字列を短縮するから)
だと思う。
1つ目はともかく、2つ目はどうすればいいんだろう?

###調査
まぁ、まずは構文の例を見てみないとわからないよね。
「Super Reduced String php」で検索すると、[このコード](https://gist.github.com/tirjok/012e56cd36e8e0284e2488b6fb5ac838)を発見!!

構文を見てみると、推測の1つ目は当たってた。
けれど、2つ目はちょっと違うね。
要素を失くすんじゃなくて、別の配列に要素を格納するみたい。
そりゃあ短縮って聞いたら消去するのを想像しますよ…

###構文理解
[このコード](https://gist.github.com/tirjok/012e56cd36e8e0284e2488b6fb5ac838)を参考に進めていこうと思ったけど、なんか後半の構文がおかしい気が…
あくまでも参考程度に進めよう。
構文を見てみると、配列を文字列に変換しているから、その処理も必要か。

###挑戦
構文に記入すべき処理をまとめると、次の3つ。
　1.大小のループ
　2.文字を入れるための文字列
　3.配列を文字列に変換する処理
それぞれを入れて…

`Run Code`っと。
よしよし。

`Submit Code`はどうかな…?
良いね!!

##まとめ
今回はSuper Reduced Stringを学習しました!!
感でしかないけれど、こういう処理はよくつかいそうだから、覚えておこうっと。
TabLayoutで長押し(onLongClickListener)する。

Viewであれば``setOnLongClickListener``をセットすればよいのですが、TabLayoutにはそういったリスナーをセットするメソッドがありませんでしたので、長押し時のリスナーのセットのしかたを試してみました。※pagerは使いません。

# ClickとLongClick

### 準備

```kotlin
val tabLayout = findViewById<TabLayout>(R.id.tab_layout)
tabLayout.apply {
    addTab(tabLayout.newTab().setText("タブ1"))
    addTab(tabLayout.newTab().setText("タブ2"))
}
```

```xml
<android.support.design.widget.TabLayout
    android:id="@+id/tab_layout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:tabIndicatorHeight="0dp"/>
```

### Click
タブをタップしたときの処理はそのままリスナーがセットできます。

```kotlin
tabLayout.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
    override fun onTabSelected(tab: TabLayout.Tab) {
        when (tab.position) {
            0 -> {/*タブ1のClick処理*/}
            1 -> {/*タブ2のClick処理*/}
        }
    }
    override fun onTabReselected(tab: TabLayout.Tab) {}
    override fun onTabUnselected(tab: TabLayout.Tab) {}
})
```

### LongClick
長押しはそのままセットできなかったので、タブレイアウトからViewを取り出してセットします。

```kotlin
val tabs = tabLayout.getChildAt(0) as ViewGroup
for (i in 0 until tabs.childCount) {
    tabs.getChildAt(i).setOnLongClickListener {
        when (i) {
            0 -> {/*タブ1のLongClick処理*/}
            1 -> {/*タブ2のLongClick処理*/}
            else -> {}
        }
        false
    }
}
```


# 最後に
ふと使う必要がでたものの、こういった実装方法しか思いつきませんでした。
単にクリックしたいときも同じところを連続でタップすると1回目は``onTabSelected``ですが、二回目は``onTabReselected``にコールバックするので普通のクリック処理も中のViewにリスナー付けたりしてます。
TabLayoutの使い方としてはあまり正しくないのかもしれないです。
iTunesで外付けHDDにiPhoneのバックアップを取る（Windows10）

深夜のサイ●リヤで延々とiPhoneのプレゼンをしたことが功を奏し、n年物のAndroid端末からiPhoneXに乗り換えた友人に捧げます。
![6640297395_0b5e46f237_b.jpg](https://qiita-image-store.s3.amazonaws.com/0/128458/c16fd441-97c4-85f9-c96d-9362d7449f9e.jpeg)

# 必要なもの
* iPhone X(iPhoneは新しければ新しいほどよいものである やまを)
* Windows 10(8でも大差ないかと)
* 外付けHDD

# 手順
## ソフトウェアのインストール
iTunes( https://www.apple.com/jp/itunes/download/ )をダウンロードします。
時間と通信量がかかるので気を付けてください。

## iPhoneとWindowsをLightningケーブルでつなぐ
iPhoneとWindowsの画面に、接続を確認する画面が出ます。iPhoneの位置情報の使用を許可していないと、適当な住所が出ますが気にしないでOKです。（明らかに自分が繋いだ直後であれば）

## 画面左上の小さなiPhone風ボタンを押す
![Inkeditunes1_LI.jpg](https://qiita-image-store.s3.amazonaws.com/0/128458/c06a7e02-59b3-a850-aed6-bd9d1a0b4beb.jpeg)
ここです。iPhoneが認識されるとボタンが現れます。出ない場合は繋ぎなおしたり、データの転送を許可する操作をやり直してください。（iCloud for Windowsとやらは、使ってません。iCloudへのバックアップはiPhoneの操作だけでもできるので。）

## （ちょっと脱線）音楽を手動で管理
<img width="825" alt="itunes2.png" src="https://qiita-image-store.s3.amazonaws.com/0/128458/92af5711-8b39-9e0f-b085-ba6d24196bd1.png">
iTunes入れたて、iPhone買いたてほやほやであればまだ気にしなくていいですが、そのうちiTunes/iPhoneに音楽を入れ始めると、不意の接続で音楽の同期が始まり動作が重くなったり、音楽が削除されてしまうことがあるのでチェックを入れておきましょう。

## 手動でバックアップ
<img width="825" alt="itunes3.png" src="https://qiita-image-store.s3.amazonaws.com/0/128458/f5e9157d-c21f-f15c-22d0-11f2f758f808.png">
手動でバックアップを作りましょう。（ローカルに保存されます）
これも時間がかかりますのでノートPCの場合は充電残量をご確認ください。
「iPhoneのバックアップを暗号化」してもいいですが、将来このパスワードを忘れると、肝心な時に復元できなくなるのでおすすめしません。「マスターいつもの」というパスワードがあれば、それでもよいです。

## バックアップファイルの場所（ローカル）
いま作ったバックアップは、以下のパスに保存されています。
`C:\Users\(あなたのユーザ名)\AppData\Roaming\Apple Computer\MobileSync\Backup`
この中にある、ランダムな文字列のフォルダをおもむろに外付けHDDの任意の場所にドラッグ＆ドロップしてください。

# これで、外付けHDDへのバックアップは完了です！お疲れさまでした！
ちなみに、バックアップファイルは大抵10数～数十GBあるので、ローカルからは消しちゃうのがおすすめです。
フルスキャンとか、Windows自体のバックアップ時に余計な時間と容量がかかってしまいます。
復元したいときはiTunesのバックアップフォルダに戻してあげましょう。


# バックアップしたiPhoneの名前を確認する
余興です。バックアップデータには、iPhoneの名前がデフォルトで付きます。（iTunes→環境設定→デバイス、の一覧に表示されているのがバックアップの名前）
`iPhone→設定アプリ→一般→情報→名前` でiPhoneの名前の確認、変更ができます。
※この名前が、テザリング時のWifi名になるので面白いWifi名を披露したい人はここで頭を振り絞ってください。

# バックアップに名前をつけたい
これも余興です。バックアップの名前を変えて、iTunes上で複数表示・管理することもできます。（用途は…iOSのメジャーバージョン毎とかですかね…？）
バックアップファイルの中にある `Info.plist` をワードパットかお気に入りのエディタで開いて、先ほど確認したiPhoneの名前で検索をかけて、その部分を変更してください。（メモ帳は大人の事情という名の改行コードの事情により使えません）
これでローカルのiTunesのバックアップフォルダに入れておけば、変更したバックアップ名で表示されると思います。

# 以上です。
よいiPhoneライフを！
Laravel on Docker で php artisan serve するとlocalhost:8000が見れない

掲題の件の対処法。
dockerコマンドの```-p```オプション付与、もしくはdocker-compose.ymlの```ports```設定はしてる前提。

素の```php artisan serve```を叩いた場合、自分(localhost)以外からのアクセスを受け付けないようになっている。
Dockerコンテナ内でcurlすると正常なHTTPレスポンスが返ってくるはず。

```bash
docker exec YOUR_CONTAINER curl localhost:8000
```

というわけでコンテナの外からアクセスできるようにしてやる必要がある。
以下のオプションを付けると見れるようになる。

```bash
php artisan serve --host 0.0.0.0
```
コンパイルしないES2015にES2015らしさが足りないような気がしたのでES2018で作り直す

元ネタ: [コンパイルしないES2015(ES6)なjavasciprtで横スクロールのブラウザゲームを作る](https://qiita.com/snakada/items/eb86ed81e0eb28e8d0ea)

## はじめに

元ネタのコードを見ていると、ES5時代から抜けていないような気がしたので、さらにES2018な技術を追加して書き変えてみるというのが今回の企画です。

## 対象者

* 元ネタにES2015らしさが足りないと感じる。
* ES2018(ES9)にトライしてみたい。
* ~~Shadow DOMのことをなんとなく知っている。~~ (まだやってない)
* ~~CSS Animationのことをなんとなく知っている。~~ (まだやってない)
* Node.jsぐらいは知っておけ。解説ではYarn使うけど。
* PCにChrome Canaryをインストール済み。

## 使う技術 (後日詳しく解説するとは言っていない)

オリジナルから追加で使う技術です。

* JavaScript (ES2018)
    * モジュール(import/export)
        * ~~nomodule~~ (近日実装予定のような気がする)
    * class構文
    * 非同期関数(async/await)
    * ~~ES2018の新機能~~ (結局使ってないような気がする)
    * Flow (コメント型のみ)
    * ~~Rollup + Babel~~ (nomodule用に)
* ~~Shadow DOM~~ (中日実装予定のような気がする)
* ~~CSS Animation~~ (遠日実装予定のような気がする)

## 成果物

元ネタをforkして作りました。できることは元ネタと一緒です。**原形を留めていないといった苦情は受け付けていません。**ほら、ネーミングとか、所々継承してますでしょ？

* 右記URLで実際にプレイできます。https://raccy.github.io/wallgame/
* レポジトリは右記の通りです。 https://github.com/raccy/wallgame

Chrome Canary版のGoogle Chrome 66で動作を確認しています。2018年2月26日現在のChrome Stable版(Chrome 64)ですら動作しなかったのですが、アップデートでバグがなおったのか今は動くようになっています。他のブラウザは知りません。

TODO

* バグ取り
* コードの整理 (余計なコメントとか、要らないコードとか、難易度とか)
* ES2018の新機能を使う (候補はObjectスプレッドと非同期イテレーターかな)
* nomodule版の提供 (IE11のために！)
* DOMの完全分離 からの Shadow DOM化
* CSS Animation (壁が浮き出るとかしたい)
* サウンド
* スタート画面
* マルチプレイヤー対応 (キーボード一つで4人同時プレイを目指します)
* フィールドサイズや難易度の設定、その他諸々

## 解説

 き・・近日中に公開できたら良いなー
AWS lambdaでasync/awaitを使うための最小構成

[追記]
今のlambdaはv8系に対応したので、以下のボイラープレートを使わなくてもasync/awaitは使うことができます。
ただ、webpackでbundleしたい場合はボイラープレートのコードが参考になるかもしれません。

現在のlambdaでは、node.jsはv6.10までしか対応しておらずasync/awaitはそのままでは使えない。
簡単にasync/awaitを使えるようにボイラープレートを作った。

[ボイラープレートのリポジトリ](https://github.com/TetsuyaNegishi/lambda-node-async-boilerplate)

# 利用の流れ

1. src/app.jsにコードを書いていく
2. webpack＋babelでトランスパイルして一つのjsファイルにまとめる
3. 生成したjsファイルをzip化
4. zipファイルをLambdaに手動デプロイ

＊ デプロイを自動化するツールもあるらしいですが、設定が大変そうだったのでやめました。Lambda初心者かつnodeでasync/awaitを使いたい人に向けたものです。

# ファイル構成

```
root/
　├ src/
　│　└ app.js
　├ .babelrc
　├ package.json
　└ webpack.config.js
```

# Babel

```json:.babelrc
{
  "presets": [
    ["env",{
      "targets": {
        "node": "6.10"
      }
    }]
  ]
}
```

Babelのプラグインには_babel-preset-env_を使用した。少し前には_babel-preset-es2015_が使われていたが、現在は_babel-preset-env_を使うほうがよいとのこと。

`.babelrc`でtargetsにnodeのv6.10を指定することで、そのバージョンで動くようにトランスバイルしてくれる。

# Webpack

```js:webpack.config.js
const path = require('path');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');

module.exports = {
  target: 'node',
  entry: path.resolve(__dirname, 'src/app.js'),
  output: {
    path: path.resolve(__dirname),
    filename: 'index.js',
    libraryTarget: 'umd',
  },
  resolve: {
    extensions: ['.js'],
  },
  plugins: [
    new UglifyJsPlugin(),
  ],
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: [{
          loader: 'babel-loader',
        }],
      },
    ],
  },
};
```

本当はBabelを使ってトランスパイルするだけでasync/awaitは使えるようになる。
しかしwebpackでバンドルしないとnode_moduleもzip化する必要があり、ファイルサイズが数十MBまで膨らんでしまった。
そのため、webpackでバンドルしている。

`src/app.js`をentryとしてroot直下にindex.jsを吐き出している。

webpack.config.jsははまりどころで設定にミスがあるとLambdaにデプロイしたときに正しく動いてくれない。
特に以下の点に注意。

- targetにnodeが指定されているか
- output.libraryTargetが'umd'になっているか

# zip化

[ボイラープレート](https://github.com/TetsuyaNegishi/lambda-node-async-boilerplate)ではpackage.json内で以下のようにnpm scriptsを設定している。

```json:package.json
{
"scripts": {
      "build": "webpack && npm run build:zip",
      "build:zip": "rm -f Lambda.zip && zip Lambda.zip index.js"
  }
}
```

シェルから`yarn build`を実行するとLambda.zipが生成される。
あとはLambda.zipをブラウザからデプロイすればOK。
Typescriptのコンパイル環境を作成する(webpack 4.0.0)

# webpackでtypescriptをコンパイルする
Typescriptを勉強したかったので、webpackを使って環境を構築することにした。
何番煎じかわからないが、忘備録としてアウトプット。

## npmから必要なmoduleを持ってくる
まずは

```
$ yarn init
```

moduleをinstall

```
$ yarn add -D ts-loader typescript webpack webpack-cli
```

## tsconfig.jsonを作成する
`includes();` とかも使いたいので`lib`に`dom`と`es2017`を追加

```tsconfig.json
{
  "compilerOptions": {
    "sourceMap": true,
    "target": "es5",
    "module": "es2015",
    "lib": [
       "dom",
       "es2017"
    ],
    "moduleResolution": "node",
    "experimentalDecorators": true
  }
}
```

## webpack.config.jsを作成する
`entry`とかのpathについては、適当に変更してください。

```webpack.config.js
/**
 * @file webpack.config.js
 */
module.exports = {
  mode   : 'development',
  entry  : './src/js/main.ts',
  output : {
    path    : `${__dirname}/dist/js`,
    filename: 'bundle.js'
  },
  module : {
    rules: [
      {
        test: /\.ts$/,
        use : 'awesome-typescript-loader'
      }
    ]
  },
  resolve: {
    extensions: [
      '.ts'
    ]
  }
};

```

## package.jsonに`scripts`を追記
```package.json
{
 // ~ 省略
  "scripts": {
    "build": "npm run clean && webpack --mode production",
    "dev": "webpack",
    "clean": "rm -rf ./dist"
  },
  "devDependencies": {
    "ts-loader": "^4.0.0",
    "typescript": "^2.7.2",
    "webpack": "^4.0.1",
  }
}
```

`npm run build`ってやってコンパイル...できると思ったが、何やらエラーが...

```
The CLI moved into a separate package: webpack-cli.
Please install 'webpack-cli' in addition to webpack itself to use the CLI.
-> When using npm: npm install webpack-cli -D
-> When using yarn: yarn add webpack-cli -D
```

CLIのパッケージが別れたとのことなので、指示どおりに `yarn add -D webpack-cli`を叩く。


```/src/js/main.ts

(function(){
  const hoge: string = 'hoge';
  alert hoge;
});
```
が

```dist/js/bundle.js
(function() {
  var hoge = 'hoge';
  alert(hoge);
});
```
コンパイルできたくさい。 
このままだと開発しにくそうなので、今度は`webpack-dev-server`とかを使って、hot reload出来るようにする~~かもしれない~~。
Dropboxのbackupをgitで取る

便利で使ってるDropboxですけど、どこかで誤ってファイルを消すと、同期しているすべてのマシンでそのファイルが消えてしまうので、同期とは別にバックアップがあった方が安心です。
どこかのマシンでcronとtarとかrsyncでバックアップしても良いのですが、何世代バックアップ取るかとか考えると面倒です。
そこで、gitを使えば履歴管理もできて便利だと考えました。
gitのリポジトリは、Dropboxディレクトリに置くわけにはいかないので、外に置くことになります。
最初、Dropboxディレクトリの親でgit initすることを考えたのですが、それだとホームディレクトリ全体が対象になってしまっていまいちです。
なので、gitのworking tree機能を使って、外に.gitディレクトリを作ることにします。
あ、環境はmacです。

```shell-session
% cd ~/Dropbox
% git init --separate-git-dir ~/.dropbox.git
```

続いて、~/Dropbox/.gitignoreを以下の内容で作ります。

```:.gitignore
.DS_Store
.dropbox
.dropbox.cache
.sync
Icon^M^M
/vimperator/vimperator-plugins
```

おもむろにgit add、そしてcommit

```shell-session
% git add .
% git commit -m "initial commit"
```

Dropboxの中に他の.gitディレクトリがあると、addするときに以下のような警告が出る。

```shell-session
warning: adding embedded git repository: vimperator/vimperator-plugins
hint: You've added another git repository inside your current repository.
hint: Clones of the outer repository will not contain the contents of
hint: the embedded repository and will not know how to obtain it.
hint: If you meant to add a submodule, use:
hint:
hint: 	git submodule add <url> vimperator/vimperator-plugins
hint:
hint: If you added this path by mistake, you can remove it from the
hint: index with:
hint:
hint: 	git rm --cached vimperator/vimperator-plugins
hint:
hint: See "git help submodule" for more information.
```

submoduleとして扱うこともないので、後者の指示の通りgit rmした。何故か、-fオプションが必要だったけど。→結局、.gitignoreに追加することにした。

後は、気がむいたときに git commit -aとかすれば良い。

ちなみに、.gitignoreの意味は以下。

- .DS_Store →説明不要ですよね？
- .dropbox →dropboxが作るディレクトリ
- .dropbox.cache →同上
- .sync →Resilio syncが作るディレクトリ？
- Icon^M^M →アイコン？emacsだったらCtrl + q/Ctrl + mを2回、vimだったらCtrl + v/Ctrl + mを2回。(git statusの画面とかだと、Icon\rと表示されるので、最初何も考えずに\rとか^Rとか書いてなんでうまく行かないんだろうと悩んだ。\r\n→^M^Jでしたね。)
- /vimperator/vimperator-plugins →このディレクトリに.gitがあるので。

このやり方だと、~/Dropbox/.git に以下の内容が書かれるので、.dropbox.gitがないマシンでgitコマンドを叩くと悲しいことになるけど、叩かなければ良いのです。

```:.git
gitdir: /Users/<ユーザ名>/.dropbox.git
```

参考にしたところ

- [macos - How to ignore Icon? in git - Stack Overflow](https://stackoverflow.com/questions/17556250/how-to-ignore-icon-in-git)
DeployGateで「有効期限切れです」

DeployGateにアップしたiOSアプリを
実機にインストールしようとしたところ、

いつもは「インストール」ボタンが表示されるところに
「有効期限切れです」
「アプリの有効期限が切れています。開発者にお問い合わせください。」
と書かれていて、
「インストール」ボタンが表示されない、
したがってインストールができない…！
困った…！

となった時のメモ。

## 【状況】

数時間前までインストールできていたのに、
突然インストールできなくなり、焦りました。

「開発者にお問い合わせください。」と書かれているものの、
開発者は私だし…！どうすれば…！

## 【解決方法】

始めは何の有効期限の事を言っているのかわからなかったのですが、
デベロッパー登録しているメールを確認したところ、

Your iOS Distribution will expire in 30 days.
This certificate will no longer be valid in 30 days. To create a new certificate, visit Certificates, Identifiers & Profiles in your account.
（30日以内に証明書の有効期限が切れるので新しい証明書を作ってね、とかなんとか）

こんなメールが１ヶ月前に来ていました…。
ちょうど30日ほど経ったため、証明書の期限が切れてしまったようです。

そのため、メールに書かれているURLから証明書を新しく作り直しました。

※このあたりの
https://developer.apple.com/account/ios/profile/
Certificates, IDs & Profiles >
左にある「Provisioning Profiles」から詳細を見ると、
赤いマークとともに「Expired（期限切れ）」と書かれた証明書が出てきました。
しかもその時は、数分経つ毎にひとつ、またひとつと「Expired」が増えていました…。
（ちょうど更新時期だったため、いくつかあった証明書が
端から更新されていたようです）
それらをクリックして、Editボタンからそれぞれの証明書を作り直しました。

その後、Xcodeに戻ってDeployGateにアップし直すと、
無事インストールできるようになりました。

## 【感想】

毎年同じ時期にアプリをリリースしていると、
同じような時期に有効期限が切れがちかもしれないな、と思いました。
今回もリリース予定の数日前に突然この状況になったので、焦りました…。

そして、証明書を作り直した後も、
DeployGateに過去に「有効期限切れです」と表示されたバージョンについては
ダウンロードできなくなってしまいました…。
以前とのバージョン比較をしたかったので、不便な事になってしまいました…。
HTTPステータス200ではない時のアクセスログをsyslogに出す

スクリプトを用意

```bash:/var/apache2/2.2/tools/apache_syslog
#!/usr/bin/bash

/usr/gnu/bin/awk " \
    /POST/ { \
        if (\$9 != 200) { \
          command = sprintf(\"echo '%s' | /usr/bin/logger -p local0.error\", \$0);
          system(command);
        } \
    } \
    { \
        print; \
    } " | cat >> /var/apache2/2.2/logs/access_log
```

httpd.confでログ出力設定

```httpd.conf
<IfModule log_config_module>
  CustomLog "|/var/apache2/2.2/tools/apache_syslog" common
</IfModule>
```
Thymeleafの出力結果を単体テストする

###  0.テストしようとしたきっかけ

ThymeleafとSpring MVCは便利でHTMLのパスを渡すだけで便利に処理をしてくれる。
ただThymeleafに本当に想定していた値が入っているかテストしたいと思いその方法を記載した。

### 1.Thymeleafのth:textの内容をテスト

####  1-1.まずはHTMLを用意する

th:textに正しい値がセットされるかテスト

```html:sample1.html
<!DOCTYPE html>
<html lang="ja" xmlns:th="http://www.thymeleaf.org">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>テスト</title>
</head>
<body>
	<div th:text="${th_text}"></div>
</body>
</html>
```

####  1-2.テストクラスを用意

ThymeLeafにth:textをセットしてその値が正しくHTMLにセットされるかテスト

```java:ThymeLeafTest.java
@Test
public void ThymeLeafのTextのテスト() {
// TemplateResolverに設定値をセット
TemplateResolver resolver = new ClassLoaderTemplateResolver();
 resolver.setTemplateMode("HTML5");
 resolver.setPrefix("templates/");
 resolver.setSuffix(".html");
// TemplateEngineにTemplateResolverの値をセット
TemplateEngine templateEngine = new TemplateEngine();
templateEngine.setTemplateResolver(resolver);

// ThymeLeafで使用するテキスト生成
Context ctx = new Context();
String hello = "テキストのテスト";
ctx.setVariable("th_text", hello);

// ThymeLaefの結果出力（templates配下のsample1.htmlを読み込む）
String result = templateEngine.process("sample1", ctx);
System.out.println(result);
// ThymeLaefの結果出力にセットした文字列があるか
assertThat(result, is(containsString(hello)));
}
```
### 2.Thymeleafのth:eachの内容をテスト

####  2-1.まずはHTMLを用意する

th:eachに正しい値がセットされるかテスト

```html:sample2.html
<!DOCTYPE html>
<html lang="ja" xmlns:th="http://www.thymeleaf.org">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>テスト</title>
</head>
<body>
	<table border="1">
		<tr th:each="element, elementStat : ${th_each}">
			<td th:text="${element}"></td>
		</tr>
	</table>
</body>
</html>
```

####  2-2.テストクラスを用意

ThymeLeafにth:eachをセットしてその値が正しくHTMLにセットされるかテスト

```java:ThymeLeafTest.java
@Test
publicvoidThymeLeafのEachのテスト(){
//TemplateResolverに設定値をセット
TemplateResolverresolver=newClassLoaderTemplateResolver();
resolver.setTemplateMode("HTML5");
resolver.setPrefix("templates/");
resolver.setSuffix(".html");
//TemplateEngineにTemplateResolverの値をセット
TemplateEnginetemplateEngine=newTemplateEngine();
templateEngine.setTemplateResolver(resolver);

//ThymeLeafで使用するリスト生成
Contextctx=newContext();
List<String>list=Arrays.asList("aaa","bbb","ccc");
ctx.setVariable("th_each",list);

//ThymeLaefの結果出力（templates配下のsample1.htmlを読み込む）
Stringresult=templateEngine.process("sample2",ctx);
System.out.println(result);
//ThymeLaefの結果出力にセットした文字列があるか
assertThat(result,is(containsString("aaa")));
assertThat(result,is(containsString("ccc")));
}
```

### ※今回のテストクラスを作って

本来のThymeLaefは、TemplateEngineクラスのprocessメソッドを介してHTMLに結果を介している。
Symfony初期インストール手順(3系)


## 環境

- LinuxまたはMacOS
- PHP 5.6以上
- Composer
- Symfony 3.4

## Symfonyインストーラーをインストール

[公式サイト](https://symfony.com/doc/3.4/setup.html#creating-symfony-applications)の通り

```bash

# コンソールで実行
sudo mkdir -p /usr/local/bin
sudo curl -LsS https://symfony.com/installer -o /usr/local/bin/symfony
sudo chmod a+x /usr/local/bin/symfony
```

## Symfonyプロジェクト生成

```bash
# コンソールで実行(3.4系の最新のSymfonyプロジェクトが生成される)
symfony new sample-project 3.4
```

## 確認

```bash
# コンソールで実行
cd sample-project
php bin/console server:run 0.0.0.0:8000
```
ブラウザで http://localhost:8000/ にアクセスしてWelcome画面が表示されれば成功

## Symfonyが必要とするライブラリなどの状況確認
不足している拡張機能などがないか確認するには次のコマンドを実行

```bash
# コンソールで実行
php bin/symfony_requirements
```
次のような出力がされていればSymfonyが概ね動作する状態

```bash
 [OK]                                         
 Your system is ready to run Symfony projects
```
node.js にとても長い式を食べさせると死ぬ

* [ruby にとても長い式を食べさせると死ぬ]( https://qiita.com/Nabetani/items/5d62ff62ffaf4c556989 )
* [python にとても長い式を食べさせると死ぬ]( https://qiita.com/Nabetani/items/68040ab25c4a845fb9c3 )

のシリーズ。

[整数を419378回インクリメントするとMacのg++が死ぬ](https://qiita.com/kaityo256/items/6b5715b213e955d44f55)
や
[C++でアスタリスクをつけすぎると端末が落ちる](https://qiita.com/kaityo256/items/d54439246edc1cc58121)
にインスパイアされて。

node.js に 

* `(((((1)))))`
* `[[[[[1]]]]]`
* `1+1-1+1-1+1-1+1-1+1-1`
* `!!!!!1`
* `{0:{0:{0:{0:{0:1}}}}}`
* `function(){ return function(){ return 1; }() }()`

のような式を食べさせていつ死ぬのか調べてみた。

node は v9.6.1 。
環境は、 macOS High Sierra。メモリ 16GB。

結果。

# `(((((1)))))`

```ruby:ruby2.5
a = [*1..20000]
p(a.bsearch do  |n|
  puts "#{n}"
  File.open( "hoge.js", "w" ){ |f| f.puts( "console.log("+"("*n+"1"+")"*n+")" ) }
  begin
    "1"!=%x( node hoge.js ).strip
  rescue
    true
  end
end)
#=>690
# RangeError: Maximum call stack size exceeded
```

なんか node.js はしぶといんじゃないかと先入観を持っていたんだけど、 ruby と比べるとだいぶ弱かった。
python よりは強いけど。


# `[[[[[1]]]]]`
```ruby:ruby2.5
a = [*1..20000]
p(a.bsearch do  |n|
  puts "#{n}"
  File.open( "hoge.js", "w" ){ |f| f.puts( "console.log("+"["*n+"1"+"]"*n+")" ) }
  begin
    !(/^[\[\s]+(1|Array)[\]\s]+$/===%x( node hoge.js ).strip)
  rescue
    true
  end
end)
#=> 767
# RangeError: Maximum call stack size exceeded
```

`( )` よりも `[ ]` の方が長持ちした。意外。
`[ ]` の方が重そうだけど。

# `1+1-1+1-1+1-1+1-1+1-1`

これは、「`+1-1`」の個数が 1億個でも死ななかった。
しぶとい。


# `!!!!!1`
```ruby:ruby2.5
a = [*1..1000000]
p(a.bsearch do  |n|
  puts "#{n}"
  File.open( "hoge.js", "w" ){ |f| f.puts( "console.log("+"!"*n+"1)" ) }
  begin
    !(/true|false/===%x( node hoge.js ).strip)
  rescue
    true
  end
end)
#=> 6204
# RangeError: Maximum call stack size exceeded
```

括弧と比べるとだいぶしぶとい。10倍ぐらいの感じ。


# `{0:{0:{0:{0:{0:1}}}}}`
```ruby:ruby2.5
a = [*1..20000]
p(a.bsearch do  |n|
  puts "#{n}"
  File.open( "hoge.js", "w" ){ |f| f.puts( "console.log("+"{0:"*n+"1"+"}"*n+")" ) }
  begin
    ""==%x( node hoge.js ).strip
  rescue
    true
  end
end)
#=>647
# RangeError: Maximum call stack size exceeded
```

オブジェクトのネストは、括弧と同じぐらいになった。
なんとなく、括弧の半分ぐらいと予想していたんだけど、ハズレた。

# `function(){ return function(){ return 1; }() }()`
```ruby:ruby2.5
a = [*1..1000000]
p(a.bsearch do  |n|
  puts "#{n}"
  File.open( "hoge.js", "w" ){ |f| f.puts( "console.log("+"function(){ return "*n+"1;" + "}()"*n + ")" ) }
  begin
    "1"!=%x( node hoge.js ).strip
  rescue
    true
  end
end)
#=> 375
# RangeError: Maximum call stack size exceeded
```

関数呼び出しのネストの重さは、括弧の倍ぐらいということなんだろう。
もっと重さに差があるものと想像していた。

#まとめ

node.js は、おおむね ruby よりは弱く、python よりは強い感じ。
ただ、「1+1-1+1-1 ... +1-1」に関しては、メモリの許す限りいくらでも行けそうな雰囲気である。

ブラウザでどうなるのかが気になるところだけど、手軽に試す方法がよくわからないのでやめておく。

根拠のない予想としては、 Firefox の圧勝で、次が Chrome、そして Opera、 Edge、 Safari の順かな。
ECTテンプレートで使える記法(memo)

ectを使う機会があったのでっ(' w ' )

| 記法                         　　　　 |       概要        　　　　　　　　　　　　　　　　　　　　　|
|:-------------------------------|------------------------------|
| <% %>      |CofeeScriptコードを埋め込める<br>コードは実行されるが、結果は出力されない|
| <%= %>     |任意のCofeeScript式を埋め込める<br>式の値は出力され、値はHTMLエスケープされる|
| <%- %>     |任意のCofeeScript式を埋め込める<br>式の値は出力され、値はHTMLエスケープされない|
|    %%>     |%>のエスケープで、%>出力時に使用|
| <%%        |<%のエスケープで、<%出力時に使用|
Git commands for undoing work

# Git commands for undoing work
|Command|Use|
|:-----------|:-------------|
|git checkout -b branch|Create a new branch with the name branch|
|git add filename(s)|Stage files in preparation for committing them to the repository|
|git commit|Save the staged changes to the repository|
|git checkout branch|Switch to the specified branch|
|git merge branch|Incorporate the commits from the branch branch into the current branch|
|git branch --delete|Remove a local branch|
|git branch -D|Remove al local branch whose commits are not incorporated elsewhere|
|git clone URL|Create a local copy of a remote repository|
|git log|Read the commit history for this branch|
|git reflog|Read the extended history for this branch|
|git checkout commit|Check out a specific commit; puts you into a detached HEAD state|
|git cherry-pick commit|Copy a commit from one branch to another|
|git reset --merge ORIG_HEAD|Remove from the current branch all commits applied during a recent merge|
|git checkout --filename|Restore a file that was changed, but has no yet been committed|
|git reset HEAD filename|Unstage a file that is currently staged so that its changes are not saved during the next commit|
|git reset --hard HEAD|Restore all changed files to the previously stored state|
|git reset commit|Unstage all of the changes that were previously committed up to the commit right before this point|
|git rebase --interactive commit|Edit, or squash commits since commit|
|git rebase --continue|After resolving a merge conflict, continue with the rebasing process|
|git revert commit|Unapply changes stored in the identified commit; this creates a sharing friendly reversal of history|
|git log --oneline --graph|Display the graphed history for this branch|
|git revert --mainline 1 commit|Reverse a merge commit|
|git branch --contains commit|List all branches that contain a specific commit object|
|git revert --no-commit last_commit_to_keep..newest_com|Reverse a group of commits in a single commit, instead of creating an object for every commit that is being undone|
|git filter-branch|Remove files from your repository permanently|
|git reflog expire|Forget about extended history, and use only the stored commit messages|
|git gc --prune=now|Run the garbage collector and ensure all noncommitted changes are removed from local memory|
Unityでデスクトップマスコットのためにウィンドウ透過した

#はじめに
最近、趣味でデスクトップマスコットを作成しています。
その過程で必要なのが**ウィンドウ透過**です。
作る過程で結構詰まったのでメモしておきます。

#開発環境
- Unity 2017.4.15f1
- Microsoft Visual Studio
- Windows 10 Home

#開発&実行

以下のようなコードを記述しました。

```C#:WindowTransparent.cs
using UnityEngine;
using System;
using System.Runtime.InteropServices;

public class WindowTransparent : MonoBehaviour
{
    [DllImport("user32.dll")]
    private static extern int GetForegroundWindow();

    [DllImport("user32.dll", EntryPoint = "SetLayeredWindowAttributes")]
    private static extern Boolean SetLayeredWindowAttributes(int hwnd, uint crKey, byte bAlpha, uint dwFlags);
    [DllImport("user32.dll", EntryPoint = "GetWindowLong")]
    private static extern int GetWindowLong(int hWnd, int nIndex);
    [DllImport("user32.dll", EntryPoint = "SetWindowLong")]
    private static extern int SetWindowLong(int hWnd, int nIndex, int dwNewLong);

    const int LWA_COLORKEY = 0x1; // SetLayeredWindowAttributesで第2引数を使う場合
    const int LWA_ALPHA = 0x2; // SetLayeredWindowAttributesで第3引数を使う場合
    const int GWL_EXSTYLE = -20; // 拡張ウィンドウスタイルを書き換えるためのオフセット
    const int WS_EX_LAYERED = 0x80000;

    const uint TRANSPARENT_COLOR = 0x00000000; // 透過する色

    void Start()
    {

#if UNITY_EDITOR

#else

        int handle = GetForegroundWindow(); // ウィンドウを指定

        int extStyle = GetWindowLong(handle, GWL_EXSTYLE); // ウィンドウの情報を取得
        SetWindowLong(handle, GWL_EXSTYLE, extStyle | WS_EX_LAYERED); // ウィンドウの属性を変更
        SetLayeredWindowAttributes(handle, TRANSPARENT_COLOR, 0, LWA_COLORKEY); // ウィンドウの特定の色を透過

#endif

    }

}
```

Unity Editorで実行するとめんどくさいことになるので
ビルドしたプログラムでのみ透過するようにしています。
また、透過するウィンドウは実行時の最前面にあるウィンドウになっています。

上記コードで実行する際には
* MainCameraのClearFlagsをSolid Color
* MainCameraのBackgroundを黒(#00000000)
にする必要があります。
![unity_desktopchar.png](https://qiita-image-store.s3.amazonaws.com/0/203750/311db2bf-34c9-8ef2-4ea7-8b2c8c2f8ad6.png)

また, ウィンドウを装飾するためにWindowsAPIを使用しているのでuser32.dllが参照できる状態にしておく必要があります。
Unityアプリケーションでdllファイルを参照する場合はAssetsフォルダ直下にPluginsフォルダを作成してdllファイルを入れておくよいです[[参考]](http://tvmllab.com/unity%E3%81%A7dll%E3%82%92%E4%BD%BF%E3%81%86/)。今回はuser32.dllをいれておきます
（上記コードを試してうまくいかない場合はこちらも試してみてください）

#最後に
UIのボタンに指定の色が含まれていて少し透過されたりすると
たまにボタンがきかなくなることがあったので調整が必要そうです。
また、デスクトップマスコットにするにはウィンドウのフレームを消したり、
透過したウィンドウを終了する方法を考えたりしないといけないですね。


#参考
https://answers.unity.com/questions/869378/viewing-desktop-in-scene.html
http://www.pinvoke.net/default.aspx/user32.setlayeredwindowattributes
http://blog.goo.ne.jp/hiro239415/e/6860f82ef2939e3e14268e96e0479edc
OpenFOAMでtutorialのdamBreakをやってみた

自分用の備忘録としてタイトルの通りtutorialのdamBreakをやってみた
流体は水と空気(VOF法の気液混相流解析)で非定常解析である


条件
PC:Windows10(3.2GHz、64bit、メモリ8Gb)、VirtualBox、DEXCS2017

解析条件
形状は下図の通り
![2018-02-26_22-07-07.png](https://qiita-image-store.s3.amazonaws.com/0/190551/abb282c8-7ac6-a9a5-3268-22bd691f1abb.png)

解析タイプ：非定常解析で0〜0.5sec

やり方は以下のホームページの通りやった
https://cfd.direct/openfoam/user-guide/dambreak/

解析の順序は次の感じで進めた
tutorialの解析ファイルを自分のフォルダにコピーする
blockMeshでメッシュを切る
解析実行
paraFoamで結果を表示する

```shell
a@a ~ $ run     //自分の作業ディレクトリに入る
a@a ~/OpenFOAM/a-v1706/run $ 
a@a ~/OpenFOAM/a-v1706/run $ cp -r $FOAM_TUTORIALS/multiphase/interFoam/laminar/damBreak/damBreak .   //tutorialをコピーし貼り付ける
a@a ~/OpenFOAM/a-v1706/run $ cd damBreak  //フォルダを移動する
a@a ~/OpenFOAM/a-v1706/run/damBreak $ blockMesh　　//メッシュを切る
a@a ~/OpenFOAM/a-v1706/run/damBreak $ cp 0/alpha.water.orig 0/alpha.water
a@a ~/OpenFOAM/a-v1706/run/damBreak $ setFields
a@a ~/OpenFOAM/a-v1706/run/damBreak $ interFoam | tee log　//解析を実行する
a@a ~/OpenFOAM/a-v1706/run/damBreak $ paraFoam　　//結果を表示する
```

ParaViewが起動するのでプロパティの「Volume Fields」の「alpha.water」にチェックを入れる

![2018-02-26_22-24-22.png](https://qiita-image-store.s3.amazonaws.com/0/190551/564261f6-6b1c-43da-6a6f-24c4dce0432f.png)

「Apply」をクリックするとモデルが表示される
![2018-02-26_22-30-09.png](https://qiita-image-store.s3.amazonaws.com/0/190551/732b0816-b658-956c-aa36-2725b20db4a6.png)

「Solid Color」を「◉alpha.water」に変更する
![2018-02-26_22-31-08.png](https://qiita-image-store.s3.amazonaws.com/0/190551/b393a316-a743-76ad-c427-20c2d59c6ff5.png)

再生ボタン(緑色のボタン)を押すとアニメーションが開始される

![result.png](https://qiita-image-store.s3.amazonaws.com/0/190551/2e72a177-a6da-913e-c095-8151fae5ff6a.png)
AWS CodedeployのGithubアクセストークンの削除について

## 概要
AWSのCodeDeployとGitHubを連携していて、
GitHubとのOAuth認証がうまくいかず、CodeDeploy側で設定したGitHubのアクセストークンを一度削除したいことがありました。

例) CodeDeploy設定画面
![スクリーンショット 2018-02-26 22.40.00.png](https://qiita-image-store.s3.amazonaws.com/0/95324/5c0387df-29ea-3f01-4a0f-0523c0fe7945.png)

ですが、GUI(マネジメントコンソール)だと削除画面もなく、GitHub側でパスワード変更しても状況変わらず困り果ててました。

## 解決策
GUIでは削除できないですが、CLIなら削除できるようです。
公式ドキュメントは [こちら] (https://docs.aws.amazon.com/cli/latest/reference/deploy/delete-git-hub-account-token.html) です。

実際にやった手順はこちら

```
$ aws deploy list-git-hub-account-token-names
TOKENNAMELIST	<GitHubアカウント名>
$ aws deploy delete-git-hub-account-token --token-name <GitHubアカウント名>
$ aws deploy list-git-hub-account-token-names
→なにも表示されないこと
```
ちなみにリージョンを指定する場合は、他と同様最後に```--region <リージョン名>```を入れればOKです。

削除後、CodeDeploy画面で再度GitHub連携し、以下のように表示されればOKです。
例） OAuth認証画面
![スクリーンショット 2018-02-26 22.49.23.png](https://qiita-image-store.s3.amazonaws.com/0/95324/ee556963-57e6-a054-bd9a-7f84f02bddc8.png)


## 注意
aws cliのバージョンが古いと上記オプションは使用できない可能性があるので、やる前にバージョンアップすることをオススメします。
C3.jsのdata.json、data.keysの挙動が思っていたのと違った

C3.jsのdata.jsonとdata.keysを組み合わせて利用した際に、個人的に思ってたんと違う挙動がありました。

# 基本的な挙動
```js
const sample = [{data1:12, data2: 1},{data1:4,data2:3}];
c3.generate({
  bindTo: "#chart",
  data: {
    json: sample,
    keys: {
      value: ["data1","data2"]
    },
    type: "pie",
  }
});
```
data.jsonに指定された配列から、data.keys.valueで指定されたkey情報ごとにデータを表示します。
今回の例であれば、data1が16、data2が4となる円グラフが表示されます。

# 思ってたんと違う挙動
data.keysに指定した値がラベルとして画面上に表示されます。
そのため、以下のようなコードを作成しました。

```js
const sample = [{"1.データA":12, "2.データB": 1},{"1.データA":4,"2.データB":3}];
c3.generate({
  bindTo: "#chart",
  data: {
    json: sample,
    keys: {
      value: ["1.データA","2.データB"]
    },
    type: "pie",
  }
});
```

するとなんということでしょう。グラフが表示されないではありませんか。

## なにが起きているのか。
原因を知りたかったので、C3.jsのソースを読んでみました。
なんやかんやあって、c3_chart_internal_fn.findValueInJsonというメソッドが実行されます。

```js
c3_chart_internal_fn.findValueInJson = function (object, path) {
    path = path.replace(/\[(\w+)\]/g, '.$1'); // convert indexes to properties (replace [] with .)
    path = path.replace(/^\./, ''); // strip a leading dot
    var pathArray = path.split('.');
    for (var i = 0; i < pathArray.length; ++i) {
        var k = pathArray[i];
        if (k in object) {
            object = object[k];
        } else {
            return;
        }
    }
    return object;
};
```
上記をみればわかるのですが、[]や.があった場合は、更に中のオブジェクトを参照するように作られています。
つまりkeysで"data1.hoge"と指定すると、C3.jsは以下のようなデータ構造を想定しています。

```js
[{data1:{hoge:1}},{data1:{hoge:2}}]
```
なんと高機能。だがしかし、そのまま表示して欲しい・・・。

## どうすればいいのか
### 対応方法1. data.columnsで指定する。
data.jsonではなく、以下のようにdata.columnsを利用します。
データ構造が先程と異なります。

```js
c3.generate({
  bindTo: "#chart",
  data: {
    columns:[["1.データA", 12, 4], ["2.データB", 4, 3]],
    type: "pie",
  }
});
```
data.columnsの場合、配列内の各配列の一つ目の要素がデータ名になります。
（説明が難しいですが、上記のコードを参照ください。。。）

### 対応方法2. data.jsonをオブジェクトにして、data.keysを省略する
公式のReferenceだとdata.jsonは配列にして、data.keysとともに利用するしかないっぽい雰囲気ですが、ソースコードを確認したところ、実は以下のように指定できます。

```js
const sample = {"1.データA":[12,4], "2.データB": [1,3]};
c3.generate({
  bindTo: "#chart",
  data: {
    json: sample,
    type: "pie",
  }
});
```
この場合は、オブジェクトのキーに[]や.があっても問題なく動作します。
これもデータ構造が変わってしまいますね。