OmniAICreator/Qiita-1.07M huggingface dataset:
Azure AD連携したAWSアカウントでaws-cliを使う

Azure AD連携をしてAWSを利用している会社もあるかと思います。
そのときにaws-cli使うのが面倒すぎたので自動化するツールを作りました。

適当なIAM　User作ればよいという話もありますが、個別に全員分発行するのは面倒だし全員で同じアカウント使い回すのも微妙だし、退職者管理とかも考えるとAzure AD連携を活かせるほうが良いかなと思います。

※2019/01/08 追記： tokenの有効期限が固定になっていたので設定で渡せるようにしました

# 概要
あまり詳しくないですが、Azure AD連携の場合はSAMLを利用しているかと思います。
なのでSAMLのXMLを持ってきてassume-role-with-samlをすれば一時的セキュリティ認証情報が取得できます。
やり方は以下に書いてあるとおりです。
https://aws.amazon.com/jp/premiumsupport/knowledge-center/aws-cli-call-store-saml-credentials/

ただaws-cliはほぼ毎日使うものなのに毎回SAMLレスポンスを手動で持って来るのはしんどすぎたので自動化しました。
ツールを実行するとChromeが起動し、そこでOffice365などにログインすると勝手にSAMLレスポンスを拾ってきてassume-role-with-samlしてくれます。
Chrome経由なのでMFAなどでも問題なくログインできます。
やってるのはそれだけです。

# 詳細
リポジトリは以下です。
https://github.com/knqyf263/azaws

## Installation
バイナリもReleaseに上げてあるので該当するアーキテクチャのバイナリを適当に落としてきて `/usr/local/bin` とかに置けば動くと思います。
goがインストールされている場合は

```golang
$ go get -u github.com/knqyf263/azaws
```

で良いです。

## 使い方
### 設定
まず最初にAzureでログインするための設定をする必要があります。
具体的にはTenant IDとApp ID URIが必要です。
これは管理者の人であれば画面ポチポチしていれば手に入ると思います。
https://www.syuheiuda.com/?p=3586

自分は管理者じゃなかったので困ったのですが、SAMLレスポンスの中に入っているのでデコードすれば手に入ります。
Chromeでデベロッパーツールを開いてNetworkタブでSAMLレスポンスを探します。
別タブで開かれて瞬時にredirectされるのでNetworkタブで見るの難しかったのですが、以下の記事の方法で別タブでもデベロッパーツールが自動で開かれるようにできます。
https://qiita.com/takenobi/items/50cb459db1abc75f8092

あとは開いたら「Preserve log」にチェックを入れれば記録できるかと思います。
https://developers.google.com/web/tools/chrome-devtools/console/?hl=ja#preserve-log

<img width="936" alt="DevTools_-_signin_aws_amazon_com_saml_と_Amazon_Web_Services_Sign-In.png" src="https://qiita-image-store.s3.amazonaws.com/0/56222/3cb62f86-4f39-390a-ae24-f9f46b93feec.png">

SAMLレスポンスを見つけたらあとはBase64デコードすれば良いです。
デコードされたXMLの中の `tenantid` のところに書いてあるのがTenant IDで、 `Audience` のところに書いてあるのがApp ID URIです。

Tenant ID等が手に入ったらコマンドで設定しておきます。

```console
$ azaws --configure
Azure Tenant ID: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
Azure App ID URI: https://signin.aws.amazon.com/saml?XXXXXXXXXXXX
Session Duration Hours (up to 12): 6
```


### ログイン
上でconfigureが終わっていればコマンドを実行するとChromeが起動します。
そこで普段どおりログインすれば `~/.aws/credentials` に一時的セキュリティ認証情報が保存されます。
そのときに使うprofile名はコマンドラインオプションで指定可能です。
また、assumeするroleも指定しておく必要があります。

```console
$ azaws --role admin --profile test
```

### aws-cli
上のコマンドが正常に実行されれば `~/.aws/credentials` に[test]のセクションが作られているはずです。
あとは通常通りawsコマンドが実行可能です。

```console
$ aws sts get-caller-identity --profile test
```

### オプション
他にも `-user-data-dir` のオプションもあります。
これはChromeのprofileを保存しておくpathになります。
2回目以降はAzure ADのセッションが切れていなければChromeが勝手にログインしてくれるのでパスワード等を打つ必要がなくなります。
初回ログイン時に「パスワードを保存」などにチェックを入れておけば次以降の起動はパスワードが埋まった状態になるのでログインボタンだけ押せばよいです。

ただデフォルトでは `/tmp/azaws` に作るようにしているためPCを再起動すると消えます。
PC再起動しても残しておきたい場合は$HOMEの下とかApplicationsの下とか適当な場所を指定しておくと良いです。

```
Usage of azaws:
  -configure
        Configure options
  -profile string
        AWS profile name (default "azaws")
  -role string
        AWS role name (required)
  -user-data-dir string
        Chrome option (default "/tmp/azaws")
```

# まとめ
CLIにID/PW渡すの嫌がる人いるかもな、と思ってChrome DevTools Protocolを使ってGUIで実現しているところがアピールポイントです。
ただいちいちGUI立ち上がるのうざいので `--no-gui` 的なやつ作っても良いなと思ってます。

AWSをAzure ADと連携してる人たちが世の中にどのぐらいいるか分からないのですが、自分は捗りまくるようになったので満足です。
署名なしでiOSアプリのビルド&単体テスト〜AppCenter編〜

## 「Visual Studio App Center」とは？

Microsoftが提供しているクラウドのCI/CDサービスです。
基本的な機能は無料で使用できます。

(以下「App Center」と呼ぶ)

## 環境

- Xcode：10.1 (10B61)
- Swift：4.2.1
- Carthage：0.31.2
- CocoaPods：1.6.0.beta.2

## 準備

### スキーマのコンテナをワークスペースに変更(ワークスペース使用時のみ)

CocoaPodsなどで `*.xcworkspace` を使っている場合のみ必要な設定です。

__Xcodeを起動 > Product > Scheme > Manage Schemes…
対象SchemeのContainerをWorkspaceに変更__
<img width="775" alt="スクリーンショット_2019-01-07_22_54_31.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/138245/aa375599-a811-d1c9-f14a-4b7f5110f3e8.jpeg">

### CocoaPodsのインストールスクリプトの実装(β版のCocoaPods使用時のみ)

App Centerの環境は基本的に最新のCocoaPodsがインストールされています。
β版のCocoaPodsを使用したい場合はスクリプトを手動で実装する必要があります。

`appcenter-post-clone.sh` という名前でプロジェクトのルートフォルダに配置することで、ソースのクローン直後に自動で実行されます。

```bash:appcenter-post-clone.sh
#!/usr/bin/env bash

# β版のCocoaPodsを使う
# ∵Xcode 10×CocoaPods 1.5.3の組み合わせだとコード署名でビルドエラーが発生するため
sudo gem install cocoapods --pre
```

## App Centerでビルドの設定

App Centerにログインしてプロジェクトを作成します。
https://appcenter.ms/

プロジェクトの作成やGitリポジトリの連携については割愛します。
私はAzure DevOpsのReposにあるGitリポジトリと連携させています。

__左のツリーで「Build」を選択
対象ブランチを選択__
<img width="507" alt="スクリーンショット_2019-01-07_23_19_43.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/138245/d41c5b7f-360a-9fc2-7911-50810ad76267.jpeg">

__ビルド設定__
<img width="740" alt="スクリーンショット 2019-01-07 23.22.24.png" src="https://qiita-image-store.s3.amazonaws.com/0/138245/896d9a58-be1d-4c94-cd36-ca56c2fe5782.png">
<img width="749" alt="スクリーンショット 2019-01-07 23.36.52.png" src="https://qiita-image-store.s3.amazonaws.com/0/138245/89dbe5e8-8631-3975-b731-f7925b4848d4.png">


私は以下のように設定し、ビルドと単体テストを実行させています。
デプロイまで行う場合は署名などの設定をONにしてください。

|項目|値|備考|
|:--|:--|:--|
|Project/Workspace|{プロジェクト名}.xcworkspace|対象プロジェクト or ワークスペース|
|Shared Scheme|{対象スキーマ}|選択できるスキーマがないと「No Scheme」エラーとなる|
|Xcode version|10.1|対象Xcodeのバージョン。Swiftのバージョンと紐付いている|
|Build scripts|Post-clone|対象スクリプト。所定の位置に配置するだけでこちらに表示される|
|Build frequency|Build this branch on every push|プッシュ時に自動でビルドする場合は上、手動は下を選択する|
|Automatically increment build number|OFF|ビルド番号を自動でインクリメントするか|
|Run XCTest tests|ON|XCTestを実行するか|
|Environment variables|OFF|環境変数を使用するか|
|Sign builds|OFF|署名してビルドするか。UIテストを実行する場合は必須|
|Test on a real device|OFF|実機でテストを実施するか。 __有料__|
|Distribute builds|OFF|アプリを配布するか|
|Build status badge|ON|ビルドステータスバッジを使用するか|

## おわりに

これで「ソースをプッシュ→ビルド→単体テスト」を自動化できました！
あとはこれに続けて「→デプロイ」まで自動化できるようにしたいです。

App Centerによるビルドでは、CocoaPodsやCarthageで管理しているライブラリを自動でインストールしてくれるため、簡単な設定のみでビルドできて非常に便利です。

## 参考リンク

- [Visual Studio App Center | Visual Studio - Visual Studio](https://visualstudio.microsoft.com/ja/app-center/)
Python で PaSoRiのセットアップ と FeliCaの読み取り

# はじめに
できたこと

- nfcpyのインストール
- FeliCaの認識
- ICOCAの交通履歴閲覧

# 環境
- Ubuntu 18.10
- [PaSoRi](https://www.amazon.co.jp/%E3%82%BD%E3%83%8B%E3%83%BC-SONY-%E9%9D%9E%E6%8E%A5%E8%A7%A6IC%E3%82%AB%E3%83%BC%E3%83%89%E3%83%AA%E3%83%BC%E3%83%80%E3%83%BC-PaSoRi-RC-S380/dp/B00948CGAG)
- Python 2.7
- お手持ちのFeliCa

# 手順
Python はインストール済みと想定．
nfcpyを公式リファレンス通りにインストールする．
[nfcpyのリファレンス](https://nfcpy.readthedocs.io/en/latest/topics/get-started.html#installation)

```bash:インストール例
sudo apt update
sudo apt upgrade
sudo apt -y install python-pip
sudo apt -y install python-dev
sudo apt -y install libusb-dev
sudo apt -y install python-usb
sudo pip install -U nfcpy
sudo reboot
#必ず再起動してください！私はココでつまずきました..
lsusb
#PaSoRiをPCに差し込み，Sonyデバイスが確認できたらOK
```

次に以下のコマンドを実行し，

```bash
python -m nfc
```
以下の結果が出れば成功！
失敗ならば，リファレンスを読み直してください．

```bash:実行結果
No handlers could be found for logger "nfc.llcp.sec"
This is the 0.13.5 version of nfcpy run in Python 2.7.15+
on Linux-4.18.0-13-generic-x86_64-with-Ubuntu-18.10-cosmic
I'm now searching your system for contactless devices
** found SONY RC-S380/P NFC Port-100 v1.11 at usb:001:004
I'm not trying serial devices because you haven't told me
-- add the option '--search-tty' to have me looking
-- but beware that this may break other serial devs
```

# 結果
セットアップは終了したので，FeliCaの読み取りをしてみたいと思います．
### nfcpyでFeliCaの情報閲覧

```bash:nfcpy
git clone  https://github.com/nfcpy/nfcpy.git
cd nfcpy/examples/
sudo python ./tagtool.py --device usb:XXXX:XXXX
#XXXX:XXXXはlsusbで出したデバイスID
```

実行すると，

```bash:FeliCa認識待ち
[nfc.clf] searching for reader on path usb:XXXX:XXXX
[nfc.clf] using SONY RC-S380/P NFC Port-100 v1.11 at usb:001:004
** waiting for a tag **
```

上記のような結果が出ると成功です！
実際にICOCAでも置いて読み取ってみましょう！

```bash:IDm
Type3Tag 'FeliCa Standard (RC-S915)' ID=**************** PMM=**************** SYS=****
```
(一部修正)
でましたね．この情報は，IDmといいます．
[(引用) IDmについて](http://www.orangetags.jp/words/idm)
> IDmは、FeliCaのICチップ製造時に、ICチップに記録され書き換えができない固有のID番号である。IDmは8byte（16桁）の数字で、トレーサビリティと個体識別を目的としてソニーが製造するICチップに書き込まれ同じ番号が流通しないようにソニーが管理をおこなっている。編集は不可能であり比較的簡単に利用できることから、応用範囲が広く、このID番号を使ったアプリケーション・システムが広く普及している。

### 交通履歴閲覧
次にICOCAの交通履歴が閲覧してみましょう．

```bash:nfcpy-suica-sample
git clone https://github.com/m2wasabi/nfcpy-suica-sample
cd nfcpy-suica-sample/
sudo python suica_read.py
```

```bash:交通履歴
=== 14 ===
端末種: 改札機
処理: 運賃支払
日付: 18-12-16
入線区: 神戸新交通-ポートアイランド
入駅順: 三宮
出線区: 神戸新交通-ポートアイランド
出駅順: 京コンピュータ前
残高: 2243
BIN: 
XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX 
=== 15 ===
端末種: 改札機
処理: 運賃支払
日付: 18-12-16
入線区: 西日本旅客鉄道-大阪環状紀勢本線
入駅順: 鶴橋
出線区: 西日本旅客鉄道-東海道本神戸線
出駅順: 三ノ宮
残高: 2523
BIN: 
XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX 
=== 16 ===

```
(一部修正)
20件の交通履歴が出ます．
残高とかもわかっちゃうので割と実用的ですね．

# 考察
今回は主にセットアップだけだったが，次回はラズパイと連携してドアのオートロックを制作する予定．
割とやってて面白かったので，IDmとか勉強してFeliCaのセキュリティについて追求できたらいいなと思う．

# 参考
https://nfcpy.readthedocs.io/en/latest/topics/get-started.html#installation
https://github.com/m2wasabi/nfcpy-suica-sample
https://qiita.com/keitasumiya/items/7bdb3ccf55176ee731d4
https://uepon.hatenadiary.com/category/nfc
https://qiita.com/xshell/items/55302a588b5927dde6b6
http://www.orangetags.jp/words/idm
初めてのVulkanプログラミング step2  vkqueue

[目次に戻る](https://qiita.com/tositada_nakada/items/db0f01c1c8c2945f786b)

ソースコードは以下の場所に置いておきます。各自のバージョンに合わせたプロパティ設定をしてから自由にご利用ください。

[GitHub](https://github.com/nakadasanda/vulkanAppaddcal2018)

##queue
キューは、デバイスの実行エンジンへのインターフェースを提供します。コマンドは、実行前にコマンドバッファーに貯められます。そしてコマンドバッファーは、queueに送信されます。キューに送られたコマンドは、バッチ処理によって実行されます。キューに送られたコマンドは、アプリケーションの介入なしに実行されます。

vkqueueは論理デバイスを作成した時に自動的に生成されますが、queueを操作するためのハンドルを持ちません。まずqueueへのハンドルを格納するクラスメンバーを追加します

```cpp
VkQueue queue;
```
このvkGetDeviseQueuを使用して各キューファミリーのキューハンドルを取得します。パラメータは、論理デバイス、キューファミリー、キューファミリーインデックス、そしてキューハンドルを格納する変数へのポインターです

```cpp
vkGetDeviceQueue(_device, 0, 0, &queue);
```
step2は、これで終了です。デバイスとキューができたら、グラフィックボードを使った操作ができるようになります。
次の章では、やっとコマンドプロンプトのほかに新たなwindowを作ることができます。

## 連絡先

tweeter: [tositada_nakada](https://twitter.com/nakadasanda17)
mail: nakadasanda@outlook.com

## 寄付

paypal: [tositada_nakada](https://www.paypal.me/nakadasanda)
Amazon: [欲しいものリスト](http://amzn.asia/fGpGuJo)
Apple ClangでOpenMPを使う

この記事では、Appleが提供しているClang（XcodeやCommand Line Toolsに含まれるもの）でOpenMPを使ったコードをコンパイル可能にする方法を述べる。

# 前提
macでOpenMPを使えるようにする方法を調べると、homebrewでgccかllvmかclang-ompをインストールしましょう、という情報がほとんどだ。理由としては、Apple ClangではOpenMPが使えないので別のコンパイラが必要だから、とされている。

しかし、実はそんなことはなかった。少なくとも、コンパイラを丸ごとインストールする必要はない。

# 方法
※　以下、Henry Schreiner氏による詳しい記事 https://iscinumpy.gitlab.io/post/omp-on-high-sierra/ からの抜粋です。

## libompを入手する
```
brew install libomp
```
OpenMPのランタイム ライブラリがないとどうしようもないので、これは必要。

## オプションを付けてコンパイルする
普通に `-fopenmp` だけ付けてもコンパイルが通らないので

```
clang -Xpreprocessor -fopenmp -lomp myfile.cxx
```
とする。肝心なのはOpenMPプラグマを処理させるための `-Xpreprocessor` オプション。リンク時には `-lomp` も必要になる。

# まとめ
libompだけインストールすればいいので簡潔。

今までのようにhomebrewでllvmをインストールしたり、どっちのclangが使われているのか気にしたりする必要がなくなって、開発環境の構築がだいぶ楽になった。
react nativeで開発時に出る黄色のボックスを消す

![alt](https://user-images.githubusercontent.com/26253721/39765058-e8d0eae4-531b-11e8-9305-4c852f269517.png)
react nativeで開発してると、黄色いモーダル出てくるよね。

お前らが出てくると、タブを押せないんじゃ！！

というわけで消しましょう。

```
console.disableYellowBox = true
```
とApp.jsのトップレベルに記述しましょう。

例

```js
// App.js
import React from 'react'
console.disableYellowBox = true;

class App extends Component {
…
```

マリックもびっくり。
黄色いボックスが消えます。

ただconsole.warnによる黄色いボックスも表示されなくなるので注意。

## 注意
黄色のボックスは、問題のあるコードを指摘してくれるありがたいものです。
しかも、この方法はreact nativeのソースコード内に書かれている非公式のメソッドです。
この方法は自己責任のもと実行してください。
JavaScriptを使用しないパララックス２選

qiitaの記述練習兼、後輩への講座のまとめ資料としてメモ程度に記述します。
拙い箇所も多々あると思いますが、温かい目で閲覧ください。
#background-attachment

言っちゃえば背景固定ですね。
下にスクロールすると、ファーストビューが固定されて簡易的な視差効果が生まれます。

```html:index.html
<div id ="first-view">
</div>
<div id ="contents">
</div>
```

```css:sample.css
#first-view {
background-image: url(img/bg.jpg);
background-attachment: fixed;
width: 100vw;
height: 100vh;
}

#contents {
width: 100vw;
height: 100vh;
background-color: #aaa;
}
```

#sticky
ただ注意点があり、
サポートブラウザがまだ広くありません。
祖先要素にoverflowが掛かっているとうまく動作しない。
inline-block要素はsafariではスティックしないようです。
<img width="1213" alt="スクリーンショット 2018-12-22 10.35.30.png" src="https://qiita-image-store.s3.amazonaws.com/0/281953/4f25a35e-ae6b-79be-ea11-ad9baf034c3a.png">
問題点はありますがすごく便利な機能です。

```html:sticky.html
<div class="sticky one">
</div>
<div class="sticky two">
</div>
<div class="sticky three">
</div>
```

```css:sample.css
.sticky {
width:100vw;
height:100vh;
position:sticky; 
top:0;
}

.one {
background:#f00;
}

.two {
background:#242424;
}

.three {
background:#aaa;
}
```

詳しくはこちらの記事を参考ください。
[position: stickyの面白い使い方と使用時の注意点](https://parashuto.com/rriver/development/position-sticky#notes)
私よりももっと細かく書かれていると思います。

正直、CSSでのパララックスは限界があります。
Jsと比較されてしまうとどうしても目劣りしてしまいます。
よっぽどの理由がない限りはライブラリ等を使用してパララックスを導入した方が
UX的にも良いと思いましたw
S3-apigatewayのCORS

AWSのCORS関連でハマったので設定をまとめます。

# 概要
下記のアーキテクチャで、
- S3バケットにWEBページ静的ホスティング
- 上記WEBページから、APIGatewayを経由して別のS3バケットからデータ取得
を行います。
しかし、静的ホスティングをしているバケットのドメインとデータが格納されているドメインが異なるので、CORSでハマります。
![Screenshot at 2019-01-07 22-56-07.png](https://qiita-image-store.s3.amazonaws.com/0/289777/b633b48b-77a7-f265-5d46-78263187e3e0.png)

# APIGatewayでのCORS設定
まずクライアントPCがcallするAPIGatewayのCORS設定をする必要があります。

スクショは省略しますが、
1. API Gatewayのコンソール
2. アクショントグルボタン押下
3. CORSの有効化を選択。
4. 表示される設定値はデフォルトでOK。必要であれば、Access-Control-Allow-OriginをS3の静的ホスティングのドメインと合わせる。
5. APIGatewayのデプロイ
になります。公式は[ここ](https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/how-to-cors.html)

これでもまだCORSでハマります。
なぜなら、S3のバケット自身もCORS設定を保有するためです。

# S3でのCORS設定
こちらもスクショは省略します。
1. S3のコンソールでバケットを開く
2. アクセス権限
3. CORS設定
4. 下記のXMLドキュメントを記載して保存

```config.xml
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
    <AllowedOrigin>http://***</AllowedOrigin> <!-- ***はドメイン名-->
    <AllowedMethod>GET</AllowedMethod>
</CORSRule>
</CORSConfiguration>
```
公式は[ここ](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/dev/cors.html)
これでようやく静的ホスティングしているS３バケットから、別バケットのデータが取得できました！！

# まとめ
ローカルホストではなく、実際にホスティングしてみると詰まるところがちょこちょこあります。
筆者はCORSの知識は少なかったですが、実際に詰まることで結構勉強になりました。ホスティング大事。

※どうでもいいけど、AWSの新アイコン・旧アイコンどっちが人気なんだろ…

# 参考
https://qiita.com/tanj/items/e4486f9af5d7a903117d
https://qiita.com/matsumatsu20/items/0b7342e93daba150fa50
Python+Networkxでグラフ上のある頂点からKステップ分の近傍を簡単に探す

以前の凸包や最短経路を求める例と似た感じの小ネタで，今回はある頂点からK-th order neighborを探してくるスクリプトを，できるだけ公式の機能だけを使ってやってみる．もっと簡単な方法があったらコソっと教えてください．とりあえずの例題として，幾何的なグラフ構造をランダムに作成した．

# ランダムなグラフの作成

```python
import networkx as nx
import matplotlib.pyplot as plt

G = nx.random_geometric_graph(200, 0.125)
pos = nx.get_node_attributes(G, 'pos')

# find node near center (0.5,0.5)
dmin = 1
ncenter = 0
for n in pos:
    x, y = pos[n]
    d = (x - 0.5) ** 2 + (y - 0.5) ** 2
    if d < dmin:
        ncenter = n
        dmin = d
p = nx.single_source_shortest_path_length(G, ncenter)

fig = plt.figure(figsize=(8,8))
nx.draw_networkx_edges(G, pos, nodelist=[ncenter],alpha=0.4)
nx.draw_networkx_nodes(G, pos, node_size=40)
plt.xlim(-0.05,1.05)
plt.ylim(-0.05,1.05)
plt.axis('off')
plt.show()
```

![graph.png](https://qiita-image-store.s3.amazonaws.com/0/7181/a7aeb911-be16-96d9-ee52-11c5b8553ed6.png)


# ある頂点からKステップの頂点を求める

今回は最短経路を求める関数に渡すことができる引数**cutoff**を利用した．

```python
K = 5
nodedict = {}
for k in range(1, K + 1):
    Nk = nx.single_source_shortest_path_length(G, ncenter, cutoff=k)
    Nk = [n for (n, v) in Nk.items() if v == k]
    nodedict[k] = Nk
```

# 可視化してみる

```python
fig = plt.figure(figsize=(8,8))
nx.draw_networkx_edges(G, pos, nodelist=[ncenter], alpha=0.4)
nx.draw_networkx_nodes(G, pos, node_size=40, node_color='black')
nx.draw_networkx_nodes(G, pos, node_size=50, node_color='red', nodelist=nodedict[1])
nx.draw_networkx_nodes(G, pos, node_size=50, node_color='green', nodelist=nodedict[2])
nx.draw_networkx_nodes(G, pos, node_size=50, node_color='cyan', nodelist=nodedict[3])
nx.draw_networkx_nodes(G, pos, node_size=50, node_color='blue', nodelist=nodedict[4])
nx.draw_networkx_nodes(G, pos, node_size=50, node_color='magenta', nodelist=nodedict[5])
plt.xlim(-0.05,1.05)
plt.ylim(-0.05,1.05)
plt.axis('off')
plt.show()
```

![graph_viz.png](https://qiita-image-store.s3.amazonaws.com/0/7181/752d82ab-4d78-f2db-eb65-c35859fd9a2e.png)
プログラミングオタクとエンジニアの違い。

■自己紹介
　年齢：24歳（1995/02/14　生まれ）
　職業：SIer（4年目）

　私は、北海道の中小企業で働くSIerです。
　小さい会社なので、部署としても３人しかおらず、客先常駐で技術を売っています。

　常駐先では、プロジェクトマネージャとして、
　４名程度のメンバーの管理業務をしています。
　（最初の2年は開発→設計を担当。３年目からPMです。）

■本題
　世の中には、エンジニア集団と名乗る会社の中に、
　「ただのプログラミングオタク」が紛れていると思うのです、
　プログラミングオタクと、エンジニアの違いは、
　一言で言うと、「なぜその技術がお金になるのかを知っているかどうか」です。　

　極端な例ですが、２つ紹介します。

　●プログラミングオタク
　　・技術力がある。
　　・勉強熱心である。
　　・お客様からお金をもらっているという自覚がない。

　●エンジニア
　　・技術力がある。
　　・勉強熱心である。
　　・お客様からお金をもらっているという自覚がある。

　ITを仕事にするということは、究極を言うと、
　ソフトウェアの知識がない人が、
　困っている手作業を自動化してあげる。ということだと思うのです。
　つまり、お客様の目線を知った上で、
　どうそれをITで実現するか？だと思うのです。

　それを踏まえて、上の2つの種類の人間には、
　天と地ほどの差があるわけです。

　例えば、ITに関わる仕事をしていると、
　いつかその膨大な仕事量に絶望するときがいつか来るのです。
　プログラミングオタクは、どう考えるかというと、
　「膨大すぎる。こんなの手に追えない。」と考えます。

　使えるエンジニアは、
　「この膨大な量の中で、お客様が一番望む仕事はなんだろうか」と考えます。

　ここが、「プログラミングオタク」にはなく、「エンジニア」にはある発想なのです。
　技術力の差ではないのです。

　つまりは、インフォメーション（知識）と、
　インテリジェンス（知性）は別物だ。という事が言いたいわけです。
autokerasを使って特徴量抽出器を作る

autokerasは雑に言うとディープラーニングの自動化ライブラリです。今回はそれを使って特徴量抽出器を作ります。

# ソースコード
autokerasそのままではうまくいかず、ソースコードを書き換えてmyautokerasとしてインストールしました。
https://github.com/shiibashi/myautokeras

変更したのはここ↓
https://github.com/shiibashi/myautokeras/commit/4d4d9d9fff58f2f1c88f16d4972b61f46250dcb6

変更イメージはこんな感じ↓
途中まで計算した結果を出力するように書き換えました。
![blog用.jpg](https://qiita-image-store.s3.amazonaws.com/0/211078/f4b325e0-c5cd-203d-97a0-da9c09564d81.jpeg)

autokeras↑を使って特徴量抽出器を作るまでのスクリプトはここ↓
https://github.com/shiibashi/qiita/blob/master/7/autokeras_2vec.ipynb
以下はこのソースコードについて補足的な説明を書いていきます。
pythonのバージョンは3.6.7

# データ
数字の0と1の手書き画像を用意しました。0か1かに分類するタスクを学習し、分類の特徴ベクトルを抽出します。

# 学習
前回の記事にまとめました。

超簡単なautokerasの使い方
https://qiita.com/shiibass/items/28ffcaa9aec2799d5691

# 学習後
学習したモデルをそのまま使うのならこんな風にpredictで0か1かの予測を行います。

```python
model.predict(test_X[0:3]) # array([0, 0, 0])
```
今回は特徴ベクトルを抽出したいのでまだ続きます。まず学習したモデルを保存しておきます。

```python
# save
path = "model.hdf5"
model.export_autokeras_model(path)
```

## モデルのロード
学習したモデルを読み込みます。保存してすぐ読み込んでいて不自然ですが、学習バッチと予測バッチを切り離して運用することを想定しています。

```python
output_model = autokeras.utils.pickle_from_file(path)
```

## predict
内部ではニューラルネットワークの計算結果がリストに保存されているのでその何番目の結果を取り出すかという引数を追加しました。output_index=-1(リストの最後の要素)もしくは、引数を与えなければ従来通りの0か1かの予測ラベルを返します。最後から一つ前ならoutput_index=-2とします。

```python
vec_train_X = output_model.predict(train_X, output_index=-2)
vec_test_X = output_model.predict(test_X, output_index=-2)
```

確かめるために特徴ベクトルを出力してみます。

```python
pandas.DataFrame(vec_train_X).head(2)
```
512次元のベクトルが得られたようです。あえて日本語で解釈をするとすれば、0か1を分類するために必要な512要素ということになります。
![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/211078/f6f749a2-720d-c1a8-3716-fbd6b1cfc949.png)


## 512次元が特徴抽出器として機能するかどうか確認
一応以下のコードで高い精度が出ますので特徴抽出器として多少は使えそうな気がしますね。これでautokerasを使って特徴ベクトルを得られました。これをベースにすれば〇〇2vecを簡単に生産できそうです。

```python
from sklearn.linear_model import LogisticRegression
lr = LogisticRegression(solver="lbfgs")
lr.fit(vec_test_X, test_Y)
lr.score(vec_test_X, test_Y) # 0.9978378378378379
```

# 特徴ベクトルを得られたけどどう使うのか
そもそもなぜこんなことをする必要があるのかという話になります。〇〇2vecはベクトル空間にマッピングしているので、例えば類似データの検索に使えそうで、近似近傍探索のようなワードで調べればレコメンドエンジンを作れますね。あとはデータ分析時の特徴量として使うこともできそうです。画像や音声、テキストなどの厄介なデータ構造に対して使いにくい手法（ロジスティック回帰とか）もベクトルに変換できれば分析しやすくなります。
3Dモデルの作成プロセス

アベンジャーズやファイナルファンタジーなどのように、CGI（Computer-Generated Imagery）映画を見たり3Dゲームをしたりするのは、いつも面白いです。しかし、これらの3Dモデルは実際には簡単には作成できません。そのようなものを作成するには時間と献身が必要です。それで、映画やゲームの3Dモデルの作成方法について説明します。

#コンセプトアート
3Dモデルを作成する前に、「コンセプトアート」から始める必要があります。コンセプトアートとは、モデルの基礎となるもの、つまり2D絵のことです。これを作成するには、Adobe PhotoshopやPaint Tool SAIや鉛筆と紙などを使うことができます。しかし、時にはクライアントがあなたにキャラクターの説明を与えるだけで、それで、あなたは直接モデリングに行きます。

!![Concept Art](https://qiita-image-store.s3.amazonaws.com/0/293087/6d0f0183-f92e-5a63-55fa-3df3e0b58f60.png)

#ベースメッシュ
コンセプトアートを作った後、モデルのベースメッシュを作り始めます。ここで、詳細なしでモデルの基本的な外観を作成します。ベースメッシュを作成するには、Autodesk 3DS MaxやBlender3DやAutodesk Mayaなどを使うことができます。

![Base Mesh](https://qiita-image-store.s3.amazonaws.com/0/293087/104be1d4-3435-f077-2fd9-52da1d5fd0a7.png)

#彫刻する
ベースメッシュに満足したら、それをZBrushというのプログラムに転送して詳細を追加できます。モデルにどれだけの詳細を追加したいかは、あなた次第です。たくさん詳細を追加するので、この部分は通常最も時間がかかります。彫刻するには5日か2週間かかります。

![Sculpting](https://qiita-image-store.s3.amazonaws.com/0/293087/f97f0b15-9809-68e3-76b8-2196db9478e8.png)

#再タイポロジー
次に、再タイポロジーです。ここでは、彫刻モデルのポリゴン数を減らして、より自然で見栄えがよくなるようにします。ハイレゾリューションモデルよりもレンダリングするポリゴンが少なくて済むため、これによりゲームの実行速度が改善します。

#テクスチャリング
そして、テクスチャリングに、あなたのモデルを色で活気づけます。ここでモデルの詳細を描いて、より美しくなります。モデルにテクスチャを追加するには、Adobe PhotoshopとZbrushを使うことができます。

![Texturing](https://qiita-image-store.s3.amazonaws.com/0/293087/c39260bb-4600-fd0b-4f49-15c200a017e2.png)

#リギング
モデルを動かすには、「骨」を追加する必要があります。これはリギングということです。モデルによって「骨」を追加します。それが人であれば、私たち自身の関節のように「骨」を追加します。モデルをリグした後は、モデルを映画とゲームに追加してアニメートできます。

![Rigging](https://qiita-image-store.s3.amazonaws.com/0/293087/a247496f-7396-6049-7f4d-264a1208230f.png)

#References
- [Autodesk Maya] (https://www.autodesk.co.jp/products/maya/overview?referrer=%2Fproducts%2Fmaya%2Foverview)
- [Zbrush] (http://pixologic.com/)
ReactコンポーネントのPropsの型定義でジェネリクスを使う

ジェネリクスを使ってReactコンポーネントの呼び出し元から型情報を渡す。

```ts
interface IProps<T> {
  a: T;
}

class A<T> extends React.PureComponent<IProps<T>> {
  render() {
    const { a } = this.props;
    return <p>{a}</p>;
  }
}

ReactDOM.render(
  <div>
    {/* 型推論 */}
    <A a="hoge" />

    {/* 型を明示 */}
    <A<string> a="hoge" />

    {/* 型エラー */}
    {/* <A<number> a="hoge" /> */}
  </div>,
  document.getElementById('app')
);
```

こっちの方が実用的っぽい👇

```ts
interface IProps<T> {
  onClick: T & React.MouseEventHandler<HTMLButtonElement>;
}

class Button<T> extends React.PureComponent<IProps<T>> {
  render() {
    const { onClick } = this.props;
    return (
      <button onClick={onClick}>click</button>
    );
  }
}

interface IClick1 { (): void; }
interface IClick2 { (): string; }

const click = () => {
  console.log('hoge');
};

ReactDOM.render(
  <div>
    {/* 型推論 */}
    <Button onClick={click} />

    {/* 型を明示 */}
    <Button<IClick1> onClick={click} />

    {/* 型エラー */}
    {/* <Button<IClick2> onClick={click} /> */}
  </div>,
  document.getElementById('app')
);
```

もともとは`any`を使いたくなくてやり方を調べてたけど、型を明示するならまだしも型推論でなんでも通ってしまうのは`any`と変わらない気もする🤔

こういう外からコールバック関数を渡したいときの型定義のべすとぷらくちすが知りたい。
ColaboratoryからCSVファイルをチームドライブにダウンロードする


### 背景
[Google Colaboratory](https://colab.research.google.com/notebooks/welcome.ipynb?hl=ja) は設定不要でPythonが使えるので、わたしは退屈なことをやらせる便利ツールとして使っています。ふと「Colaboratoryで生成したCSVファイルをGoogleチームドライブにダウンロードする」ってどうやるんだろうと疑問に思い、試行錯誤した結果、動いた方法です。

### 動いたコード
Colaboratoryのファイルはチームドライブのどこかにあって、この直前のコードセルでdfと名付けたpandasのDataFrameに何か表を格納しており、このdfの表をCSVファイルとしてチームドライブ の任意のフォルダにダウンロードしたい、という状況です。まず、「Google DriveをColaboratoryにマウントする」というおまじないをColaboratoryのコードセルに貼り付けて実行します。認証のためプロンプトが出てきますが、素直に指示に従います。

```python
from google.colab import drive
drive.mount('/content/gdrive')
```

そして、チームドライブの中のフォルダ名、ファイル名を指定して、次のコードをコードセルに書いて実行します。ファイル名はここで初めて名付けています。フォルダは何階層かあっても大丈夫です。

```python
with open('/content/gdrive/Team Drives/フォルダ名/ファイル名.csv', 'w', encoding = 'utf-8-sig') as f:
  df.to_csv(f)
!cat /content/gdrive/Team\ Drives/フォルダ名/ファイル名.csv
```

これでおしまい。Googleチームドライブの指定したフォルダにデータフレームdfの内容を反映したcsvファイルが出来ました。「Google DriveをColaboratoryにマウントする」コマンドで、My Driveだけでなく、Team Driveもマウントされており、チームドライブに対してもシェルコマンドが使えるようになっていたのでした。

###おまけ
いちいちファイル名を手書きするのは面倒なので、今日の日付をファイル名（result_YYYYMMDD.csv )につけて保存しています。

```python
import datetime
now = datetime.datetime.now()
filename = "result_{0:%Y%m%d}.csv".format(now)
path = "/content/gdrive/Team Drives/フォルダ名/" + filename
with open(path, 'w', encoding = 'utf-8-sig') as f:
    df.to_csv(f)
!cat /content/gdrive/Team\ Drives/フォルダ名/$filename
```

### 元ねた
2019年1月現在、ググってもColaboratoryで作成したCSVファイルをチームドライブにダウンロードするやり方を簡単に書いている記事は見当たらなくて、しばらくの間、頭を悩ませていました。[Google公式Tutorialの"Mounting Google Drive locally"](https://colab.research.google.com/notebooks/io.ipynb#scrollTo=u22w3BFiOveA)にテキストファイルを作成してMy Driveに格納する例があり、今回はそれを応用しました。そもそもこれダウンロードじゃないし、という突っ込みはあるかもしれないのですが、目的は達成できたし、誰かの時間を節約するのに役立つかもしれないと思い、ここにメモっておきます。
JOBのサンプルコードの動作確認手順

# 概要
ここには、[JOB]( https://github.com/EddieLa/JOB )のサンプルコードを使用してバーコードを読み取った際の手順を記載します。
[デモページ]( http://eddiela.github.io/JOB/ )も用意されているので、そちらで動作を確認することもできますが、
今回は、自分のPC上に立てているApacheで動作させています。
以下、手順です。
# 手順
1.https://github.com/EddieLa/JOB/tree/gh-pages から clone or ダウンロードします。

```
※以下のファイルがダウンロードできます。
index.html  
StreamDemo.html  
DecoderWorker.js  
JOB.js  
exif.js  
```
2.ダウンロードしたファイルをドキュメントルートに配置します。
3.ブラウザから index.html（サンプルコード）にアクセスすると以下の画面が表示されます。
![Screenshot_20190106-215252_Chrome.jpg](https://qiita-image-store.s3.amazonaws.com/0/262399/0002eca7-fce8-825c-a6fa-30dccd94a434.jpeg)
4.「ファイルを選択」をタップすると以下のようにアプリケーションの一覧が表示されるので、今回は「カメラ」を選択します。
![Screenshot_20190106-215259_Android System.jpg](https://qiita-image-store.s3.amazonaws.com/0/262399/af04b25b-3a67-2ae6-acb4-a249fb339d43.jpeg)
5.カメラが起動します。撮影すると以下の画面が表示されるので、「OK」をタップします。
![Screenshot_20190106-215453_Camera.jpg](https://qiita-image-store.s3.amazonaws.com/0/262399/27ab45a0-cce2-c8ee-2560-fad2d7467ed4.jpeg)
6.すると、以下のようにバーコードの種別と読み取れたコード値が表示されます。（うまく読み取れなかった場合は、「Decoding failed.」と表示されます。）
![Screenshot_20190106-215502_Chrome.jpg](https://qiita-image-store.s3.amazonaws.com/0/262399/d8bcc2b4-dea7-30e1-a2c4-e5a24b3a04a3.jpeg)

動作確認に利用した端末は Galaxy S9+(SC-03K) です。

以上です。

# サンプルコードについて、ざっくり考察。
※2019/01/08 追記

```javascript:index.html
// 1.起点
// 　カメラでの撮影等が完了し、バーコード読み取り対象の画像の選択が完了すると、
// 　この要素のonchangeイベントが発生します。
<input id="Take-Picture" type="file" accept="image/*;capture=camera" />

// 2.onchangeイベントのハンドリング
// 　onchangeイベントが発生した際、以下のように画像をfileとして受け取るようにしています。
takePicture.onchange = function (event) {
  var files = event.target.files;
  if (files && files.length > 0) {
    file = files[0];
// ：略
}

// 3.バーコード画像の読み込み＆デコード
try {
	var URL = window.URL || window.webkitURL;
	showPicture.onload = function(event) {
		Result.innerHTML="";
		JOB.DecodeImage(showPicture);
		URL.revokeObjectURL(showPicture.src);
	};
	showPicture.src = URL.createObjectURL(file);
}
catch (e) {
// 略 ※注意：catchの中でもFileReaderを使用して画像の読み込み＆デコードを試みています。
}

// 4.デコード結果のハンドリング＆結果表示
// 　デコード結果がresultとして受け取ることが出来ます。
// 　ここでは、フォーマット（result[i].Format）とバーコード値（result[i].Value）を結果として表示しています。
JOB.SetImageCallback(function(result) {
	if(result.length > 0){
		var tempArray = [];
		for(var i = 0; i < result.length; i++) {
			tempArray.push(result[i].Format+" : "+result[i].Value);
		}
		Result.innerHTML=tempArray.join("<br />");
	}else{
		if(result.length === 0) {
			Result.innerHTML="Decoding failed.";
		}
	}
});
```
以上です。
Twitterで100万円キャンペーンの集計

あけましておめでとうございます。
お金持ちの人のアカウントをフォロー＆RTすると100万円！というキャンペーンがが流行りの2019年ですね。

1億円を配りたくなった、配りたい人なんとかしてくれと言われた人用に記事を書いてみました。
もしそんな方のお役に立てたなら当選者の1人として扱っていただければ幸いです。

以下のような条件のキャンペーンをやること想定で書いています。Twitter APIでこれをどう実現するかという内容が主です。

# キャンペーン概要
- 特定のアカウントがキャンペーン参加用のツイートを投稿する
- 参加者は該当アカウントのフォロー状態となり、上記のツイートをRTする
    - 参加用ツイートの指定期間外のものは無効とする
- 参加者の中から `抽選`で100名を選び当選者とする
- 当選者にはDMを送信し当選物の受け渡しについての調整を進める。落選者には何も連絡なし
- 
まずはシステムを使わないでカジュアルにばらまくパターンです。

# 1.システムなんて無用。人力で十分ですよパターン
- RTの通知欄を無作為なタイミングで当選者数以上の3〜5倍の確認し、その時最も最新でRTしていた人のアカウントを記録する
    - キャンペーン終了後、収集したアカウントをランダムで並び替え、DMを100人に送るまで以下を行う
        - 当選者の上から順にフォロー状態をチェックし、フォローをしていたら当選のDMを送る
    - フォローをしていなかった/外された、ユーザーが消える可能性があるのでバッファで3倍〜5倍の人の数を集めるとしています


## 2.API使って事前に準備をしておいて集めるパターン
- 去年UserStreamが抹殺された今、リツイートの収集はAPIでやる限り4パターンしか方法はありません
    - [Account Activity API](https://developer.twitter.com/en/products/accounts-and-users/account-activity-api.html)
        - 最近のTwitter APIの闇その1です。2ももちろんあります。
        - APIをこういう目的で使うよという申請文を書き、あまりそれをよく読んでない審査官のチェックをくぐりぬけたもののみが使える選ばれしもののAPIです。個人の1フォロワーのアカウントで5回申請しましたが最終的に全滅でした。。
        - 基本的にAPI保持ユーザーに関連したイベントはだいたいとれます。RTももちろんとれます。
    - [検索API](https://developer.twitter.com/en/docs/tweets/search/api-reference)
        - 5秒に1回最大100件取得できるので、5.25秒ごとくらいのインターバル(経験則的にAPIのレスポンスはだいたい平均0.2〜0.3秒くらい)で検索をかける。参加用ツイートへのツイートしかでてこないようにクエリを調整する。
            - 例: `RT @campaignakaunto 100万円です`
        - おそらくすごいペースでRTされるので検知の漏れはかなり発生するのですが、まずはここから運試しということです
    - [Filter realtime Tweets](https://developer.twitter.com/en/docs/tweets/filter-realtime/api-reference/post-statuses-filter.html)
        - Streaming APIの生き残りです。検索と同じようにクエリを指定してリアルタイムなRTイベントを受け取ります
        - 検知数の制約がないのでこちらのほうが検知の漏れが少ないです
    - [Firehose](https://gigazine.net/news/20161031-twitter-firehose/)
        - これだけ使ったこと無いの正直よくわからないのですが、年間100万ドル以上払うとツイートの全量データがもらえるらしいです
        - [別の会社](https://nazuki-oto.com/twitter/)を通して手に入れると100万ドルもしないかも
        - いずれにせよこれ使う金があったらもっとばらまいた方がいいと思います


## 開催後に集計を始めなければいけなくなった場合
- 集計をはじめる前の人は全員落選！とするのがぶっちゃけ一番楽なのですが、機会の平等のためそれはなしとします
- 以下手順でフォロワーのユーザーIDを集めた後、参加用ツイートを集めているかをチェックします
    - [フォロワーのユーザーID取得](https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-followers-ids)でフォロワー全員のIDを取得
    - 取得したIDをランダムに並べ替え、[特定ユーザーの概要情報取得](https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-followers-list)で取得したフォロワーを上から100人ずつ見ていき、参加用ツイートをRTしているかチェックする。
    - このAPIで取得したユーザー情報には最新のツイートも含まれているので、RTの有無もだいたいチェックできます
Mac初期設定

一気に2台のMacの環境構築を行うことになったのでメモ
個人的な初期設定

- 不要なDockの削除
- ターミナルをHomebrew、透過55%でデフォルト設定
- Finderのサイドバーにホームディレクトリの追加

```
chflags nohidden ~/
```
- Finderに隠しファイルの表示

```
defaults write com.apple.finder AppleShowAllFiles TRUE
killall Finder
```

- Homebrew設定

```
xcode-select --install
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
brew tap homebrew/cask
brew tap homebrew/cask-versions
```

- 使用モジュールインストール

```
brew install \
curl \
coreutils \
findutils \
tree \
gnu-sed \
graphviz \
awscli \
docker
brew tap heroku/brew && brew install heroku
```

- 使用アプリインストール

```
brew install \
google-chrome \
sublime-text \
iterm2 \
slack \
libreoffice \
postman \
visual-studio-code \
clipy \
docker \
zoom \
xmind --cask
```

- Dockに追加

```
open -a '/Applications/Google Chrome.app'
open -a '/Applications/Slack.app'
open -a '/Applications/Sublime Text.app'
open -a '/Applications/LibreOffice.app'
open -a '/Applications/Visual Studio Code.app'
open -a '/Applications/Clipy.app'
```

- タブに固定 or ブックマーク  
  - gmailログイン  
  - slackログイン  
  - リポジトリサービスログイン  
  - cacooログイン  
  - チケット管理ツールログイン  
  - Qiitaログイン
  - simplenoteログイン

- Chrome拡張設定
  - ato-ichinen  
  - ColorPick Eyedropper  
  - Wappalyzer  
  - OneTab  
  - EditThisCookie  
  - WPSNIFFER  
  - JSONView  
  - Google Apps Script Github アシスタント  
  - Vimium  
  - Google 翻訳  
  - Full Page Screen Capture

## 雑感
dotfilesやシェル化できればもっと良いんだけど..
gitでcommit間の差分を出力する

使わないと意外と忘れるのでメモ。
せっかくなので実務でよく使う関連するコマンドと組み合わせて使うケースも紹介します。

# 基本編
## 二つのcommit間の差分を出力
```bash
git diff <コミットID1> <コミットID2>
```

差分を比較したい二つのコミットのコミットIDを指定してあげればOK。
コミットIDは`git log`で確認しましょう。

## 現在のブランチの状態からの差分を出力
```bash
git diff <コミットID1>
```

現在のブランチの状態から特定のコミットまでの差分比較であればコミットIDを一つだけ指定してあげればOK。

## 二つのcommit間で差分があるファイル名の一覧を取得
```bash
git diff --name-only <コミットID1> <コミットID2>
```
`--name-only`オプションでファイル名のみの出力も可能。
現在のブランチの状態からみた時に差分があるファイル名を取得したい場合はコミットID1だけを指定すればいいですね。

# 応用編
## 二つのcommit間の差分をファイルを指定して出力
```bash
# ファイル名一覧取得
git diff --name-only <コミットID1> <コミットID2>

# ファイル名を指定して差分出力
git diff <コミットID1> <コミットID2> <ファイル名>
```

比較する二つのコミット間で変更されたファイルの数が多い場合などは差分出力しても何が何やらということがあるため、ファイル名だけ先に出力しファイル指定で差分を出力するケースです。
「変更されたファイルがそもそも少ない」という場合や「多くても全部出したい」という場合は基本編の通りコミットIDの出力だけで十分ですね。

# おまけ
`git diff` にて比較対象のコミットを指定する<コミットID1>と<コミットID2>は指定順によって差分出力時の時系列を変更することもできます。
下記のような差分がある二つのコミットを比較する場合の例を見てみましょう。

```bash
git log --oneline
bbbbbbbbb コミット2
aaaaaaaaa コミット1

git diff aaaaaaaaa bbbbbbbbb
-コミット1
+コミット2
```

コミットの時系列的にはコミット1→コミット2なので正しいですね。
次はdiffのコミットIDの指定順を入れ替え

```bash
git diff bbbbbbbbb aaaaaaaaa
+コミット1
-コミット2
```

上記のように削除を表す-と追加を表す+が逆になるという結果となりました。
これは単純にdiffするときにコミットID1からコミットID2への変更点を出力しているからですね。
ちょっと考えればわかるだろ!って感じかもですが、diff取ったときに想定していたものと違う差分が出るとびっくりする時があるから覚えておくとそういう時に幸せになれるかもしれない。
ARKit + Visionで四角形を検知するときの注意点（サンプルコード付き）


## 背景

[前回の投稿](https://qiita.com/noby111/items/056735063a42493c6b63)でARKitとVisionを使ってARKitの入力から四角形検知を行う方法を紹介したが、次の問題点があった。

- iPadの横画面ではうまく四角形を検知（重ねて表示）できるが、タブレットの縦画面では四角形がズレてしまう
- iPhoneでは縦横両方とも四角形がズレてしまう

長らく原因調査を放置していたが、原因が分かったので注意点とサンプルコードを公開する。

## 理由

- ARFrameのcapturedImageをVNImageRequestHandlerで処理する際に画像のorientationを指定していなかった
- ARFrameのcapturedImageを任意のViewに表示するためのAffine変換を取得する[displayTransform()](https://developer.apple.com/documentation/arkit/arframe/2923543-displaytransform)を使わず、自前でAspectを計算していた

### capturedImageはデバイスの向きに関わらず、Landscape

ARFrameより取得できるcapturedImageはデバイスの向きに関わらず、Landscapeになる。```VNImageRequestHandler(cvPixelBuffer: CVPixelBuffer, orientation: CGImagePropertyOrientation, options: [VNImageOption : Any] = [:])```で入力画像のorientationを指定できるが、これを正しく指定を行なわないと後の処理で四角形がズレてしまう。capturedImageはY座標が反転しているようで、[.donwMirrored](https://developer.apple.com/documentation/imageio/cgimagepropertyorientation/downmirrored)を指定することでズレが解消された。

### Affine変換は自前で計算せずに、displayTransform()を使う

動作させるデバイスによって大きさは変わるが、大抵画面上のARSCNViewの縦横の大きさはcapturedImageの大きさと一致しない。さらに都合が悪いことに大抵縦横のアスペクト比も異なる。そのためcapturedImage上で検知した四角形をARSCNView上に描画するにはAffine変換を行う必要がある。iPadの縦画面だけであれば、なんとか計算して合わせることができたが、横画面やiPhoneのように縦横の比率が変わると条件が複雑になり、自前で計算することはほぼ不可能である。（あくまでも私の個人的な意見だが）そのようなときに備えてなのか[displayTransform()](https://developer.apple.com/documentation/arkit/arframe/2923543-displaytransform)というメソッドが用意されている。これを使えば任意のサイズのCGRectに合わせたAffine変換を自動で生成してくれる。そのタイミングの画面のorientationを指定してやる必要があるが、適切な引数を指定すれば、iPhoneでもiPadでもどんな向きでも四角形を重ね合わせることができた。


## サンプルコード

github上に改善版の[ソースコード](https://github.com/nob3rise/RealTimeRectangleDetection)を公開しましたので興味がある方はお試しください。

## サンプルキャプチャ

![landscape.png](https://qiita-image-store.s3.amazonaws.com/0/200963/16d5aae6-6350-c5e5-d273-2fea7754cb0c.png "landscape.png")
どくしょかんそうぶん#孫子

# 前置き
### 動機
高校生のころに読んだ孫子を改めて大人になって読んでみました！
そのアウトプットにQiitaを使用させていただきます。（迷惑）

### 構成
この記事では孫氏とは？みたいな全体的な概要を述べて、各論は以下の記事で語っていこうかなと思います。

# 孫氏とは？
- 中国で最も古く最も優れた兵法書といわれている
- 「七書」に数えられる名著で、孫氏以外の七書は孫子を参考にしているといわれる兵法書の総元締
- 春秋時代（紀元前770年～紀元前5世紀ぐらい、縄文時代らへん）に呉の孫武の教えをまとめた本
- 孫子は13章にわかれて書かれている
- 兵法書だけど戦争する前にやることやって戦争を回避しろみたいな話が多い

# 13章の概要は？
1. [計篇](https://qiita.com/gosutesu/items/5c48c892a32ec68dc162)  戦争前によく考えることで、全体の序論みたいな立ち位置
2. 作戦篇　戦争を始めるためのお金とか人の準備の話
3. 謀攻篇　戦わないで勝つ話
4. 形篇　攻守の態勢の話（たぶん、陣形とか）
5. 勢篇　攻守の態勢から得られる効果の話（陣形の意味的な？）
6. 虚実篇　攻守の態勢から得られる戦争の主導権の話
7. 軍争篇
8. 九変篇
9. 行軍篇
10. 地形篇
11. 九地篇
12. 火攻篇
13. 用間篇
「AtCoderで提出数が多い言語」ランキング

# はじめに
自分はいつもPythonを使ってAtCoderのコンテストに参加しています。
自分の身の周りでもPythonでAtCoderをやっている人が多いのですが、参加者全体ではどのプログラミング言語が人気なのか気になったため、調べてみました。
**(本記事では、2019年1月での状況を集計しています。)**
# 調べ方
調べ方は、次の通りです。
### 利用したもの
言語: Python3 (APIで情報収集, matplotで統計グラフを作成)
データ収集: [AtCoder非公式API](https://github.com/kenkoooo/AtCoderProblems/)
### 集計方法
上記のAtCoder非公式APIで提供されているAccepted Count for each langagesを利用することで、ユーザーごとの言語別の解答提出数を取得することができます。
言語ごとに、各ユーザーの提出数を足し合わせて、**言語ごとの提出数の合計**を計算しました。

# 結果
提出数が多かった言語上位7つをグラフにして可視化しました。
### 1位は圧倒的にC++
![Unknown.png](https://qiita-image-store.s3.amazonaws.com/0/257347/fa4eaa41-85ff-ab61-fac8-c37344c2321d.png)
一番多かったのは予想通りC++で、提出数で2位のPythonと5倍近くの差をつけての1位でした。
C++は競技プログラミングの公式言語と言えるポジションであり、実行速度が速いことや、 蟻本をはじめとした競技プログラミング関連の解説コードがC++で説明されることなどからこのような結果になったのかと思われます。(それにしても圧倒的ですね)
### 2位から8位の言語
![Unknown-1.png](https://qiita-image-store.s3.amazonaws.com/0/257347/aa969cc2-b7d5-33d3-4592-84663e205bb0.png)
C++が圧倒的に1位でしたが、次はC++を除いた2位から8位の言語を見ていきます。
2位はPythonで3位のJavaに2倍以上の差をつけていました。
3位のJavaはC++と同様に実行速度が速く，競技プログラミング関連でも利用者が多いイメージでしで、個人的にはC++についで2位にランクインすると予想していましたが、Pythonに負けていました。
### Pythonは人気
![Unknown-2.png](https://qiita-image-store.s3.amazonaws.com/0/257347/17d8bc71-4053-c263-5df0-64f79992393e.png)
C++を除いた2位から8位の言語の提出割合を円グラフで可視化しました。
2位から8位の言語では、 Pythonが45%ほどを占めています。
Pythonの人気な理由として、文法のシンプルさ、PyPyでの高速化、充実した標準ライブラリなど、初心者から中上級者まで、扱いやすい特徴を備えている点が考えられます。


# 今後
今回はできなかったのですが，レート別でのランキングも調べてみたいです。
おそらく、上位のレート帯ほどC++の使用割合が増え、下位になるほど多様な言語が利用されていると思われます。

# [追記]2019年7月
2019年3月ごろからAtCoder人口が急増したことを踏まえ、2019年7月では、どのように変化したのかが気になったため、再度調べてみました。

### 提出数が急増
![Unknown.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/257347/fd264c9a-68be-c131-7f6e-71dc50ddb2b9.png)

2019年1月時点では、1位のC++の提出数が約10万件、2位のPythonが約2万件だったのに対して、2019年1月時点では、**たった半年で、C++が約16万件と1.6倍ほどに、Pythonは約5万件と、2.5倍ほどになっています。**

また、Pythonを利用している人が多いようで、2019年1月時点では9位だったPyPyも7位にまで上がっています。Python自体の提出数も、3位以下の言語との差を広げています。
kintone の住所から緯度・経度を取得して地図を表示

## 処理内容
・kintone に入力した住所（ポイント名）を追加する前に、緯度・経度を取得しセットします。
・kintone 詳細画面でセットされた緯度・経度の地図を表示します。
## 完成画面
ポイント名を入力し「保存」後に、詳細画面で表示した地図。
![kintoneMap01.png](https://qiita-image-store.s3.amazonaws.com/0/75892/d2cde8ec-69b0-fb26-fcbd-a7a2a7ef9579.png)
## 設定画面
### 画面デザイン
地図を表示する部分はスペースで設定しておく。
![kintoneMap02.png](https://qiita-image-store.s3.amazonaws.com/0/75892/3de7b773-9420-3e35-e7f6-8ae17c5f0a2f.png)
### JavaScript ファイルアップロード
以下のJavaScriptカスタマイズファイルをアップロード。
![kintoneMap03.png](https://qiita-image-store.s3.amazonaws.com/0/75892/f74628f9-e1a5-4d13-971b-3e6d64699e2e.png)
## kintone の JavaScript コード
```javascript:kintoneGoogleMap.js

(function() {
	"use strict";
	
	// Google Map の指定
	var script = document.createElement('script');
	script.src = 'https://maps.googleapis.com/maps/api/js?key=<KEYを設定>';
	document.body.appendChild(script);
	
	// 追加・更新画面処理
	kintone.events.on(['app.record.create.submit','mobile.app.record.create.submit',
	'app.record.edit.submit','mobile.app.record.edit.submit'], 
	function(event) {
		var record = event.record;
		if (record['緯度']['value'] > 0 || record['経度']['value'] > 0) {
			return event;
		}
		
		// 緯度・経度を取得（同期処理）
		return new kintone.Promise(function(resolve, reject) {
			var geocoder = new google.maps.Geocoder();
			geocoder.geocode({'address': record['住所']['value']}, function(results, status){
				if(status == google.maps.GeocoderStatus.OK) {
					var lat = results[0].geometry.location.lat();
					var lng = results[0].geometry.location.lng();
					// 小数点第6位以下を四捨五入した値を緯度経度にセット
					record['緯度']['value'] = (Math.round(lat * 1000000) / 1000000).toFixed(6);
					record['経度']['value'] = (Math.round(lng * 1000000) / 1000000).toFixed(6);
				}
				resolve(event);
			});
		});
	});
	
	// 詳細画面処理
	kintone.events.on('app.record.detail.show', 
	function(event) {
		var record = event.record;
		if (!record['緯度']['value'] && !record['経度']['value']) {
			return event;
		}
    	
		var latY = record['緯度']['value'];
		var lngX = record['経度']['value'];
		
		var mapElement = kintone.app.record.getSpaceElement('map_latlng');
		var mapElementDiv = document.createElement('div');
		mapElementDiv.setAttribute('id',   'map');
		mapElementDiv.setAttribute('name', 'map');
		mapElementDiv.setAttribute('style', 'width: 800px; height: 400px');
		mapElement.appendChild(mapElementDiv);
		
		// マップの表示(経度、緯度、倍率、最大倍率)
		dysplayMap(lngX, latY, 18, record['住所']['value']);
	});
	
	// Google Map の表示
	function dysplayMap(fx,fy,zoom,pointName){
		
		var point = new google.maps.LatLng(fy,fx);
		var opts = {
			zoom: zoom,
			center: point,
			mapTypeId: google.maps.MapTypeId.ROADMAP,
			scaleControl: true
		};
		
		var map = new google.maps.Map(document.getElementById('map'), opts);
		var marker = new google.maps.Marker({
			position: point,
			map: map,
			title: pointName
		});
	}
})();

```
## 参照情報
【2018年7月16日版】Google Maps の APIキー を取得する ( https://nendeb.com/276 )
Google Maps JavaScript API ( https://developers.google.com/maps/documentation/javascript/tutorial?hl=ja )
Google Maps API の使い方・利用方法 ( http://www.webdesignleaves.com/pr/plugins/googlemap_01.html )
Google Maps API入門 ( https://www.ajaxtower.jp/googlemaps/ )
Gradle Swagger Generator PluginでAPI文書の展開レベルを変更する

[Gradle Swagger Generator Plugin](https://github.com/int128/gradle-swagger-generator-plugin) を使ってAPIドキュメントを生成する場合に、初期状態の展開レベルを変更する方法を紹介します。

## 前提

ここでは、 [SpringFox](http://springfox.github.io/springfox/) のようにソースコードからAPIドキュメントを生成するケースではなく、手書きしたYAML形式のSwaggerドキュメントからSwagger UI形式のAPIドキュメントを生成するケースを想定しています。

動作確認したソフトウェアのバージョンは次の通りです。

* Oracle JDK 1.8
* Gradle 4.10
* Gradle Swagger Generator Plugin 2.16.0

## カスタマイズ前

`doc/api.yaml` にAPIドキュメントがあるとして、Swagger UIを生成するための設定はおおむね次のようになっているはずです。

```gradle
plugins {
    id 'org.hidetake.swagger.generator' version '2.16.0'
}

dependencies {
    swaggerUI 'org.webjars:swagger-ui:3.20.3'
}

swaggerSources {
    api {
        inputFile = file('doc/api.yaml')
    }
}
```

Swagger UI形式のAPIドキュメントを生成してブラウザで確認すると、すべてのエンドポイントが完全に展開された状態になることが分かります。最初のうちはこれでも問題ありませんが、APIの数が増えてくると全体が把握しづらくなります。

```shell
$ ./gradlew generateSwaggerUI
$ open build/swagger-ui-api/index.html
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/33668/6e8af673-b842-a6fe-61e6-474f91a694ee.png)

## カスタマイズ後

そこで、 [公式ドキュメント](https://github.com/int128/gradle-swagger-generator-plugin#configure-swagger-ui) に従って設定をカスタマイズします。プラグインの設定としてカスタマイズできるわけではなく、カスタマイズ済みのSwagger UIのHTMLファイルを用意してプラグインに組み込むという点がポイントです。

1. Swagger UI 公式ページから [index.html](https://github.com/swagger-api/swagger-ui/blob/master/dist/index.html) を取得する
2. Gradle Swagger Generator Plugin に組み込めるようindex.htmlを修正し、設定値をお好みでカスタマイズする
    * 設定値の一覧 → https://github.com/swagger-api/swagger-ui/blob/master/docs/usage/configuration.md
    * ここでは、展開レベル (`docExpansion`) を `full` → `list` に変更している
 
    ```diff
    diff --git a/doc/index.html b/doc/index.html
    index 549f5f3..163140a 100644
    --- a/doc/index.html
    +++ b/doc/index.html
    @@ -40,6 +40,10 @@
         window.onload = function() {
           // Begin Swagger UI call region
           const ui = SwaggerUIBundle({
    +        spec: window.swaggerSpec,   // (mandatory) use source of swagger-spec.js
    +        validatorUrl: null,         // (mandatory) disable validator
    +        docExpansion: 'list',       // expand only the tags
    +
             url: "https://petstore.swagger.io/v2/swagger.json",
             dom_id: '#swagger-ui',
             deepLinking: true,
    ```

1. カスタマイズしたindex.htmlでデフォルトのindex.htmlを上書きする

    ```diff
    diff --git a/build.gradle b/build.gradle
    index 0aadabc..286e95b 100644
    --- a/build.gradle
    +++ b/build.gradle
    @@ -49,5 +49,13 @@ jacocoTestReport {
     swaggerSources {
         api {
             inputFile = file('doc/api.yaml')
    +        ui {
    +            doLast {
    +                copy {
    +                    from 'doc/index.html'
    +                    into outputDir
    +                }
    +            }
    +        }
         }
     }
    ```

再度、Swagger UI形式のAPIドキュメントを生成してブラウザで確認すると、今度はAPIエンドポイントの一覧が見出し（タグ）レベルだけで表示されるようになっていることが分かります。

```shell
$ ./gradlew generateSwaggerUI
$ open build/swagger-ui-api/index.html
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/33668/52be9f18-1d91-963c-c3ad-b699aa797b49.png)

展開レベルの変更だけに限らず、ほかのカスタマイズも同様の手順で実現できると思います。
C#でbinaryでDateTimeを読み書き

# 目的
時系列でデータをファイルに記録していく際に、記録時刻もつけて保存することがあります。これを人間がわかりやすいようにText形式で書き込んだりすると、ファイルサイズが増えるだけではなくて、読み込みの際の手間が増えてしまいます。面倒くさがりの私は、これをなるだけ楽にできるようにしました。

#　方法
FileStream, BinaryWriterを使うところは他の方が書かれているものと同じです。

##### 書き込み
DateTime は基準時刻（ここではUNIXのEPOCH TIME 1970/1/1 00:00:00）からの時間をmillisecond単位を得て、この時間をdoublea型の変数として、書き込みます。

##### 読み込み
FileStreamで一度にファイルを読み込みます。もしフィアルサイズが大きくて、一度に読み込めない場合は、 FileStream.Read でoffset, countを指定することで分割して読み込むことができます。
Binary　dataは　byte[]形式で　読み込み、そのデータをBitConverterを使って、元の変数に戻します。

`Write code'
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;

static void Main(string[] args)
        {
            FileStream fs = new FileStream("test.bin", FileMode.Create);  
            BinaryWriter bw = new BinaryWriter(fs);                        
            DateTime refTime = new DateTime(1970, 1, 1, 0, 0, 0);       
            int s;                                                       
            unsafe                                                        
            {
                s = sizeof(DateTime);
                Console.WriteLine(s.ToString());
            }

            for ( UInt64 i = 0; i < 10; i++)
            {
                DateTime Now = DateTime.Now; 
                TimeSpan dt = Now - refTime;    
                double timeVar = dt.TotalMilliseconds;  
                bw.Write(timeVar);  
                bw.Write(i);   

                Console.WriteLine(timeVar.ToString() + " " + i.ToString());
                System.Threading.Thread.Sleep(950);    

            }

            Console.ReadLine();

            fs.Close();   
        }
    }
}


'Read Code'
using System;
using System.IO;

namespace readBin
{
    class Program
    {
        static void Main(string[] args)
        {

            Uri startupPath, targetPath;

     
            FileStream fs = new FileStream("../../../../writeBin/bin/Debug/test.bin", FileMode.Open, FileAccess.Read);
            

            byte[] buf = new byte[1000];  // define buffer
            fs.Read(buf);                 // read binary file   
              fs.Read()
            double timeVar;             
            DateTime Now;
            DateTime refTime = new DateTime(1970, 1, 1, 0, 0, 0); // Unix EPoch time
            
            UInt64 count;

            for (int i = 0; i < 10; i++)
            {
                timeVar = BitConverter.ToDouble(buf, i * 16);   
                count = BitConverter.ToUInt64(buf, i * 16 + 8);
                Now = refTime.AddMilliseconds(timeVar);
                double micro = timeVar % 1000;
                Console.WriteLine(Now.ToShortDateString() + " " + Now.ToLongTimeString() + ":" + micro.ToString() +" " + count.ToString());
            }

            Console.ReadLine();
        }
    }
}
スクロールでheaderをfadeInさせる方法。

#【jQuery】スクロールでheaderをfadeInさせる方法
スクロールした際、headerをfadeInさせる方法です。
参考サイトはこちらです。
[Olta](https://www.olta.co.jp/)

##ゴール
スクロールした際、本来とは違う、別に作ったheaderをfadeInさせる。

##考え方
- fadeInさせたいheaderを用意する(header-cloneとする)
- 本来のheaderに重ね非表示にする
- スクロールしたときheader-cloneをfadeInさせる

##コード
```index.html
<header id="header">
      <!-- hrader開始 -->
      <div class="header-first">
        <div class="header-call ">
          <img class="call" src="../images/icon-tel.svg" alt="">
          <p>050-3205-1008</p><sapn id="time">（10:00~18:00 土日祝日除く）</span>
          </div>
          <div class="global-nav">
            <ul>
              <li>運営会社</li>
              <li>よくある質問</li>
              <li>ログイン</li>
            </ul>
          </div>
      </div>
    </header>
    <!-- header終了 -->

      <!-- header-clone開始 -->
      <div class="header-clone">
        <div class="header-call-clone">
          <img class="logo-clone" src="../images/logo.svg" alt="">
          <img class="call-clone" src="../images/icon-tel.svg" alt="">
          <p>050-3205-1008</p><sapn id="time">（10:00~18:00 土日祝日除く）</span>
        </div>
        <div class="global-nav-clone">
          <div class="list-4"><a href="">無料登録して申し込む</a></div>
          <ul>
            <li>運営会社</li>
            <li>よくある質問</li>
            <li>ログイン</li>
          </ul>
        </div>
      </div>
      <!-- header-clone終了 -->

```

```style.css
.header-clone {
  height: 90px;
  background-color: #fff;
  display: none;
  position: fixed;
  top: 0px;
  width: 100%;
  z-index: 1;
}
```

```javascript

$(function() {
  var $window = $(window),
      $clone = $('.header-clone'),
      threshold = 0.1;

      $window.on('scroll',function(){
        if($window.scrollTop() > threshold) {
          $clone.fadeIn();
        }else{
          $clone.fadeOut();
        }
      });
});

```

##解説
まずheader-cloneを作成しcssでposition: fixed;を指定し、本来のheaderの上に重ねます。（fixedは重ねるためのプロパティではありません。画面の決まった位置に固定させたいときに使うプロパティです。）


それができたら、今はまだ重なっているだけなので、display: none;を指定し、header-cloneを非表示にしましょう。
これで、fadeInさせる準備は完了です。

次はjQueryです。

windowオブジェクトを変数＄windowに格納しましょう。
続いて、header-cloneを$cloneへ格納しましょう。（新たに作ったfadeInさせたいheaderです）
最後に0,1という値をthresholdに格納して変数は終わりです。

関数の処理に移ります。
したいことは「スクロールしたとき・・・」です。
なのでwindow.on('scroll',function(){});とすることで、スクロールしたときの処理をかけるようになります。

ここではif文を使います。
if文を訳すと、「もし、0,1以上スクローしたら・・・」です。
なのでif($window.scrollTop() > threshold)とします。

scrollTop()は現在のスクロール量を取得できるメソッドなので、if文で現在のスクロール量と0,1を比較している状態を作っているんですね。

後は条件通りにfadeInさせるだけです。

##まとめ
まず実装したいことを明確にし、それらを細かく分けていきましょう。
今回なら、実装したいことはスクロールしたらheader-cloneをfadeInさせるでした。

ここで考えるのは、「どんな時に」「どんなタイミングで」です。

こんな風に条件を細かく分ければ、コードが見えてくるのではないかなと思います。

なんせ独学なので、もっといい考え方やコードがあれば教えてください。
閲覧ありがとうございました。