OmniAICreator/Qiita-1.07M huggingface dataset:
jQueryとJavaScriptの比較

既存の古いページに合わせて、素のjavasciriptで頑張っていたら、
「jQuery使いなよ(笑)」って言われました。
ということで、（個人的には基礎を学びたいところもありjavascriptで書いてたんだけど・・・ぶつぶつ）
お仕事のためにもjQueryをおさらい。
javascriptと比べてどのくらい楽になるのか、直近使っていたものについて比較してみました。

# 比較内容
- おまじない
- 要素の生成
- 要素の取得
- 要素の追加
- 非同期処理（そのうち更新）

##おまじない
と、よく言われる、書き始めによく利用する書き方。

```js:js
(function () {
    //ここに処理を書く
}());
```

```js:jQuery
$(document).ready(function(){
  // ここに処理を書く
});

// 以下の書き方もある
$(function() {
  // ここに処理を書く
})

```
jsの書き方は、関数定義を()で括ることで関数呼び出しをせずに即実行する、即時関数というもの。スコープ汚染を防ぐために大事。
jQueryの書き方は、redyイベントという関数。HTMLドキュメントのロードが完了し、DOM操作ができるタイミングで処理を実行する。jsの window.onload に動作が似ている（window.onload はCSSやjsドキュメントも全てロード完了してから処理が実行されるので、厳密には違う)。

##要素の生成

```js:js
var input = document.createElement("input");
input.id = "hoge";
input.type = "hidden";

console.log(input): //<input id='hoge' type='hidden'>
```

```js:jQuery
var input = $('<input>').attr({
  id: "hoge",
  type: "hidden"
});

// もしくは、以下でも良い。
var input_2 = $("<input>", {
  id: "hoge",
  type: "hidden"
});

console.log(input_2[0]); //<input id='hoge' type='hidden'>
```


##要素の取得

```html:取得元のHTML
<p id="hoge" class="fuga"></p>
```

```js:js
// idで取得
var id = document.getElementById("hoge");
console.log(id); //<p id="hoge" class="fuga"></p>

// クラスで取得
var className = document.getElementsByClassName("fuga");
console.log(className); //HTMLCollection
```

```js:jQuery
// idで取得
var id_2 = $("#hoge").get(0);
console.log(id_2); //<p id="hoge" class="fuga"></p>

// もしくは、以下でも良い。
$("#hoge")[0];

/** 補足 */
// 以下の書き方だとjQueryのオブジェクトを取得してしまう。
// jsと同様にHTMLのDOM要素を取得するには、".get(0)"をつける必要がある。
$("#hoge")

// classで取得
$(".fuga")
```

##要素の追加
```html:追加先のHTML
<div id="hoge" class="fuga">Hello!</div>
```

appendChild

```js:js
var target = document.getElementById("hoge");
var p = document.createElement("p");
var text = document.createTextNode("How are you?");
p.appendChild(text);
target.appendChild(p);

console.log(target); //<div id='hoge'>Hallo!<p>How are you?</p></div>
```

```js:jQuery
// jsでは5行で書いていたものが1行で書ける。
$("#hoge").append('<p>How are you?</p>');

var target = $("#hoge")[0];
console.log(target); //<div id='hoge'>Hallo!<p>How are you?</p></div>

// 以下でも良い。
$('<p>How are you?</p>').appendTo("#hoge");
```


~~innerText（innerHTMLも同じ動きをするみたい）~~
→この解釈は間違いです。まだ修正できていません（すみません）。

```js:js
target = document.getElementById("hoge");
console.log(target) //<div id="hoge">Hallo!</div>

target.innerText = "Bye."

console.log(target) //<div>Bye.</div>　（上書きされる）
```

```js:jQuery
var target = $("#hoge")[0];
console.log(target); //<div id="hoge">Hallo!</div>

$("#hoge").html("Bye.");
  
console.log(target); //<div>Bye.</div>　（上書きされる）
```

#参考にさせて頂いたサイト
即時関数について
http://unitopi.com/js-function/
https://qiita.com/Koizumi-Greenwich/items/d192ad98ca8b2449e4fd

全体的に。だいぶ昔からお世話になっています。
http://semooh.jp/jquery/
プロキシ内でngrokを動かすための方法

# 前置き

以下の話はWindows環境での話です。
Macもプロキシ内なのにうまくいっているのでMacはシステム設定を自動的に読みにいっているのかもしれません。

# ngrokパッケージインストール

まず前提として、プロキシ内でnpmするためにはnpm自体にプロキシ設定をする必要があります。
[こちら](https://qiita.com/LightSpeedC/items/b273735e909bd381bcf1)など参照。

これでパッケージは取ってこれたのですが、ngrokはpostinstallでngrokのバイナリを取ってくるのでプロキシ内だとエラーになります。postinstallではrequestパッケージが使われているので`https_proxy`を設定すればよい（httpsに取りに行っているため）
https://github.com/request/request#proxies

# ngrok単体動作

というわけでパッケージをインストールしたので実行、したけど例外が起こる・・・
問題の切り分けのために以下のコマンドを実行。

```
ngrok http 3000
```

Session Statusがreconnectingで接続できていない雰囲気。
[ngrokのドキュメント](https://ngrok.com/docs#outbound-proxy)を確認したところ`http_proxy`を設定しろということらしい。設定したらonlineになった。

# ngrokパッケージ

これでOKかと思ったらまだエラー。プロキシ君が「127.0.0.1にアクセスできないよー」と。うん、できないと思う。
これはngrokモジュール（Node.js）がngrokバイナリにrequestパッケージ使ってAPI投げているためなので127.0.0.1を`no_proxy`に設定。

# まとめ

というわけでプロキシ内でngrokパッケージを動かすためには次の3つの環境変数を設定する必要がありました。

- https_proxy：ngrokバイナリを取るため。プロキシサーバを設定する
- http_proxy：ngrokバイナリが外部と通信するため。プロキシサーバを設定する
- no_proxy：ngrokモジュールがngrokバイナリと通信するため。127.0.0.1を設定する
IBM Cloud (IaaS) でやるべき設定項目

IaaS なので GNU/Linux のホストを用意します。

## デバイスの注文

SoftLayer カスタマーポータル
control.softlayer.com

デバイス - デバイス・リストからデバイスを注文し EOL の長そうなディストリビューションを選択。 Debian で延々とアップデートし続ける手も有りますが、ここでは CentOS を選択します。

ロケーションは Tokyo 2 。
OS は CentOS7.0-64 Minimal for VSI 。

## ドメインの登録

次にドメインを登録します。まったくの新規の場合、サービス - ドメインの登録から、必要なドメインを購入します。

ここでは dts-hoge.net を買ったことにします。

## DNS の設定

ネットワーク - DNS - 前方ゾーンを選択し、購入したドメインの DNS を設定します。サブドメインがある場合は A レコード、またメールを送信するなら MX レコード、 TXT レコードを設定しましょう。

```conf
$ORIGIN dts-hoge.net.
$TTL 86400
@ IN SOA ns1.softlayer.com. support.softlayer.com. (
                       2018071914        ; Serial
                       7200              ; Refresh
                       600               ; Retry
                       1728000           ; Expire
                       43200)            ; Minimum

@                      86400    IN NS    ns1.softlayer.com.
@                      86400    IN NS    ns2.softlayer.com.

@                      900      IN MX 99 @

@                      900      IN TXT   169.56.xx.x
@                      900      IN TXT   v=spf1 include:sendgrid.net ~all
@                      900      IN A     169.56.xx.x
```

前方ゾーンはもちろん、リバース DNS レコードも忘れず登録しておきます。

## SSL 証明書

セキュリティー - SSL - 注文から、必要な SSL 証明書を注文します。

この辺は長いので以下の記事などを参照。

さくらインターネットRapidSSL申込みからApache設定まで
https://qiita.com/kobake@github/items/81c5a589ffb11f77e61e

上記記事で書いてないこととしては、証明書のパーミッションは root:apache の 750 くらいにしておきます。特に秘密鍵は取り扱い注意なので。

## ウェブアプリケーションの配備

これはアプリケーションごとにリリース用の手順を用意していると思いますので、ターゲットとなる IaaS
 環境に自動配備するように仕込んでおきます。スケールアウトが必要ならそのあたりも仕込んでおきます。

## 監視

Softlayer は ping による死活監視しかしてくれないようなので munin を仕込みます。

この手の設定ファイルの常として、本体 (/etc/munin/munin.conf) は以下のように conf.d ディレクトリをインクルードするようにしておいて、ドメイン固有のカスタム設定はそのディレクトリ配下に置きます。

```conf
includedir /etc/munin/conf.d
```

カスタム設定 /etc/munin/conf.d/localhost.conf

```conf
contact.admin.command mail -s "[admin][munin][${var:host}] System resources monitoring report" dts-hoge@dts.co.jp
contact.admin.always_send warning critical

[xxx.dts-hoge.net]
    address 127.0.0.1
    use_node_name yes
    yum.pending.warning 25
    yum.pending.critical 50
    df._dev_xvda1.warning 70.0
    df._dev_xvda1.critical 90.0
    df._dev_xvda2.warning 50.0
    df._dev_xvda2.critical 90.0
    load.load.warning 5
    load.load.critical 10
    cpu.user.warning 95
    cpu.user.critical 99.5
```

これでリソース枯渇時にメールが来ます。


今回は以上です。
Atom を WSL の GIT_EDITOR として使う

WSL のターミナルから Git を使っている場合にコミットメッセージを Windows の Atom で入力できるようにする方法のメモです。Atom のターミナルから WSL の Git を使う方法については情報がたくさんありますが，逆（？）の場合は見当たらなかったのでまとめました。

やっていることは**パスを変換するラッパースクリプトを書いているだけ**です。

## WSL から Atom を使う場合の制限

[Atom は 1.18 で WSL からの起動をサポート](http://blog.atom.io/2017/06/13/atom-1-18.html)しました。また，[WSL と Windows の相互運用性](https://docs.microsoft.com/en-us/windows/wsl/interop)により，作業ディレクトリも可能な限り WSL のものが維持されるようになっています。これらのおかげで，Windows ファイルシステム（DrvFs）上のファイルやディレクトリならば，ほぼ問題なく Atom で開けます。

ただし，WSL から Atom でファイルやディレクトリを開くためには**相対パスで指定する必要がある**ようです。絶対パスだとうまくいきません。たとえば，`/mnt/c/path/to/sample.txt` を開こうとすると `C:\mnt\c\path\to\sample.txt` のように解釈されてしまいます。Windows ではスラッシュもパスの区切りとして利用できるためなのか，中途半端に受け入れられてしまってエラーにならず，作業ディレクトリのドライブが頭につきます。


## GIT_EDITOR として使う場合の問題

普通にエディタとして使う場合は常に相対パスで指定するようにすれば問題ありませんが，Git のエディタとして設定する場合には困ることがあります。

コミットを実行するとコミットメッセージを入力するために `COMMIT_EDITMSG` というファイルが指定したエディタで開かれますが，このファイルのパスは**絶対パスで渡される**ようなのです。Atom を WSL の `$GIT_EDITOR` に設定している場合，`/mnt/c/path/to/repos/.git/COMMIT_EDITMSG` を開こうとして `C:\mnt\c\path\to\repos\.git\COMMIT_EDITMSG` を開いてしまいます。当然，この状態でコミットメッセージを書いて保存しても，無関係の場所にファイルができるだけで正しくコミットされません。

```shell-session
$ git commit

Aborting commit due to empty commit message.
```

## パスを変換するラッパースクリプト

この問題への対処としては，簡単なラッパーを書くことが考えられます。以下のようなシェルスクリプトを書いて `~/bin/atom` として `$PATH` に入れておけば解決です。

```bash:~/bin/atom
#!/usr/bin/env bash

set -eu

argv=("$@")

for ((i=0; i < $#; i++))
do
	v=${argv[$i]}
	if [[ $v != -* ]]; then
		argv[$i]=$(wslpath -m $(realpath "$v"))
	fi
done

cmd.exe /C atom.cmd "${argv[@]}"
```

オプション以外の引数をファイル・ディレクトリと見なして `wslpath` コマンドでパスを変換しています。`set -e` しているので，WSL のファイルシステム（VolFs）上にあるファイルを開こうとすると，`wslpath` がパスの変換に失敗してエラーとなり，その時点で強制終了します。誤って WSL のファイルを編集してしまう事態を避けることができます。

`realpath` でパスを正規化しているのは，通常のエディタとしてターミナルから起動する場合も想定してのことです。`wslpath` は（引数に相対パスが与えられると？）シンボリックリンクを展開しません。ホームディレクトリに Windows ファイルシステム上のディレクトリへのシンボリックリンクを作っている場合，そのディレクトリをホームディレクトリからの相対パスで開こうとするとエラーになります。あらかじめ `realpath` でシンボリックリンクを展開して絶対パスに直してやることで，この問題を回避することができます。


## 参考

* [Atom 1.18 | Atom Blog](http://blog.atom.io/2017/06/13/atom-1-18.html)
* [Windows interoperability with Linux | Microsoft Docs](https://docs.microsoft.com/en-us/windows/wsl/interop)
Automatorで赤外線リモコン

クロッサム2以来いろいろ赤外線リモコンをいじっているのですが、[BitTradeOneのUSB赤外線リモコン](http://bit-trade-one.co.jp/BTOpicture/Products/005-RS/index.html)を気に入って使っています。

USB赤外線リモコンをMac mini(2010) - El CapitanのAutomatorで使えるようにしてみます。

まずccなどのcommand line toolsをインストールします。ターミナルでccを実行すると、インストールのダイアログが表示されるのでそのままインストールします。

続いてmrubyの[githubのブランチ](https://github.com/mruby/mruby)をcloneしてbuild_config.rbに以下を追加してビルドします。

```
  conf.gem :github => 'yamori813/mruby-remocon'
  conf.gem :github => 'matsumoto-r/mruby-sleep'
```

USB赤外線リモコンの制御用のスクリプトを書きます。Apple Remoteの真ん中のボタンを押すスクリプトです。cmdの信号のデータ形式は[こちら](https://qiita.com/yamori813/items/6b69f662dbc9248ca0c6)に書いてあります。

```ruby:appleremote.rb
cmd = [130, 119, 225, 32, 00]

t = Remocon.new()

if t.open then
  t.send(cmd)
  usleep 45*1000
  t.send(cmd)
  usleep 45*1000
  t.send(cmd)
end
```

Automatorのシェルスクリプトを実行に書き入れます。

![スクリーンショット 2018-07-20 16.05.21.png](https://qiita-image-store.s3.amazonaws.com/0/104066/277dcca2-8639-1d18-757f-3df92aa914ca.png)

これで保存して実行するとiTunesが起動します。

![スクリーンショット 2018-07-20 16.17.59.png](https://qiita-image-store.s3.amazonaws.com/0/104066/e394dbff-69c0-8bf2-ce6f-93c22b9eb907.png)

もちろんiTunesはクリックすれば起動するので、わざわざこんなことする必要はなくて、USB赤外線リモコンはSONY,NEC,家電協会のフォーマットに対応しているので、いろいろな応用ができるのではないかと思います。

赤外線リモコンの制御用のアプリを作っていたのですが、最近は勝手アプリが動か無いようになっているので、システムの設定を変えずにできることを試してみました。
Cocoaで複数の修飾キーを認識する

メモ程度の内容ですが・・・

最近macOSアプリ開発でCocoaを触ることがあるのでハマったところとか気づいたところを書いておきます。

## 環境

Xcode 9.4.1
Swift4
Deployment Target 10.13

## 内容

Cocoaでは `flagsChanged()` で修飾キー(ShiftとかAltとかCommand)が押された状態を取得できますが、複数キーが押された場合どうすればその状態を確認できるのだろうと少しハマりました。

## 解決方法
### 2018/07/21 修正
コメントいただきましたが、modifierFlagsがOptionSetだったので旧方法より短く書くことができます。

```swift
if event.modifierFlags.contains([.shift, .command]) {
    // 処理
}
```

### 旧方法
なんのことはない、複数キーをANDでとればいいだけでした。

```swift
if event.modifierFlags.contains(NSEvent.ModifierFlags.shift) && event.modifierFlags.contains(NSEvent.ModifierFlags.command) {
    // 処理
}
```
Linuxでもペイントは使えるんやで

## はじめに
Linuxになって、プログラミングがスムーズになったわ。
PCとして最低限の設計しかないから、好きなように開発環境整えられるし。
いやぁ、良かったよかった。

…でも、それって欲しいものがあれば自分で探して来いってことでもあるんだよね。
だから、windowsの`Microsoft Word`とか`ペイント`とかないわけでして…
まぁ、Linuxにも標準のペイントソフトはあるけど、使いにくいよね。
比べてみると、Windowsのペイントソフトがいかに優秀かわかるわ。

さて、そんなペイントソフトを入れてみますか。

## Pinta
Windowのペイントではないけれど、使いたい機能はこれで充分。

アイコンもペイントとほとんど同じだし、これで問題ないでしょ。
![Screenshot from 2018-07-20 16-01-40.png](https://qiita-image-store.s3.amazonaws.com/0/218398/28587a6b-6193-88bc-d0f8-647a3e3ab043.png)

ちなみに、入れ方は次のコマンドを入力するだけ

```
sudo add-apt-repository ppa:pinta-maintainers/pinta-stable #Pintaのレポジトリ取得
sudo apt-get update #アップデート
sudo apt-get install pinta
```

これでLinuxがより最高になったぜ！！
kotlinでif文の条件に代入式を使いたい

どういうことかというと、こういうやつ↓

```kotlin
if (val date = arguments?.getSerializable(ARG_DATE) as LocalDate) {
    ...
```

結論から言うと、できません。言語仕様がそうなので、仕方ないですね。

しかし、次のようなinline funを定義すれば、似たようなことはできます。

```kotlin
inline fun <T, R> ifNotNull(value: T?, thenPart: (T) -> R, elsePart: () -> R): R {
    return if (value != null) {
        thenPart(value)
    } else {
        elsePart()
    }
}
```

これを使えば次のように書けます。

```kotlin
val thenOrElse = ifNotNull(arguments?.getSerializable(ARG_DATE) as? LocalDate, {
    // it => LocalDate
    "then"
}, {
    "else"
})
```

then/elseパートは値を返すので、普通のif-then-else式のように使えます。

elseパートがないバージョンも定義しておけばよいと思います。

```kotlin
inline fun <T, R> ifNotNull(value: T?, thenPart: (T) -> R): R? {
    return if (value != null) {
        thenPart(value)
    } else {
        null
    }
}
```
PyCallで複数のPythonを使い分けて利用する

# はじめに

RubyからPyCallを使ってPythonのライブラリを利用しようとして少しはまったので、対処をまとめます。

# Python2系と3系が混在

この時、必要なライブラリが同じようにインストールされていれば問題ないのですが、どちらかにしか入っていないものを利用する場合、初期で使用されるPythonのバージョンが違っているとエラーになります。

# 環境変数の設定

以下のとおりENV["PYTHON"]を設定することで、使用するPythonのバージョンを指定できます。

## Python2の場合

```rb:
#!/usr/bin/env ruby

# 環境変数の設定
ENV['PYTHON'] = "/usr/bin/python"

# PyCallの読込
require 'pycall'
```

## Python3の場合

```rb:
#!/usr/bin/env ruby

# 環境変数の設定
ENV['PYTHON'] = "/usr/bin/python3"

# PyCallの読込
require 'pycall'
```

できた！
オープンロジ(openlogi)APIの入庫/出庫実績をS3にPUT

# オープンロジとは
[日々の物流業務をもっと効率的に。物流アウトソーシングサービス OPENLOGI](https://www.openlogi.com/)
> 月間出荷件数が数件〜数千件まで
固定費ゼロ・従量課金で利用できる物流アウトソーシングサービス

## OPENLOGI API
https://api.openlogi.com/doc/api.html
最新は1.4.
[Amazon MWS](https://developer.amazonservices.jp/) と比べると、 RESTful, JSON とモダンな仕様ですが、APIの種類は少ない。

# 目的
最終的にAd-hocに分析するにしろ、DB/DWHに投入してBIするにしろ、
S3に保存することでAWSの豊富なサービスとツールの恩恵を受けられるので便利です。

例えばad-hocな分析をしたければ、新しいEC2インスタンス上に簡単かつ高速にコピーできるし、[SDKは複数の言語またはプラットフォームに対応しているし](https://aws.amazon.com/jp/tools/)、Athenaを使ってしまってもよい。

**S3を制する者はAWSを制す**

また、OPENLOGI APIのレスポンスJSONのままでは大量データの高速処理に向かないため、TSVへの変換も行います。

# 設計
1. OPENLOGI APIで入庫/出庫実績をGET
2. JSONをTSVに変換
3. S3にPUT

# 準備
## 用意するもの
- `curl`
- `jq`
- `awscli` (aws configure済み)
- S3バケット

## まずは登録する（無料）
https://www.openlogi.com/
メールアドレス認証に続いて、アカウント情報を入力。
APIの利用だけなら支払い情報の登録は不要。

## アクセストークン発行
https://api.openlogi.com/console/
トークン名(クライアント名)を入力するだけで発行完了

権限管理などは無い模様だが、リクエスト元の管理を行うためにアクセストークンはクライアント毎の発行が望ましい。

# 実行

結果的にワンライナーになってしまった

- [OPENLOGI API v1.4 入庫実績API](https://api.openlogi.com/doc/api.html#入庫-入庫実績)
- [OPENLOGI API v1.4 出庫実績API](https://api.openlogi.com/doc/api.html#出庫-出庫実績)
- [cp - AWS CLI Command Reference](https://docs.aws.amazon.com/cli/latest/reference/s3/cp.html)

```
$ TOKEN=your_bearer_token
$ curl -s -H"X-Api-Version: 1.4" -H"Authorization: Bearer $TOKEN" https://api.openlogi.com/api/warehousings/stocked/YYYY/MM | jq .warehousings[] | jq '.items[]+{"stocked_at":.stocked_at}' | jq -r '[.stocked_at,.id,.name,.quantity]|@tsv' | aws s3 cp - s3://your-bucket-name/warehousings/stocked/YYYYMM
$ curl -s -H"X-Api-Version: 1.4" -H"Authorization: Bearer $TOKEN" https://api.openlogi.com/api/shipments/shipped/YYYY/MM | jq .shipments[] | jq '.items[]+{"shipped_at":.shipped_at,"company":.recipient.company}' | jq -r '[.shipped_at,.id,.name,.quantity]|@tsv' | aws s3 cp - s3://your-bucket-name/shipments/shipped/YYYYMM
```

## 確認
```
$ aws s3 cp s3://your-bucket-name/shipments/shipped/YYYY/MM/DD
YYYY-MM-DDThh:mm:ss+09:00    AA001-I000001    ほげ    1
YYYY-MM-DDThh:mm:ss+09:00    AA001-I000002    ふが    1
```
Google Spreadsheetで1:N結合風味

この記事は
===

* Google Spreadsheetで見かけだけテーブル結合ちっくにしたかったメモです

やりたいこと
===

* Google Spreadsheetで、別シートに1:N関係のデータが外部キー付きであって、それを結合して表示したい
* 複数紐づいている場合は1セルの中で適当に区切って表示してほしい

例）
---

* 元シート

| ユーザID | 氏名     |
|----------|----------|
| 1        | 山田太郎 |
| 2        | 鈴木二郎 |
| 3        | 佐藤三郎 |

* 別シート

| ユーザID | コメント           |
|----------|--------------------|
| 1        | 頑張ってください！ |
| 1        | 大ファンです！     |
| 3        | お久しぶりです！   |

* 元シートをこうしたい

| ユーザID | 氏名     | コメント                              |
|----------|----------|---------------------------------------|
| 1        | 山田太郎 | 頑張ってください！<br>---<br>大ファンです！ |
| 2        | 鈴木二郎 |                                       |
| 3        | 佐藤三郎 | お久しぶりです！                      |

やり方
===

* 元シートのコメント列に下記を記載でOK

```
=JOIN(char(10)&"---"&char(10),query('別シート'!A:C,"select C where B="&A2&" and C <> ''", false))
```

終わりに
===

* SpreadsheetでSELECT文書いた時の負け犬感は異常
Golangのポインタ渡し初心者を卒業した

# Golangのポインタ渡しに関して
ポインタはC言語を勉強したときに理解していたけどGolangでポインタ渡しを使う際に
「なぜ使うのか」
「値渡しとどう違うのか」
という部分があいまいだったので書いてみました。

## ポインタに関しては下記記事を参照
「ポインタってなんだよ」みたいな方は下記記事を読んでおくと理解しやすいかもです。
[ポインタ](https://wa3.i-3-i.info/word12814.html)
[ポインタ変数](https://wa3.i-3-i.info/word12814.html)

## まずは関数への値渡しでアドレスを出力してみる
```go:test.go
func Test(a int) {
    fmt.Println("aのアドレス(関数内)：", &a)
}

func main() {
    a := 10
    fmt.Println("aのアドレス：", &a)
    Test(a)
}

// aのアドレス： 0xc4200160f0
// aのアドレス(関数内)： 0xc4200160f8
```

表示されたaのアドレスに注目してください。
違うアドレスが出力されていますね。これはmain( )の中のaとTest( )の中のaが別物であることを表しています。
関数の引数に値渡しをした場合は、関数が実行される際に値がコピーされるからです。

## 値渡し
この関数が実行されるときに値がコピーされるという知識を踏まえてTest( )の中で変数aを変更しようとしてみます。

```go:test.go
func Test(a int) {
    a += 1
    fmt.Println("aの値(関数内)：", a)
}

func main() {
    a := 10
    fmt.Println("Test()呼び出し前のaの値：", a)
    Test(a)
    fmt.Println("Test()呼び出し後のaの値：", a)
}

// 実行結果
// Test()呼び出し前のaの値： 10
// aの値(関数内)： 11
// Test()呼び出し後のaの値： 10
```
予想通りですね。aをTest( )に渡すことによってaは11になると思いきやそれはTest( )の中だけの話でmain( )の中でもう一度aを出力すると10のままでした。
この動きがポインタ渡しを理解するときのポイントです。ではポインタ渡しを見てみましょう。


## ポインタ渡し
ポインタ渡しを理解するときは

- `fmt.Println(&a)`とやるとaのアドレスが出力されるということ
- `*a`がポインタが指し示している変数を表していること(👉がポインタで📦が変数だとすると、こういうイメージ→👉📦)

の2つを押さえておけばオッケーです。

```go:pointer.go
func Test(a *int) { //←aはint型のポインタ変数になる。👉を作ったイメージ。
    *a += 1         //aポインタが指している変数に入る数を+1する
    fmt.Println("aの値(関数内)：", *a)
}

func main() {
    a := 10
    fmt.Println("Test()呼び出し前のaの値：", a)
    
    // 呼び出しで、アドレスを渡す。
    Test(&a)
    fmt.Println("Test()呼び出し後のaの値：", a)
}
// Test()呼び出し前のaの値： 10
// aの値(関数内)： 11
// Test()呼び出し後のaの値： 11
```

先ほどの値渡しとの違いはどこでしょうか。そうです。Test( )呼び出し後のaの値です。
Test関数実行後もaが11になっていますね。
これがポインタ渡しの特徴です。値渡しと違って、Test関数実行後にも変更を保持することができます。便利ですね。

## なぜポインタ渡しを使うのか
ややこしいし、値渡しでよくねと正直値思っていたのですが、

- 値渡しと違って、間接的に参照・操作できる

- 上で見たように値渡しだと関数の引数として構造体を渡した場合に、その構造体のコピーが生成されてしまい、元の構造体に影響を与えない。ポインタ渡しだと影響を与えることができる。
- 単純にORマッパーなどのライブラリがポインタを使うので使わざるを得ない
- 大きな構造体を値渡しするとコピー処理で性能が劣化する。 ポインタ渡しの場合には固定で8バイト(64bit)/4バイト(32bit)なので性能が劣化しない。

というような理由から使うようです。

間違い等ありましたら教えていただけると嬉しいです！!

## 参考
https://www.yoheim.net/blog.php?q=20170901
https://tour.golang.org/moretypes/1
Ethernaut 「Level.1 Fallback」解答例

# Fallback

下記のコントラクトコードを見てください。
このレベルをクリアするには、

1.このコントラクトのownershipを自分にする
2.コントラクトの残高を０にする

回答に助けになるヒント

・ABIとやり取りする時にEtherを送る方法
・ABIの外部にEtherを送る方法
・wei/etherとの変換
・Fallbackメソッド

## Sources

```.js
pragma solidity ^0.4.18;

import 'zeppelin-solidity/contracts/ownership/Ownable.sol';

contract Fallback is Ownable {

  mapping(address => uint) public contributions;

  function Fallback() public {
    contributions[msg.sender] = 1000 * (1 ether);
  }

  function contribute() public payable {
    require(msg.value < 0.001 ether);
    contributions[msg.sender] += msg.value;
    if(contributions[msg.sender] > contributions[owner]) {
      owner = msg.sender;
    }
  }

  function getContribution() public view returns (uint) {
    return contributions[msg.sender];
  }

  function withdraw() public onlyOwner {
    owner.transfer(this.balance);
  }

  function() payable public {
    require(msg.value > 0 && contributions[msg.sender] > 0);
    owner = msg.sender;
  }
}
```

## 解答
クリアする条件と出されたヒントから注目する。
contract sourcesからは、ownershipを変更する「owner = msg.sender」
payableを動かすには、contractにEtherを送信する
```msg.value```は、送信されたEtherの値
```msg.sender```は、コントラクトを実行したPlayerのアドレス（つまり自分）
となり、```msg.sender```のアドレスを```owner```に入れればownershipが取れることになります
ownershipが取れてしまえば、```withdraw```メソッドにコントラクトのBalanceを全て自分に転送するとあるので実行できればこのレベルはクリアしたことになります。

まずはFallbackメソッドにある下記の条件をクリアする為、```contitribute[msg.sender]```を０ではなくしてしまいましょう。

```.js
require(msg.value > 0 && contributions[msg.sender] > 0);
```
contributeメソッドに```contribute[msg.sender]```に送ったEtherの値を加算するコードがありますが、条件として```０.００１ Ether```未満というものがあります。
０ではなくすれば良い為、```0.0001 Ether```を送るようにしてみます。

```.js
contract.contribute({value: toWei(0.0001,"ether"), from: player})
```
Etherを送る場合Valueの値はWei換算の為、EtherをWeiに変換するコードを記入しています。
このコードを実行することで```contribute```に```0.0001 Ether```送ることができます。

次のコマンドで自分の```contributions```の値を確認してみましょう

```.js
await contract.getContribution()

t {s: 1, e: 14, c: Array(1)}
  c:[1]
  e:14
  s:1
  __proto__:Object
```

自分の```contributions```が０ではなくなれば、ｃontractのsendTransactionを使い0.0001のEtherを送り（０以上ならOK）、Ownerを取得します。
メソッド名のないFallbackメソッドの場合は、sendTransactionを使います。

```.js
contract.sendTransaction({ from: player, to: instance, value: toWei(0.0001, "ether")})
```

ownershipが取得できたかコントラクトのオーナーを確認します。

```.js
await contract.owner()
"(自分のアドレス)"
```

Ownerを取得した後は、contractの残高を取得する```withdraw()```メソッドを実行します。

```.js
contract.withdraw()
```

以上で「Level.1 Fallback」をクリアできます。
解答に導く順序についてはこれが正しいというわけではないのですが、クリア条件を満たすことはできると思います。
コントラクトのメソッドに直接Etherを送る方法については色々と調べさせていただきました。
Thymeleaf3でMap<String, Object>形式から表を出力する

# 目的
Thymeleafで出力する項目が可変の表(table)を出力したいときに利用します。

## 実行環境
SpringBoot 2.0.3.RELEASE ( Thymeleaf 3.0.9.RELEASE )

## Controllerと出力するデータ

Controllerからは、Map<String, Object>形式のものを渡します。ただしMapの出力順序を必ず定めたいので、LinkedHashMapを使っています。

```java
package alphapz.thymeleaf.controller;


import java.util.LinkedHashMap;
import java.util.Map;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.servlet.ModelAndView;

/**
 * @author A-pZ
 *
 */
@Controller
public class MatrixController {
	@GetMapping("")
	public ModelAndView display(ModelAndView mnv) {

		mnv.addObject("data", matrix);
		mnv.setViewName("index");

		return mnv;
	}

	private Map<String, Object> matrix = new LinkedHashMap<String, Object>() {{
		put("id","ID001");
		put("name","username");
		put("address","USER_ADDRESS");
	}};
}
```

## View (Template)

dataの名前で先程のMapが格納されているので、Collection系を繰り返し表示する th:each で指定します。

```html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<body>
	<table>
		<thead class="thead-dark">
			<tr>
				<th th:each="entry : ${data}" th:text="${entry.key}"></th>
			</tr>
		</thead>
		<tbody>
			<tr>
				<td th:each="entry : ${data}" th:text="${entry.value}"></td>
			</tr>
		</tbody>
	</table>
</body>
</html>
```

th:each で取り出した要素は、EntrySet なので、キー名は key、値は value から取得できます。
Javaのfor文

for文というのは繰り返しの構文です。for文を使いこなせれば、表やたくさんの行のある大きなデータも取り扱うことができるようになります。

```java:書き方
for (初期化式; 条件式; 更新式) {
     処理内容;
}
```

サンプルコード：

```java:ForSample.java
public class ForSample {

   public static void main(String args[]) {

      for(int x = 10; x < 20; x = x + 1) {

         //xの値を表示
         System.out.println("xの値 : " + x );

      }
   }
}
```

```text:結果
xの値 : 10
xの値 : 11
xの値 : 12
xの値 : 13
xの値 : 14
xの値 : 15
xの値 : 16
xの値 : 17
xの値 : 18
xの値 : 19
```
DockerCE18.06で使えるBuildKitを使おう

# 概要

2018/07/19にリリースされたDockerの18.06バージョンでは、BuildKitというものが実験的に統合されて使えるようになり、
ビルドが30倍速くなる（こともある）！　とDockerのMeetupで教えてもらったので、Docker初心者がそれを試す手がかりとして、これを残します。


紹介されていたのは、こちらの資料です。
[DockerCon参加報告 (`docker build`が30倍以上速くなる話など)](https://www.slideshare.net/AkihiroSuda/dockercon-docker-build30)


# なぜ速くなるのか

ものすごく簡単に言ってしまうと、２点だと思います。

1. 並列処理するから
2. キャッシュを有効活用するから

これまでマルチステージでDockerfileを書いていても、上から順に、シーケンシャルにしか処理してくれませんでした。
それを依存関係を加味して、並列で実行することで処理時間を短縮しよう、と。

また、mavenやgoなどで使ったパッケージマネージャのリソース、aptやyumのキャッシュを有効に使うことで処理時間を短縮しよう、というアプローチのように見えます。


キャッシュを使う RUN --mountは、今のDockerfileを書き換えないとできませんが、並列ビルドは **今お使いのDockerfile そのままで使える**、と言われたら魅力的ではありませんか？



# 環境準備

## Dockerのバージョンアップ

Dockerのバージョンを18.06にします。
ちゃんと18.06になっているか、コマンドでも確認しておきましょう。

```shell

docker --version
```

![1.png](https://qiita-image-store.s3.amazonaws.com/0/111676/d316e760-bda5-9817-619f-d2919ad7d1d3.png)


## 環境変数の設定

https://www.slideshare.net/AkihiroSuda/dockercon-docker-build30/20

スライドにあるように、環境変数を設定します。

```shell
export DOCKER_BUILDKIT=1
```

## experimentalを有効にする。

`実験的に統合`ということなので、experientalを有効にします。

### 有効になっているかどうかの確認

```shell
docker version
```
と入力して、表示された内容を確認します。

![2.png](https://qiita-image-store.s3.amazonaws.com/0/111676/9dfe6084-9de4-9c2e-49f2-fe8332da3b73.png)

ServerのところのExperimentalがfalseになっていたら、有効になっていません。次に進みましょう。

### Experimentalを有効にする

/etc/docker/daemon.json　を以下の内容で作成します。

```json
{
    "experimental": true
}
```

/etc/dockerの所有者が誰になっているかを確認して、必要であればsudoするなりして編集しましょう。
aws ec2でubuntu環境でDockerを入れて試していますが、ここはrootになっていました。

編集が終ったらdockerを再起動します。

```shell
sudo service docker restart
```

### 有効になっているか確認

再度確認してみます。

```shell
docker version
```

![3.png](https://qiita-image-store.s3.amazonaws.com/0/111676/93250c18-a33b-c68f-f1a4-656c6f39e204.png)

Experimentalがtrueになっていることを確認してください。

# 普通にdocker build

今まで白い文字に、たまにエラーや警告の赤い文字だったビルド画面が、青っぽい画面になりました。

![4.png](https://qiita-image-store.s3.amazonaws.com/0/111676/3b8ce7bf-7f08-b664-397e-fd81f858adf3.png)

全く同じDockerfileを、DOCKER_BUILDKIT=0にしてやってみると、こんな感じのものです。

![5.png](https://qiita-image-store.s3.amazonaws.com/0/111676/74200209-7fe4-6e21-05e5-109d5a3303ef.png)

単純なDockerfileだったため、３０倍！というほど顕著な改善は見られませんでしたが、
「今のままそのままで、速くなる」というのであれば、やらない手はないです！

# トラブルシュート

> buildkit not supported by daemon

こんなエラーがdocker buildを実行したときに返された方は、docker versionでexperimentalがtrueになっているか、有効になっているかをご確認ください。
Experimentalがfalseだと、このエラーになります。

なお、ClientとServerの両方にExperimentalがありますが、設定するのはServerの方でした。



# 情報入手元

- [Docker Meetup Tokyo #24 (DockerCon 2018報告会)](https://dockerjp.connpass.com/event/93140/)

Dockerステッカー　ありがたく頂戴いたしました。
K-meansとK-means++

# K-meansとは

大変単純なアルゴリズム。
まず、クラスターの中心を初期化して適当に置きます

```math
\mu^{(0)} = [\mu_1^{(0)}, ...., \mu_k^{(0)}]
```
そして、収束するまで、
- 各サンプルから一番近い中心を選ぶ

```math
z_i \leftarrow arg \min_{j \in {1,...,k}} || x_i - \mu_j^{(t-1)}||_2^2
```
-割り当てられたデータサンプルの中で平均をとり、クラスタの中心を更新する

```math
\mu_j^{(t)} \leftarrow \frac{1}{n_j}\sum_{i:z_i = j} x_i
```
の2つを繰り返します。一番簡単なやつ。

# KKZ法

次に、KKZ法は少しk-meansを改良したやつになります。「クラスタの中心同士は離れているべきでしょ」という考え方に基づいています。

$Step1$ ランダムにクラスタの中心の初期値を1つ選びます。
$Step2$ それぞれの点から一番近いクラスタの中心との距離を取ります。
$Step3$ $Step2$でとった距離の中で一番最大なサンプルを新しいクラスタの中心とします。

  ($Step2$から$Step4$をクラスタの中心の数がk個になるまで続けます。)
ただ、このアルゴリズムは外れ値があるとうまく動きません。

# K-means++法

今回は、「一番距離が大きいもの」が次の点に選ばれるのではなくて、「距離が大きいものが確率的に選ばれるようにする」というのがポイントです。

$Step1$ ランダムにクラスタの中心の初期値を1つ選びます。
$Step2$ それぞれの点から一番近いクラスタの中心との距離$D(x)$を取ります。
$Step3$ 重み付き確率分布を$\phi(x) = \frac{D(x_i)}{\sum_k D(x_k)}$とし、代表ベクトルをランダムに選ぶ。
  ($Step2$から$Step4$をクラスタの中心の数がk個になるまで続けます。)
CentOSでyum updateしたらlibgcc_s.so.1がないとエラーが出て対処


# 問題

```yum update``` したら

```
There was a problem importing one of the Python modules
required to run yum. The error leading to this problem was:

   libgcc_s.so.1: cannot open shared object file: No such file or directory

Please install a package which provides this module, or
verify that the module is installed correctly.
```

というのが出るようになってしまった。
以降、```yum install``` も curlやwgetもできない状態になってしまった。
（以下のように表示される）

```
$ wget example.com
wget: error while loading shared libraries: libgcc_s.so.1: cannot open shared object file: No such file or directory
```

# 対処

yumが使えないので以下から対応するrpmファイルを得る。

https://rpmfind.net/linux/rpm2html/search.php?query=libgcc

wgetも使えないのでscpで転送した。

その後

```
$ sudo rpm -ivh libgcc-4.4.7-23.el6.i686.rpm
```

で直った。
[Android Studio] Logcatのマテリアルカラーテーマ

![1_90Z9yk4rWds8CupDwCo8Rw.png](https://qiita-image-store.s3.amazonaws.com/0/251603/cc6d4d18-e763-67de-b153-7654fa4fe8ff.png)

Preferences → Editor → Colors & Fonts → Android Logcatをクリックして、下記の通り色を変更する

Assert: #BA68C8
Debug: #2196F3
Error: #F44336
Info: #4CAF50
Verbose: #BBBBBB
Warning: #FF9800
Agile Japan 2018 に参加して感じたこと

# この記事について
2018/07/19に開催されたAgile Japan 2018
参加して私が感じたことをまとめます。

# 自分の中のキーワードは「チーム」と「人」

私が思うに、アジャイルのプラクティスはチームにフォーカスを当てている印象があります。
チームのあり方、強いチーム、というテーマのセッションがいくつもありました。
チームの中の人がどれだけ成長し、成果を挙げられるチームを作っていけるか、ということも重要だと感じています。


# チームの観点から見たモブプログラミング
基調講演のWoody Zuillさんの講演
印象に残った言葉は、**Question Queue Time**、**Flow of the work**です。

### Question Queue Time
> キューがたまると、必ずマルチタスクになってしまう
> 質問の待ち時間に別の作業を行うことになるため
> チーム全員で作業を行えば、Questionの回答はすぐに得られる（はず）のでQueueがない
> これによって、チームが進める仕事のフローが１本できれいにながれるようになる

### Flow of the work
とすると、その１本をいかに速く流せるか、というのがポイントになりそうで、そこで登場するのが**フロー状態**
> フロー状態は心理学者のミハイ・チクセントミハイが提唱したもの。
> https://ja.wikipedia.org/wiki/%E3%83%95%E3%83%AD%E3%83%BC_(%E5%BF%83%E7%90%86%E5%AD%A6)

個人のフロー状態は、スポーツ選手の例などで最近良く耳にしますね。
チームのフロー状態という考え方が、私にとっては新鮮だでしたが、けど、その事例にロックバンドを出されたときに、ストンと腹に落ちました。
互いに作業しあって協同で作業を進めていく。この「流れ」を「フロー状態」にしていこう、というのがモブプログラミングの効果なのかな、という理解をしました。

# 人月見積りが阻害要因ではないか？
モブプログラミングの話をするときによくある質問は「みんなで同じことをすることで生産性は落ちるのではないか？」ということだそうです。
確かに、効率重視で考えると、作業分担してチーム内で並行作業するほうが効率が良いように感じます。SIerの私からすると、その点でモブプログラミングに疑問が浮かぶのは確かです。

その違和感を引き起こす原因は、「人月での見積り」なのではないか、と思いました。

人月見積りだと、一人当たりの時間当たり成果物量で考えるので、並行に作業して一気に片付けていくことが基本形になります。工場で一日あたりに製造できる製品の量、というのが人月見積りのモデルになっていると思っているのですが、ソフトウェアは毎回やることが異なるので、そうそう数字どおりにはいかないですよね。

## 効率よりも効果
モブプログラミングは、効率というよりは効果を求めていくものなのかな、と感じました。
・チーム全員参加で知識を共有する
・感動を共有する
・チームとして、達成できる成果が大きくなっていく
・もちろんQueueも発生しない点での効率の良さもある

効果的なアウトプットをタイムリーに出せるチームというのがアジャイルなチームだと思うので、その達成の方法としてモブプログラミングは効果的だと感じました。

# おわりに
やはり、チームや人をちゃんと見たプラクティスになっているな、という印象で、自分の中のキーワードに戻ったところで、この記事を締めくくります。
あくまで主観なので、ご意見などもいただけると幸いです。

Agile Japan 2018についてはこちらを参照。
https://www.agilejapan.org/index.html
「git new」コマンドをでっち上げる（Windowsでgitのサブコマンドを作る）

自分の場合、新規レポジトリを作る際、いつも定番的に実行しなければいけない作業がある

* `git init`
* 最初に空コミット作成
* 改行コード変換の無効設定
* 日本語ファイル名はそのまま表示させる
* メールアドレス等の設定

次の記事によると、「`git-XXXX`」という実行ファイルを作ると、`git XXXX` というサブコマンドを作成できるようだ。

* [便利な「git-サブコマンド」を作成する - Qiita](https://qiita.com/b4b4r07/items/6b76a5f969231e5e9748)

Windowsなので `git-new.cmd` というバッチファイルを作成して、自分の定番初期化作業を一括化してみよう。

```git-new.cmd
git init 
git commit -m "empty" --allow-empty
echo "* -text" > .gitattributes
git add .gitattributes 
git commit -m "Add .gitattributes as autocrlf=false"
git config --local core.quotepath false
git config --local user.email zetamatta@example.com 
git config --local user.name  zetamatta
```

テスト

```shell-session
$ git new
git: 'new' is not a git command. See 'git --help'.

Did you mean this?
        notes
exit status 1
```

**だめでした！**

EXEなどの実行ファイルでないとダメなのか。でも、スクリプトレベルのものをいちいち実行ファイル作るのは面倒すぎるなぁ。Linux だとシェルスクリプトが大丈夫なのに…**あ**

```git-new
#!/bin/sh

if [ ! -e .git ] ; then
    git init 
    git commit -m "empty" --allow-empty
fi
if [ ! -e .gitattributes ] ; then
    echo "* -text" > .gitattributes
    git add .gitattributes 
    git commit -m "Add .gitattributes as autocrlf=false"
fi
git config --local core.quotepath false
git config --local user.email zetamatta@example.com 
git config --local user.name  zetamatta
```

(最終版なので、いろいろ機能追加してますが、気にしないでください）

Git for Windows は MSYS ベースで動作しているので、普通に「`git-new`」という拡張子無しのテキストファイルを %PATH% 上において、シェルスクリプトを書けば Ok でした！

```shell-session
$ git new
Initialized empty Git repository in C:/Users/Hayama/Share/cmds/.git/
[master (root-commit) 6b0d022] empty
[master f9ca464] Add .gitattributes as autocrlf=false
 1 file changed, 1 insertion(+)
 create mode 100644 .gitattributes
```

以上
DOMException: The play() request was interrupted by a call to pause()が出たとき

<video>タグや<audio>タグを使った時に、
[Uncaught (in promise) DOMException: The play() request was interrupted by a call to pause()]といった
コンソールエラーが出る場合がありまして。

その際の対処方法の備忘録になります。

ちなみにコンソールに一緒に出てくるURLのドキュメントは以下
>
DOMException: The play() request was interrupted
https://developers.google.com/web/updates/2017/06/play-request-was-interrupted

これ、chromeのみでfirefoxとかsafariは起こらないんですね。。

##状況
・videoタグを設置して動画再生を行なっている
・chromeでブラウジングしている
・カルーセルスライダーの中に動画が入っている

##やりたかったこと
・cookie判定して有無によってスライドを取り除いたり表示したり

##起こった現象
・slickメソッドのslickRemoveを使ってスライドを削除しようとしたら、
The play() request was interrupted by a call to pause()のエラーが出て動画の
再生が起こらなくなった

##参考にしたサイト

>
Audio(Video)タグで"play() request was interrupted …"とかいうエラーが出てきたよ
https://foolean.net/p/679

結果このサイトの情報が解決に繋がったものの、
###・動画に対するplay()を投げているのがfor文内にある

という状況から、そのままsetTimeoutで挟んでもundefinedになってplay()ができない。
だったため、以下のサイトも参考に。
>
for文内でsetTimeoutを使う場合の変数のスコープ
https://qiita.com/yam_ada/items/2867985bcb6b77288548

クロージャにしないとiの参照先は常に一緒になっちゃうんだなぁと理解。


結論としては、play()してる箇所をsetTimeoutで挟んであげるのがよいと。

```
movies.play();
↓

setTimeout(function(){
  movies.play();
},1000);

↓for文の場合はクロージャで

(function(pram){
  setTimeout(function(){
    movies[pram].play();
  }, pram * 1000);
})(i);
```
書き方めちゃ適当ですみません。

日々勉強。
C#のDateTimeOffset使い方備忘録

#やりたいこと
- ローカル時間から別のタイムゾーンの時間にしたい
 - 例：日本時間（UTC+9）からニューヨーク（UTC-4）にしたい（サマータイムは考慮しない）

#コード
※変数のデータ型はわかりやすくするため型推論（var）は使ってません

```Program.cs
// UTC+XをTimeSpan型にする（今回はUTC-4）
TimeSpan userOffset = new TimeSpan(-4, 0, 0); // 時、分、秒

// 今のローカル時間（日本時間）を取得
// ここでDateTimeOffsetを使うのは、
// DateTimeだと時差情報がオブジェクトに含まれていないため
DateTimeOffset localTime = DateTimeOffset.Now;

// 一度UTC（標準時間）に変換する
// UtcDateTimeプロパティではDateTimeが取得されるため、またDateTimeOffsetにする
DateTimeOffset utcTime = new DateTimeOffset(localTime.UtcDateTime, TimeSpan.Zero);

// 取得したUTCから時差の分ずらす
DateTime targetTime = utcTime.ToOffset(userOffset);

// 表示
Console.Write(targetTime.ToString("yyyy/MM/dd HH:mm:ss"));
```

もし、ローカル時間（日本）が 2018/07/20 11:30:00 だとすると、
結果は 2018/07/19 22:30:00 となります。

#さいごに
意外と頭がこんがらがって難しかった。
サマータイムは考えたくない。
Ansible で Route53 を操作する

## Ansible で Route53 を操作する
Route53 は便利なんだけど、誰がいつ操作したかが見えないので、Rundeck で Ansible Playbook を実行し、Route53 を操作してみる。

Playbook は、Rundeck の Ansible Playbook Inline を使って管理する。

## Playbook を書く
### レコード追加
`${option.hogehoge}` は、Rundeck の Job に設定する Option 設定。
Proxy 環境じゃなければ、`environment` は不要。

```yaml:
---
#
# Route53 レコード追加
#
- hosts: localhost
  gather_facts: no
  connection: local
  tasks:
    - name: Route53 Add Record
      route53:
        state: present
        zone: ${option.zone_name}
        record: ${option.record_name}
        type: ${option.dns_type}
        ttl: ${option.ttl_sec}
        value: ${option.set_value}
        wait: yes
      register: this_result
      environment:
        HTTPS_PROXY: https://px.hoge.com:8080/
        HTTP_PROXY: http://px.hoge.com:8080/
    - debug: var=this_result
```

### レコード削除
レコード追加と同じ。`state` が `absent` になっているだけ。

```yaml:
---
#
# Route53 レコード削除
#
- hosts: localhost
  gather_facts: no
  connection: local
  tasks:
    - name: Route53 Delete Record
      route53:
        state: absent
        zone: ${option.zone_name}
        record: ${option.record_name}
        type: ${option.dns_type}
        ttl: ${option.ttl_sec}
        value: ${option.set_value}
      register: this_result
      environment:
        HTTPS_PROXY: https://px.hoge.com:8080/
        HTTP_PROXY: http://px.hoge.com:8080/
    - debug: var=this_result
```

### レコード詳細
取得の際は、`ttl` や `value` を入れなくても実行可能。

```yaml:
---
#
# Route53 レコード情報取得
#
- hosts: localhost
  gather_facts: no
  connection: local
  tasks:
    - name: Route53 Get Record
      route53:
        state: get
        zone: ${option.zone_name}
        record: ${option.record_name}
        type: ${option.dns_type}
      register: this_record
      environment:
        HTTPS_PROXY: https://px.hoge.com:8080/
        HTTP_PROXY: http://px.hoge.com:8080/
    - debug: var=this_record
```

### Rundeck の設定
誰が操作したかが分かるように、Job の成功/失敗の通知は行うようにしよう。他はお好みで。

## 仲間募集中
[弊社](https://www.nittsu-infosys.com/)ではエンジニアを募集中です。インフラからアプリ、ユーザサポートまで幅広く業務を行ってます。
https://www.nittsu-infosys.com/recruit/2019/index.html
react native + algolia search 実装

###react native + algolia search 実装

##algoliaに登録、インデックスの作成
[algolia.com](https://www.algolia.com/)から、アカウント作成。
必要なindexを作成する。dashboard画面にいけたら完了。
左のメニューからapi keysに移動し、値を控える。

##npm install

```
npm install --save algoliasearch 
```

##使用方法

これは自分のやり方なのですが、以前[firebaseの記事](https://qiita.com/janus_wel/items/4892e404d9a81b8fd118)にあったやり方を参考にさせていただいています。

```algolia.js

import algoliasearch from 'algoliasearch';
import CONFIG from './config';
 
const algolia = algoliasearch(
	CONFIG.appID,
	CONFIG.appKey
); 

export default algolia;

```

```config.js
export default {
	appID:'/*控えた値*/',
	appKey:'/*控えた値*/'
}
```
<br />
コンポーネント側

```component.js
import algolia from 'algolia.js';

.
.
.

const index_user = algolia.initIndex('user');

.
.
.

<TextInput
    style={styles.searchBox} 
    clearButtonMode='always' 
    placeholder='検索'
    underlineColorAndroid='rgba(0,0,0,0)'
    onSubmitEditing={(event)=>{
      index_user.search({
    	 query:event.nativeEvent.text,
      },(err,content)=>{
          console.log(content.hits);/*content.hitsが検索結果*/
      });
     }} />

```


もっと詳しいリファレンスは[公式ページ](https://www.algolia.com/doc/api-reference/api-methods/search/)を見てください。
Jupyterのセルにデフォルトで行番号を表示

# Jupyterのセルにデフォルトで行番号を表示

僕は Jupyter Notebook を愛用しているのですが、セルの行番号を表示させるのにいちいちコマンドを入力して表示させるが嫌になったのでデフォルトで設定してみました。

## 動作
以下はipynbを新規作成した画面ですが、既に行番号が表示されているのがわかると思います。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/195174/b948eafe-55f1-8cac-ac76-0fd0aa39b65d.png)

そして、新しいセルを作成しても行番号は表示されたままです。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/195174/e9a773f1-3677-f692-59b5-96c0f4603064.png)

なお、もちろん一度ファイルを閉じ、jupyter-notebook を再起動しても再び行番号が表示されます。


## 環境
- Ubuntu 16.04 LTS
- Python3.5.2
- jupyter 4.4.4
- jupyter-notebook 5.6.0


## コード
やることは簡単で以下のコードを `~/.jupyter/custom/custom.js` に追記するだけです。
※ `~/.jupyter/custom` のファイルやディレクトリが無い方は以下のコマンドで作成し、新規 `custom.js` ファイルに書き込んでください。
※ ちなみにpyenv-virtualenvを使っている人の`.jupyter/`の場所は`~/.pyenv/versions/<your-version>/etc/jupyter/`です。
※2020/01/09追記 : `pyenv-virtualenv` 使っている方の例としては `pyenv install 3.6.8` によってバージョン3.6.8を入れており、`pyenv virtualenv 3.6.8 sample-env` により`sample-env`という仮想環境を構築した場合、`custom.js`を記述するべきPATHは `~/.pyenv/versions/3.6.8/etc/jupyter/custom/custom.js` になります。仮想環境名の`sample-env`下ではなく`3.6.8`下であることに注意してください。ここでもフォルダがなければ作成してください。


```:console
$ mkdir -p ~/.jupyter/custom
```
```javascript:custom.js
// custom.js
//--------------------------------------------------------------------------------
// Display line numbers in code cell by default
//--------------------------------------------------------------------------------

var cell = Jupyter.notebook.get_selected_cell();
var config = cell.config;
var patch = {
  CodeCell:{
    cm_config:{lineNumbers:true}
  }
}
config.update(patch)
```

## 参考

- https://stackoverflow.com/questions/20197471/how-to-display-line-numbers-in-ipython-notebook-code-cell-by-default
- https://stackoverflow.com/a/29916445/9316234
[Android] カスタムToast

デフォルトのToast：
<pre>
Context context = getApplicationContext();
CharSequence text = "トーストを表示";
int duration = Toast.LENGTH_SHORT;

Toast toast = Toast.makeText(context, text, duration);
toast.show();
</pre>
![android_android-toast_01.png](https://qiita-image-store.s3.amazonaws.com/0/251603/f2aa2961-af0c-4989-4492-7716d697fa7c.png)


カスタムToast:
![1_xRGylM8wqFjq7IUxJOJbcQ.png](https://qiita-image-store.s3.amazonaws.com/0/251603/d37b6a85-acf8-90ed-6258-5061278a525c.png)

ライブラリ名：FancyToast-Android
リンク：https://github.com/Shashank02051997/FancyToast-Android

ライブラリを取り込み方：
${module}/build.gradleに下記を追記する。

<pre>
dependencies {
	...
	compile 'com.github.Shashank02051997:FancyToast-Android:0.1.3'
}
</pre>

使い方：

サンプルコード：
<pre>
FancyToast.makeText(this,"Hello World !",FancyToast.LENGTH_LONG,FancyToast.DEFAULT,true);
</pre>
Vim Ale で Docker 内のコマンド実行

Lint 用のコマンド （ここでは flake8） の実行パスが設定できるので、そこに登録してあげれば良い

```vim:~/.vimrc
let g:ale_python_flake8_executable = 'bin/flake8'
```

```bash:bin/flake8
#!/bin/bash

docker-compose exec web flake8 $@
```

Virtualenv の場合も、これで行ける気が

https://github.com/w0rp/ale/blob/master/doc/ale-python.txt
react nativeのTips(メモ)

#react nativeのTips(メモ)
##FlatListでマルチカラムを実現したい。
<br />
属性にnumColumnsを持たせたあげる。

```example.js
<FlatList ref={(ref)=>{this.fList = ref;}} style={styles.listView} numColumns={3} execData={ex} data={ex} keyExtractor={(item, index) => item.ex} renderItem={this._renderItem} />

```

個人的には子要素styleにflex:1を持たせたあげるときれいになると思う。

こんな感じ

![S__111812663.jpg](https://qiita-image-store.s3.amazonaws.com/0/260113/e7e6e365-cdcb-9179-b505-ffc8d0511011.jpeg)  

##react navigationでheaderのボタンで画面遷移したい。  

navigation optionにnavigation引数を持たせる。

```example.js
navigationOptions: ({ navigation })=>({
  header: <View style={{backgroundColor:'#222'}}>
    	    <TouchableOpacity style={{alignSelf: 'flex-start',marginLeft:10,}} onPress={()=>{navigation.goBack()}}>
    	      <Icon color='#FFF' name={'chevron-left'} size={35} />
    	    </TouchableOpacity>
    	  </View>,
		 })

```

  
以下、随時追加していきます。
Linux firewalldでポート開放する方法（RHEL/CentOS7系） 

#ファイアウォールとは

>ファイアウォールとは防火壁のことだが、コンピュータネットワーク関連では、ネットワークの結節点となる場所に設けて、コンピュータセキュリティ上の理由、あるいはその他の理由により「通過させてはいけない通信」を阻止するシステムを指す。(引用元：Wikipedia)

RHEL/CentOS 7系ではfirewalldがデフォルトになっており、iptableとの共存はできない。（firewalldを無効化し、iptableを使用することは可能）

# サービスの起動と停止

```サービス起動.
 # systemctl start firewalld
```
```サービス停止.
 # systemctl stop firewalld
```
```サービス確認.
 # systemctl status firewalld
```
もしくは

```サービス確認.
 # firewall-cmd --state
running
```

# ポート追加と削除
```ポート追加.
 # firewall-cmd --add-port=80/tcp --zone=public --permanent
```
永続的な設定にするため--permanentを付加。
付加せずに設定した場合、再起動で設定前の状態に戻ってしまうので注意。

```ポート削除.
 # firewall-cmd --remove-port=80/tcp --zone=public --permanent
```
# 設定の有効化
```設定確認.
 # firewall-cmd --reload
```
# 設定状態の確認
```設定確認.
 # firewall-cmd --list-all
```
[Android] カスタムダイアログ

ダイアログは、ユーザーによる意思決定や追加情報の入力用に表示される小さなウィンドウです。 ダイアログは全画面に表示されることはなく、通常はユーザーが処理を続ける前にアクションを起こす必要があるモーダル イベントに使用されます。

![dialogs.png](https://qiita-image-store.s3.amazonaws.com/0/251603/10b6fa38-c4c5-da1d-f56b-ebc22887a3ba.png)

デフォルトダイアログより見た目が良いのカスタムダイアログのライブラリを紹介します。
ライブラリ名：Sweet Alert Dialog
リンク：https://github.com/pedant/sweet-alert-dialog

ライブラリを取り込み方：
${module}/build.gradleに下記を追記する。
<pre>
repositories {
    mavenCentral()
}

dependencies {
    compile 'cn.pedant.sweetalert:library:1.3'
}
</pre>

使い方：
メッセージのみ：
<pre>
new SweetAlertDialog(this)
    .setTitleText("メッセージです。")
    .show();
</pre>

メッセージとタイトル：
<pre>
new SweetAlertDialog(this)
    .setTitleText("タイトル")
    .setContentText("メッセージです。")
    .show();
</pre>

エラーメッセージ：
<pre>
new SweetAlertDialog(this, SweetAlertDialog.ERROR_TYPE)
    .setTitleText("エラー")
    .setContentText("メッセージです。")
    .show();
</pre>

メッセージとアイコン：
<pre>
new SweetAlertDialog(this, SweetAlertDialog.CUSTOM_IMAGE_TYPE)
    .setTitleText("タイトル")
    .setContentText("メッセージです。")
    .setCustomImage(R.drawable.アイコン)
    .show();
</pre>
zshでも作業手順書からべた書きパスワードをなくしたい！！

すごくいい記事だな〜と思ったのですが、zshで動かなかったのでzsh版です。

[Linux 作業手順書からべた書きパスワードをなくすシンプルなアイディア](https://qiita.com/ktooi/items/ba156bb1848c31f04949)

## 結論
zshのreadにはpオプションがないみたい。

**TOKEN?** が変数宣言部分になります。

```console
read -s 'TOKEN?tokenを入れてください>'
tokenを入れてください>
echo $TOKEN
hoge
```
AWS EC2にGITのリポジトリを作ってSouceTreeからSSHでアクセスする

#やりたいこと
GitのリモートリポジトリをEC2上に構築したかった。
アパッチは使っていないし、SSHで鍵認証のアクセスも。
実際EC2側の準備はすぐに済んだのだが、WindowsのGitからSSHしに行くところでかなりはまった

自分用の手順書みたいなものなので、
環境次第で動かないことはザラだと思いますが、
同じように困っている人の一助になれば幸いです。

#EC2側の準備
まずはGit用のユーザーを作成して、
ホームディレクトリにGitリポジトリを置くディレクトリを作る 
※ユーザー作成後は全てGit用ユーザーでコマンドを実行すること

```bash
useradd gituser
passwd gituser

su gituser

#リポジトリを置くディレクトリ名はhoge.gitにする慣例があるとかないとか
mkdir /home/giuser/test.git 
cd /home/giuser/test.git

#--bare を付けるとワークディレクトリを持たない.gitのみのリポジトリになる
#プッシュ先のリモートリポジトリとして作成する場合は基本的には--bareを付ける 
git init --bare 
```
これでGitの準備はOK
次はSSH鍵を作る

```bash
 ssh-keygen -t rsa
```
このコマンド入力後、パスフレーズの入力を求められるが
面倒なので入力せずエンターでパスする。
すると、
```/home/gituser/.ssh/id_rsa```
=>秘密鍵（クライアントで使うやつ）
```/home/gituser/.ssh/id_rsa.pub```
=>公開鍵（サーバーに置いておくやつ）

の二つのファイルが作られる

EC2のCentosのインスタンスでは公開鍵は
/home/username/.ssh/authorized_keys
というファイル名で保存される必要があるので、
そのようにするのと、
鍵関係のパーミッションは規定が決まっているのでそちらも変更する

```bash
mv /home/gituser/.ssh/id_rsa.pub /home/gituser/.ssh/authorized_keys
chmod 700 /home/gituser/.ssh/
chmod 600 /home/gituser/.ssh/authorized_keys
```

ここまででEC2側の設定は終わり。

#クライアント側の設定

クライアント側ではGitに秘密鍵の場所を設定する必要がある
SouceTreeではPutty及びPuttyKeygen、pagentなどを使った
SSH接続が推奨されているようであるが、

私の環境ではなぜか鍵の認証がうまくいかなかった・・・・

なので、PuttyではなくOpenSSHを使用してSSH接続をする。

気が向いたらスクショをあげるが、今は箇条書きで

・SSHクライアントPuttyからOpenSSHに変更する
・GitクライアントをSouceTree組み込みのものでなく、システムで使用しているものに変更
＝＞Windows用Git単体でインストールしておく
　　Windows用GitにはOpenSSHが組み込まれている。
・C:\Program Files\Git\etc\sshみたいな感じのディレクトリがあるはず
　ここのssh_configというファイルを下記の様に編集または追記

```
Host　xxx.xxx.xxx.xxx 接続先　
   HostName xxx.xxx.xxx.xxx ここも接続先
   Port 22 SSHポート番号
   User gituser SSHログインユーザー
   IdentityFile C:\path\to\key 公開鍵へのパス
```
ソースツリーからでも、GitBashからでもいいのでクローンしてみる

```
git clone ssh://gituser@xxx.xxx.xxx.xxx/home/gituser/test.git
```

以上。
Mapを使ってオブジェクトの配列の重複を除外する。【Javascript】

## 背景
バイト中に、mongodbからとってきたオブジェクトの配列から、valueが重複しているものを除きたいという場面がありました。僕がmapとfilterでゴリゴリやっていたのを見たCTOが「（少なくともこのシーンでは）こっちの方がいいっすね」というふうにいってMapを使ってやる方法を教えてくれたのでメモ書き程度に書いています。

## 僕の書いたやつ
```typescript
interface Item {
  id: number
}

const data: Item[] = [
  { id: 1 },
  { id: 2 },
  { id: 1 }
]

const newData = data.filter((item, index, self) => (
  index === self.findIndex(i => (
    i._id === item._id
  ))
))
```
多分割と無難なんじゃないかなと思います。

## 教えてもらった実装
```typescript
interface Item {
  id: number
}

const data: Item[] = [
  { id: 1 },
  { id: 2 },
  { id: 1 }
]

const uniqueItems = data.reduce((map, item) => {
  if (!map.has(item.id)) {
    map.set(item.id, item)
  }
  return map
}, new Map<number, Item>())

const newData = Array.from(uniqueItems.values())
```

## 感想
僕は、「ある配列をもとになんらかの配列を生成する」という処理を考えるときに、どうしてもmapやfilterのみで考えてしまう傾向があるみたいなので、適宜他の方法も考えられるようにならないといけないなぁという感じですね。もちろん、mapやfilterなどの方が適している場合もあるので、そのへんうまく使い分けられるようになれたらいいっすね。
BigQueryでGCS上のファイルにクエリを発行する

## はじめに

GCSからBigQueryへファイルを取り込む際の型定義が悩ましい。
できれば自動検知で済ませたいけど、検知できない場合（例えばYYYYMMDDの数字を日付と判断できなそう）に困る。
GCS上のファイルにクエリを発行でき、SQLのSELECT句でちょっとした加工ができるなら、自動検知できるように加工すると良さそう。

## 公式のドキュメント
https://cloud.google.com/bigquery/external-data-cloud-storage
https://cloud.google.com/bigquery/external-data-cloud-storage#temporary-tables

## GCSに置いたファイル

```test.csv
null,abc,文字列１,12345,1.2345,20180101,2018-01-01,2018/01/01
null,def,文字列２,67890,6.7890,20180201,2018-02-01,2018/02/01
```

## テーブル定義ファイル

```json:bqtabledef.json
{
  "autodetect": true,
  "sourceFormat": "CSV",
  "sourceUris": [
    "gs://XXXXX-bucket/test.csv"
  ]
}
```

## CLIで単にSELECT ＊してみる

```
$ bq --project=XXXXX --location=US query --external_table_definition=testtable::/tmp/bqtabledef.json 'select * from testtable'
Waiting on bqjob_rbcf80eccec0c503_00000164b09097fc_1 ... (0s) Current status: DONE   
+----------------+----------------+----------------+---------------+----------------+---------------+--------------+--------------+
| string_field_0 | string_field_1 | string_field_2 | int64_field_3 | double_field_4 | int64_field_5 | date_field_6 | date_field_7 |
+----------------+----------------+----------------+---------------+----------------+---------------+--------------+--------------+
| null           | abc            | 文字列１           |         12345 |         1.2345 |      20180101 |   2018-01-01 |   2018-01-01 |
| null           | def            | 文字列２           |         67890 |          6.789 |      20180201 |   2018-02-01 |   2018-02-01 |
+----------------+----------------+----------------+---------------+----------------+---------------+--------------+--------------+
```

## 結果
null（という文字列）は文字列型になってる。
20180101は数値型。
2018/02/01は区切り文字がハイフンではなくスラッシュなのに日付型と判断してくれている。

## YYYYMMDDを日付型にするには
例えば文字にキャストした上で`PARSE_DATE`してみる。

```test.csv
col1,col2,col3,col4,col5,col6,col7,col8
null,abc,文字列１,12345,1.2345,20180101,2018-01-01,2018/01/01
null,def,文字列２,67890,6.7890,20180201,2018-02-01,2018/02/01
```


```
$ bq --project=XXXXX --location=US query --external_table_definition=testtable::/tmp/bqtabledef.json --use_legacy_sql=false 'select PARSE_DATE("%Y%m%d", CAST(col6 AS STRING)) from testtable'
Waiting on bqjob_r52cefb0cf8a06d7c_00000164b5f1932f_1 ... (0s) Current status: DONE   
+------------+
|    f0_     |
+------------+
| 2018-01-01 |
| 2018-02-01 |
+------------+
```
Javaで比較対象の文字列が同じか判定する

文字列(String)を比較するには、値の大小ではなく、equalsメソッドを使用します。


```java
String型変数A.equals(String型変数B)
```

String型変数に「.equals」を続けます、そして()の中に比較対象のString型変数をそのまま指定します。
「String型変数AとString型変数Bが等しいかどうか」という内容になりますので、等しい場合はtrueが、等しくない場合はfalseが返ります。

サンプルコード：

```java:HelloWorld.java
public class HelloWorld{

     public static void main(String []args){
        
        String str1 = "abc";
        String str2 = "Abc";

        System.out.println(str1.equals(str2));
    
     }
}
```

```text:結果：
$ javac HelloWorld.java
$ java HelloWorld
false
```