OmniAICreator/Qiita-1.07M huggingface dataset:
vagrantで同期機能を使うと、ゲスト側でファイルやフォルダーが消せなくなる

#vagrantの同期機能とは

vagrantfileをこんな感じでいじると・・・

```ruby
  # Share an additional folder to the guest VM. The first argument is
  # the path on the host to the actual folder. The second argument is
  # the path on the guest to mount the folder. And the optional third
  # argument is a set of non-required options.

  config.vm.synced_folder "./src", "/home/src"
```
第一引数に指定したホスト側フォルダーと、第二引数に指定したゲスト側が同期される。

#第二引数で指定した仮想側フォルダーは消せなくなる。
その理由はvagrantのプロセスがそのフォルダーを掴んでいるから。


#なぜそんなことになったか・・・
python3をゲストOSに入れて、さらにvenvを用いてゲストOS内に仮想環境を構築した。
そのvenvで作成したフォルダとHOST側の任意のフォルダをvagrantの同期機能で同期しておけば、ホスト側の編集したファイルを仮想環境ですぐ実行できるかなと思ったわけだ。

それはいいのだが、環境作り直そうと、ゲストOS側のvenvで作成したディレクトリを消そうととしたら、消せませんと言われて悲しくなった。

#対策
一旦 vagrantfileの同期設定部分をコメントアウトして立ち上げなおすと、同期解除された状態になる。
それでようやく、

```bush
rm -rf ./xxxxx

```

みたいなことができる。

※仮想環境へのアプローチも含め、このvagrantの同期onoff切り替え等他に何かいい方法があれば教えてください。切実。
[C#] ファイルの出力

#ファイルの出力

```
FileInfo fi = new FileInfo(GlobalVariable.custom_csv_path);
using (StreamWriter sw = fi.AppendText())
{
sw.Write("OUTPUT SOMETHING");
}
```

usingが使いたくないなら、以下のように自分でcloseしなければいけないらしい。これは面倒だ。
usingを使うと、usingを抜ける際に自動的にやってくれるらしい。

```
FileInfo fi = new FileInfo(GlobalVariable.custom_csv_path);
StreamWriter sw = fi.AppendText();
sw.Write("OUTPUT SOMETHING");
sw.Flush();
sw.Close();
```
[Unity] ファイル置き場、各場所からのファイルの入力



#ファイルの置き場所(Unity PCとスマホ実機の違い)
Resourceフォルダならいいんだけど、Resourceフォルダ外でやる場合はたぶん場所が違うので不都合が起きる。


```
#if UNITY_EDITOR
    private static string custom_csv_path_ = "C:/default.csv";
#elif UNITY_ANDROID || UNITY_IOS
    private static string custom_csv_path_ = Application.persistentDataPath + "/default.csv";
#endif
```

#ファイルの入力(読み込み)
##Resourceフォルダから

```
string file_name = "default";
TextAsset ta = Resources.Load(file_name, typeof(TextAsset)) as TextAsset;
string read_data = ta.text;
```

##外部フォルダから
```
        string read_data = "";

        FileInfo file_info = new FileInfo("C:/default.csv");

        try
        {
            using (StreamReader sr = new StreamReader(file_info.OpenRead(), Encoding.UTF8))
            {
                // 最初から最後まで全部読み込む
                read_data = sr.ReadToEnd();
            }
        }
        catch (Exception e)
        {
            //ここにエラーメッセージを書く？
        }
```
これだけは絶対に参加したい国内の最重要テック・カンファレンス5選（2018年版）

めちゃくちゃ有用な情報をゲットできる以下の国内最重要テック・カンファレンスの開催概要をまとめてみました。

1. Developers Summit
1. SLUSH TOKYO
1. TECH IN ASIA TOKYO
1. CEATEC JAPAN
1.  TechCrunch Tokyo

## 1. Developers Summit

![](https://encrypted-tbn1.gstatic.com/images?q=tbn:ANd9GcQSl85x73ra2BT88bYEGfz617DBm8o9qkgPGpaTi46IiJkD0uyVOdFnYPe2)

スポンサーとしてGoogle, Salesforce, ORACLE, Microsoftなどの「デジタル・ジャイアント」に加え、GitHubやTrelloなどの著名なベンチャー企業が名を連ねるカンファレンスです。ハンズオンでは最新技術を実際に開発しながら学ぶこともできます。

### 開催概要
* 2/15（木）、2/16（金）
* ホテル雅叙園東京
* 参加費無料（事前登録制）

### スピーカー
* 『はじめてのAmazon Alexaスキル開発』、畠中 俊巳（アマゾンジャパン）
* 『Kubernetesでミッションクリティカル・システムを実現するための設計／実装ノウハウ』、早川博（日本オラクル）
* 『Gitで安定マスターブランチを手に入れる』、井上 誠一郎（ワークスアプリケーションズ）

など

---
-  [ Developers Summit 2018](http://event.shoeisha.jp/devsumi/20180215/)
  
## 2. SLUSH TOKYO

![](https://lh4.googleusercontent.com/proxy/-oOQ1vw52yjkVGh5XoE4kn7v2U_5d7AojiozjjBxkzQOIqMIpsdyYtn3CWwGPMCG-WmFo3Zddhwp77X4Kkv3T8H3mvYTDD_WfoZKTRzThSOn=w512-h288-nc)

全てのセッションが英語でスピーチされるフィンランド発祥の世界最大級のスタートアップイベントです。会場はロックフェスのような演出がなされていて、他のカンファレンスとは一線を画しためちゃくちゃクールなイベントです。

### 開催概要
* 3/28（水）、3/29（木）
* 東京ビッグサイト
* CONFERENCE PASS: 19,500円

### スピーカー

* Stefan Thomas（Ripple, Inc., CTO）
* 辻 庸介（株式会社マネーフォワード, CEO）
*  山内奏人（ワンファイナンシャル株式会社, CEO）

など 

---

* [Slush Tokyo 2018 - Slush Tokyo](http://tokyo.slush.org/)
* [世界最大級のスタートアップイベントが来年も「Slush Tokyo 2018」として、3月28-29日に東京ビッグサイトにて開催](https://www.google.co.jp/amp/s/prtimes.jp/main/html/rd/amp/p/000000012.000013477.html)

## 3. TECH IN ASIA TOKYO

![](https://encrypted-tbn1.gstatic.com/images?q=tbn:ANd9GcQgLanQ-0qjGf3iIQkgc0UAtsdTP1Plym1VgbIjjC7c-w_whsMNW4DfTYYn9g)

アジアに焦点を当てた技術情報を提供し月間1000万PVを誇るメディア「Tech in Asia」が開催する、アジア最大級のスタートアップイベントです。毎年、シンガポール・東京・ジャカルタの3都市で開催されています。

### 開催概要
* 9月下旬
* 会場未定
* 一般パス: 44,700円

### スピーカー（2017年）
* 狩野雄三（株式会社bitflyer, CEO)
* James Riney (500 Startups Japan, Managing Director)
* Alexis Zheng (Uber, Product Lead)

など

---

* [Tech in Asia - Connecting Asia's startup ecosystem](https://www.techinasia.com/events/tokyo)
* [Tech in Asia Tokyo 2017 - ​スピーカーリスト｜Tech in Asia Japanのプレスリリース](https://www.google.co.jp/amp/s/prtimes.jp/main/html/rd/amp/p/000000046.000014933.html)


## 4. CEATEC JAPAN

毎年開催される度に様々なメディアで取り上げられる、出展者数600社以上の超大型展示会です。時間がどれだけあっても足りないくらい充実したブースやセッションが用意されています。

![](https://encrypted-tbn2.gstatic.com/images?q=tbn:ANd9GcRCjWeiAm0VN_RZGqLhOIG2bCq9P_2XafkmyvYfMGt9h1MxwyQvENfIaQm6)

### 開催概要
* 10/16（火）〜10/19（金）
* 幕張メッセ
* 参加費無料（事前登録制）

---

[CEATEC JAPAN ( シーテック ジャパン 公式サイト )](http://www.ceatec.com/ja/)

## 5. TechCrunch Tokyo

![](https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSQR7P9CMqD-Q81Z6-7nwA14AMXdL0TuGBxEENiV-i5aJjebpJQo9Fc30e4)

米国を本家とする主要ITメディア「TechCrunch」が主催するイベントです。国内外のスピーカーによるセッションに加えて、目玉企画であるスタートアップ企業のピッチコンテスト「スタートアップバトル」が毎年開催されます。

### 開催概要
* 11月中旬
* 会場未定
* 一般チケット: 40,000円

### スピーカー（2017年）
* 『「カンバン方式」のアプリ化でタスク管理の定番となったTrelloの軌跡』、Michael Pryor（Trello, Head of Product）
*  『いよいよ日本上陸、Google Home搭載の会話型AIの未来』、Brad Abrams (Google Assistant,  Group Product Manager)
* 『“モノを瞬時に現金化” 注目アプリ「CASH」、連続起業家の新たな挑戦』、光本勇介（株式会社バンク, CEO）  

など

---

- [TechCrunch Tokyo 2017  |  TechCrunch Japan](http://jp.techcrunch.com/event-info/techcrunch-tokyo-2017/)
[備忘録]Unity で始める C# その4 脱出ゲームを作ろう

**実際に作業して気づいたポイント**

・Assetフォルダには種類ごとにスクリプトやシーンを分けたほうがよい。
→[Resources][Scenes][Scripts]のように分ける。それぞれ、「画像とサウンド」　「シーン」「スクリプト」を入れる。

・Unityなどでボタンなどの操作できる部品を作る機能を**UnityUI(通称uGUI)**という。これを利用することでゲーム画面にボタンやテキストボックス、チェックボックスなどを配置できる。シューティングゲームの武器選択や、RPGのアイテム倉庫画面を作るのに向いている。

・**Canvas（キャンバス）**とはボタンなどの部品を配置する土台となるパーツ。**透明**で表示されないが、ボタン類をキャンバスの子OBとして配置すれば、まとめて移動したりサイズ変更したりできて便利。

・CanvasなどのUnityUI関連のGOを追加するとEventSystemというGOが追加されるが残しておくこと。

・作成したCanvasをヒエラルキーでみると、ゲーム画面より遥かにでかくなっている。単位の基準があっていないので、直してやる。**もともとの「ゲーム画面」はMainCameraGO、つまりカメラがうつす範囲。**だからキャンバスの設定を変更して**カメラの範囲内に収まるように調整**してあげればゲーム画面と合うようになる。

```:手順
Canvasをインスペクターでいじる。
[Canvas]コンポーネントの[Render Mode]を[Screen Space - Camera]に変更。
次にMain CameraOBを[Render Camera]にD&D。
[Canvas Scaler]コンポーネントの[UI Scale Mode]を[Scale with Screen Size]を選択し、
[Referrence Resolution]を画面のサイズに調整してあげる。Matchを1(Height)に変更（今回は高さを揃えて幅を変更するようにした）。
```
**解説**
Canvasコンポーネントはキャンバスの機能そのものを提供している。[Render Mode]を[Screen Space - Camera]にして参照するカメラを指定すると、**カメラの撮影範囲に収まるように**サイズ調整される。CanvasScalerコンポーネントはキャンバス上に配置したUIパーツのサイズを調整する。[UI Scale Mode]を[Scale with Screen Size]にした場合、[Referrence Resolution]に指定した解像度を基準に調整してくれる。Matchはん実機の画面サイズと[Referrence Resolution]の設定値が一致しない時の調整方法の設定で、1(Height)に変更すると、**高さを揃えて幅を変更するように**設定できる。

---
**背景を設置する**
キャンバスの上にUIパーツを配置していく。**ぬりつぶしや飾りとして画像を表示させる場合は、イメージを配置する**。UIパーツは通常のTransformコンポーネント（以下CP）の代わりに**RectTransformCP**を持っており、Anchor（アンカー）の種類によって位置かサイズを調整できる。

**・親OBと位置を合わせる→Anchorはストレッチ以外を選び、PosX,Y,Width,Heightで位置とサイズを指定**

**・親OBとサイズをあわせる→Anchorはストレッチを選択、Left,Right,Top,Bottomでパディング（余白）サイズを指定**

---
**タイトルを配置**
UIからテキストを選択。Posで位置を調整し、テキストに表示したい文字を入力。テキストCPでフォントサイズとAlignmentを調整すれば完成！


**ボタンを設置**
UIからボタンを選択。先程と同様に位置を調整。ボタンの文字を設定するには、ボタンの子OBになっているテキストを編集。ボタンには、クリックされたときにスクリプト内のメソッドを呼び出す機能がある。また、ボタンにはButtonコンポーネントをもっており、「クリックされたときに何かを実行する」というボタンの基本機能を実現させるCPである。**ボタンなどのUIパーツはイベントを持っており、そこのどのメソッドを呼び出すかを指定する。**
ちなみにボタンの場合は**OnClickイベント**をもつ。

**プログラムで次のシーンに切り替える**
ボタンにSceneManagerクラスのLoadSceneメソッドを呼び出して、指定したシーンを読み込む。

```:SceneManageクラスのLoadSceneメソッドの使い方　引用Unity公式
using UnityEngine;
using UnityEngine.SceneManagement;

public class ExampleClass : MonoBehaviour
{
    void Start()
    {
        // Only specifying the sceneName or sceneBuildIndex will load the Scene with the Single mode
        SceneManager.LoadScene("OtherSceneName", LoadSceneMode.Additive);
    }
}
```
"OtherSceneName"のところに移りたいシーン名を書く。

---

```:ボタンに付与するメソッドを定義
public void PushStartButton () {
		//TileManagerクラスに書かれた、PushStartButtonメソッド。ここで定義している。
		SceneManager.LoadScene ("GameScene");
	}
```

今日はゲームのタイトル画面作成と、他のシーンへの移行ができるようになった。
[Unity] Randomを取得する(UnityEngie.Random vs System.Random)

##ランダム
以下のエラーを受けることがある。
>error CS0104: `Random' is an ambiguous reference between `UnityEngine.Random' and `System.Random'

以下のサイトにすばらしい調査結果があるので必見。
http://developer.wonderpla.net/entry/blog/engineer/Unity_RandomNumber/

とりあえずUnityEngine.Randomでよさそう
[C#] 配列に対するfor ,foreach


配列でforeachで行うと、要素数全てに対して処理を行う。
https://docs.microsoft.com/ja-jp/dotnet/csharp/programming-guide/arrays/using-foreach-with-arrays

配列string[10,2]があった場合に、[i,0]に対して処理を行いたいなら
>for (int i = 0; i < array.GetLength(0); i++)
>{
>   array[i,0]の処理
>}


配列string[10,2]があった場合に、[0,i]に対して処理を行いたいなら
>for (int i = 0; i < array.GetLength(1); i++)
>{
>   array[0,i]の処理
>}
[C#] 配列の長さを取得する

new string[10, 2]

以下の配列になる（値をxとする)
x,x
x,x
x,x
x,x
x,x
x,x
x,x
x,x
x,x
x,x

Row(行)=10 , Column(列)=2

10が欲しいなら array.GetLength(0) -> 10
2が欲しいなら array.GetLength(1) -> 2
要素数が欲しいなら array.Length -> 20
emacsで快適なGo言語ライフを送るための設定

全ての言語をemacsで書きたい！
分かります、その気持ち。特にコード補完やハイライト、インデントの自動整形などの機能は必須ですよね。
今回はGo言語を快適に書くための設定をしてみました。
【参考】
[emacs でgolang編集環境を作る](https://qiita.com/bussorenre/items/3e80e59d517db8aebf46)

# 前提
・Go言語導入済みであること
・emacsにpackage.elが導入済みであること

# Go言語packageの入手
```bash:必要なパッケージをダウンロード
go get github.com/rogpeppe/godef # 関数定義等の参照パッケージ
go get -u github.com/nsf/gocode # 補完パッケージ
go get github.com/golang/lint/golint # flycheckでシンタックスエラーを検知
go get github.com/kisielk/errcheck # flycheckでシンタックスエラーを検知
```

go getコマンドでで$GOPATH配下にpackageがダウンロードされます。

# emacsへの各種packageの導入
Go言語のシンタックスハイライト用にgo-modeを、コード補完のためにcompany-goをemacsに導入しておきます。

```
M-x package-list-packages # packageリストを更新しておく
M-x package-install go-mode
M-x package-install company-go
```


# elispの設定
elispは最終的に下記の設定となりました。

```elisp:init.el
;; Goのパスを通す
(add-to-list 'exec-path (expand-file-name "/usr/local/go/bin/"))
;; go get で入れたツールのパスを通す
(add-to-list 'exec-path (expand-file-name "/Users/user/dev/go/bin/"))

;; flycheck-modeを有効化してシンタックスエラーを検知
(add-hook 'go-mode-hook 'flycheck-mode)
(add-hook 'go-mode-hook (lambda()
	   (add-hook 'before-save-hook' 'gofmt-before-save)
	   (local-set-key (kbd "M-.") 'godef-jump)
	   (set (make-local-variable 'company-backends) '(company-go))
	   (setq indent-tabs-mode nil)	  ; タブを利用
	   (setq c-basic-offset 4)	  ; tabサイズを4にする
	   (setq tab-width 4)))

;; company-modeとの連携してコード補完する
(require 'company-go)
(add-hook 'go-mode-hook (lambda()
	  (company-mode)
	  (setq company-transformers '(company-sort-by-backend-importance)) ;; ソート順
	  (setq company-idle-delay 0) ; 遅延なしにすぐ表示
	  (setq company-minimum-prefix-length 3) ; デフォルトは4
	  (setq company-selection-wrap-around t) ; 候補の最後の次は先頭に戻る
	  (setq completion-ignore-case t)
	  (setq company-dabbrev-downcase nil)
	  (global-set-key (kbd "C-M-i") 'company-complete)
	  ;; C-n, C-pで補完候補を次/前の候補を選択
	  (define-key company-active-map (kbd "C-n") 'company-select-next)
	  (define-key company-active-map (kbd "C-p") 'company-select-previous)
	  (define-key company-active-map (kbd "C-s") 'company-filter-candidates) ;; C-sで絞り込む
	  (define-key company-active-map [tab] 'company-complete-selection) ;; TABで候補を設定
	  (define-key emacs-lisp-mode-map (kbd "C-M-i") 'company-complete) ;; 各種メジャーモードでも C-M-iで company-modeの補完を使う
	  ))
```
サーボモーターで自動エサやりマシーンを作る（前半）

#サーボモーターって
ミニ四駆のモーターくらいしか知りませんでしたがモーターにも種類があるようです。
(電子工作を始めて知らなかった事が次々と出てくる。。)

- ACモーター　･･･　AC(交流)電源により動きます。　例) 家のコンセント
- DCモーター　･･･　DC(直流)電源により動きます。　例) 乾電池とかラズパイとかの電源
 - 一般的なモーター　･･･　一方向に対して回転し続けます。
 - サーボモーター　　･･･　指定した角度に回転します。行ったり来たり可能。

#サーボモーターとの接続と動かし方
今回はSG90という入門編っぽいサーボモーターを使うことにします。数百円で買えます。

## RaspberryPiとサーボモーターの接続方法
配線も3つしかないので迷う事は何も無いと思います。

|ラズパイGPIO|サーボモーター|用途|
|:--:|:--:|:--|
|(5V)|赤|電源<br>(動作電圧が4.8Vなので3.3Vだと足りません！)|
|GND|茶|グラウンド|
|14|オレンジ|信号|

![IMG_20180203_140006.jpg](https://qiita-image-store.s3.amazonaws.com/0/228646/672b0828-62fa-c4ca-8a81-5992f290141b.jpeg)

## 実行するpythonスクリプト
ポイントはモーターを動作させるための「PWM制御」というものです。
ウィーン、ウィーンと2回動きます。

```python3:servo.py
import RPi.GPIO as GPIO
import time

INTERVAL = 0.6
PIN = 14
FREQ = 50

GPIO.setmode(GPIO.BCM)

GPIO.setup(PIN, GPIO.OUT)
servo = GPIO.PWM(PIN, FREQ)

#init
servo.start(0.0)

for i in range(2):
  servo.ChangeDutyCycle(2.5)
  time.sleep(INTERVAL)

  servo.ChangeDutyCycle(10.0)
  time.sleep(INTERVAL)

GPIO.cleanup()
```
SG90のデータシートを見るとこいつの周波数が「50Hz」だと書いてありました。
なので、使用するPIN(14)に対して周波数FREQ(50)を以下のように指定します。

```python3
servo = GPIO.PWM(PIN, FREQ)
```



次に、ループの中でモーターの角度を指定しています。
ここに2.5～12.0の数値を指定する事で角度が決まるようです。

```python3
servo.ChangeDutyCycle(2.5)
```

詳しい説明は他のサイトにお任せして、ここでは指定した値と角度だけ整理します。
正確かは分かりませんが、理屈から行くとだいたいこんな感じ。

|指定値|角度|説明|
|:--:|:--:|:--|
| 2.5|-90°|最小値|
|7.25|  0°|(12 - 2.5) / 2 = 4.75<br>4.75 + 2.5 = 7.25|
|12.0| 90°|最大値|

![IMG_20180203_225329.jpg](https://qiita-image-store.s3.amazonaws.com/0/228646/106ef6df-c6f2-ab95-8bc4-57000870bdfa.jpeg)

そしてpythonを実行すると、、おー動きましたー

#もっと何か作りたい
いつになく配線もプログラムもサックリとできてしまいました。
うーーん、何だか物足りない。。
ということで、[最初に作った時計](https://qiita.com/elyoshio92/items/ccb27786302983cd5057)のような感じで、お遊びでも実用的な形にしてみようかと思います。

##自動エサやりマシーン！
我が家には小さいですが熱帯魚の水槽がございまして、私が彼らにえさをやり忘れる事が良くございます。
『自然界にいたら毎日必ずエサなど当たらないべ！』という酷い理由で正当化していましたが、彼らの待遇を改善すべくマシーンを作ってみる事にしました。

##電子工作ではなくただの工作
家で眠っていた何の変哲も無い端材を使ってまずは試作品を作ってみました。
**※ここから暫く技術的な話とは関係ないただのDIYが続きます** m(_ _)m
###サーボホーンと工作資材との接続
サーボモーターの駆動部の先につける角のような部品をサーボホーンというそうです。
このサーボホーンには小さい穴が開いてますが、こんな小さい穴に挿すようなネジとかあるのかしら？
分からない事は全部ジョイフルAKで聞く事にしている私はさっそく店員さんに相談しました。

私「この穴に留めれるようなネジってあるんですかね？」
AK「こんな小さいの無いわ。針金ででも留めればいいんでないかい？」

･･･なんて素敵なご回答。さすが信頼のジョイフルAKさん。
何の変哲も無い端材に穴を開けて針金でサーボホーンを固定しました。
![IMG_20180203_135352 (1).jpg](https://qiita-image-store.s3.amazonaws.com/0/228646/e8968c62-b631-9982-30a1-5358e4a07415.jpeg)

##熱帯魚のエサの取り付け
普段あげている(あげ忘れている)何の変哲も無いエサに輪ゴムでさっきの端材を固定します。
![IMG_20180203_135741.jpg](https://qiita-image-store.s3.amazonaws.com/0/228646/543c2ad6-f98a-8347-d9bb-40ab662f758d.jpeg)

##水槽の上に設置
その他さまざまな何の変哲も無い端材をつなぎ合わせてこんな感じで水槽の上に固定しました。
上からにゅっと出ている棒は上にある棚に仮止めしています。
試作なので見た目は悪いですが、オラわくわくしてきたぞ！
![IMG_20180203_223226.jpg](https://qiita-image-store.s3.amazonaws.com/0/228646/50dbdcef-ea5c-a423-05e1-a74c46023265.jpeg)

##動作確認
![ezgif.com-resize (3).gif](https://qiita-image-store.s3.amazonaws.com/0/228646/97862887-eb48-af10-1d2e-f01ca1d17031.gif)
出た出たーーーーｗｗｗｗ
いい感じにエサが出ましたー！

今はEnterキーを叩いてスクリプト実行しているので、時刻起動とかにしてホントに自動にしないとですね。
折角だからこれまでにやった7セグメントLEDとかも使ってCOOLなガジェットにしてみようか

**後半へ続く(予定)**
AWS上でWin2016をデプロイしてアクセスする方法

#はじめに
タイトルの通りです。個人的な備忘録的な記事です。
目的は、AWS上でWinServerを立ち上げたことが無かったので、
立ち上げと接続方法の確認です。

#構成図
[cloudcraft](https://cloudcraft.co/)を使用して、構成図を描きました。

![WindowsServer2016 (1).png](https://qiita-image-store.s3.amazonaws.com/0/122004/55c5f21b-d8d3-57a2-4bad-b9a80a5e828a.png)

とっても簡単な構成ですね。四角がEC2です。

#構築
1. AWSのホーム画面から「EC2」を選択
2. 青いボタンの「インスタンスを作成」を選択
3. AMIは「Microsoft Windows Server 2016 Base - ami-157fe573」を選択
4. タイプは「t2.micro」を選択して、「次の手順」を選択。
5. インスタンスの詳細の設定は「インスタンス数」を１に設定して、「次の手順」を選択。
6. 「ストレージの追加」は３０Gを選択して、「次の手順」を選択。
7. 「タグの追加」は特に指定せず、「次の手順」を選択。
8. 「セキュリティグループの設定」は以下が設定されていることを確認して、「確認と作成」を選択。
画面遷移したら「作成ボタンを」選択。

| タイプ| プロトコル |ポート範囲 |ソース |
|:-:|:-:|:-:|:-:|
|RDP|TCP|3389|カスタム　0.0.0.0/0|
※ソースを0.0.0.0/0にしている為、どこからでもアクセス可能になっています。
テスト用にデプロイしているので、セキュリティ的にザルな設定になっているので、本番運用を考慮するなら、自宅や職場のグローバルIPからのみ接続できる設定の方が好ましいです。

９.　キーペアの作成について聞かれるので、今までに作っていないor新しく作りたい場合は、作成する。
 
#パスワードの確認
AWSの画面からキーペアを使ってユーザー名とパスワードを確認する。
Lunux等に対してSSHで接続する場合はあらかじめ設定されている初期値を入力すれば良いが、Windowsに対してRDP接続する場合は事前にキーペアから独自に作成されるパスワードを確認する必要がある。~~めんどい~~

1. AWSのホーム画面から「EC2」を選択。
2. インスタンスを選択。
3. 接続したいインスタンスに対して右クリックし、「Windowsのパスワードの取得」を選択
4. 先ほど保存したキーペアをアップロードして、ユーザ名とパスワードを確認。

#接続
Windowsだと標準のリモートデスクトップを利用、MacだとMicrodsoft Remote Desktopをダウンロードして接続する。
1. リモートデスクトップを起動。
2. 接続先に先程作成した、インタスタンスのIPorホスト名を入力する。
3. 画面が表示されることを確認する。

#その他
2018年２月現在で使えるWin2016は全て英語版のみでした。
その内、日本語版も出ると思うけど、案件とかで今すぐ対応しなきゃの人は大変そうですね。
[Node.js]Passport.jsを用いたSNS認証(Google編)

Google認証を利用したので、その時のメモです。
ある程度、Node.jsへの理解がある方向けの記事になります。
##必要な前準備
1. Google Cloud Console でプロジェクトを作成し、client id と client secret を発行する。
 1. https://console.cloud.google.com
 にアクセスして新規プロジェクトを作成し、[API とサービス] > [認証情報]をクリックする。
 2. **プロジェクト名**を入力後、**認証情報を作成**をクリックし、**OAuthクライアントID**を選択する。
 3. **サービス名**を入力後、アプリケーションの種類からウェブアプリケーションを選択する。
 4. 承認済みのJavaScript生成元にhttp://localhost:8080
 、承認済みのリダイレクトURLにhttp://localhost:8080/auth/google/callback を入力する。

2. 必要なモジュールをインストールする。
```npm install --save passport-google-oauth passport```

3.Google+ API を有効にする
[API とサービス] > [API ライブラリ]をクリックし、Google+ APIを有効にする。

##コードの実装
app.jsに下記のコードを追加してください。

```javascript:app.js
const passport = require('passport');
const auth = require('./routes/auth');
app.use(passport.initialize());
// Routing
app.use('/auth', auth);
```

```javascript:routes/auth.js
const express = require("express");
const passport = require('passport');
const GoogleStrategy = require('passport-google-oauth').OAuth2Strategy;

function extractProfile(profile) {
    let imageUrl = '';
    if (profile.photos && profile.photos.length) {
        imageUrl = profile.photos[0].value;
    }
    return {
        id: profile.id,
        displayName: profile.displayName,
        image: imageUrl,
    };
}

passport.use(new GoogleStrategy({
    clientID: "上記で取得したクライアント ID",
    clientSecret: "上記で取得したクライアントシークレット",
    callbackURL: '上記で設定したロールバック URL',
    accessType: 'offline',
}, function (accessToken, refreshToken, profile, done) {
    if (profile) {
        return done(null, profile);
    }
    else {
        return done(null, false);
    }
}));

const router = express.Router();

router.get('/login',
    passport.authenticate('google', { scope: ['email', 'profile'], session: false, }),
);

router.get('/google/callback', passport.authenticate('google'), (req, res) => {
    res.redirect("/");
});
module.exports = router;
```
**[説明]**
**・ログイン URL を用意する**

```javascript:routes/auth.js
router.get('/login',
    passport.authenticate('google', { scope: ['email', 'profile'], session: false, }),
);
```
ここで用意された URL にアクセスすると、Google に認証を委譲します。
**・コールバック URL を用意する**

```javascript:routes/auth.js
router.get('/google/callback', passport.authenticate('google'), (req, res) => {
    res.redirect("/");
});
```
Googleで認証されると、コールバック先として事前に登録しておいたhttp://localhost:8080/auth/google/callback リダイレクトされます。
上記の例だと、リダイレクトされた後に、http://localhost:8080/ にリダイレクトします。

##セッションを有効にする場合
1.追加で、**express-session**をインストールする。
```npm install --save express-session```
2.app.jsに下記のコードを追加。

```javascript:app.js
var session = require('express-session');

app.use(passport.session());

passport.serializeUser(function(user, done) {
    done(null, user);
});

passport.deserializeUser(function(user, done) {
    done(null, user);
});
```

##動かしてみる
http://localhost:8080/auth/login にアクセスしてみてください。
Operationによる非同期処理の用例

#概要
OperationにはConcurrentとNon-Concurrentの２タイプがありますが、本記事ではNon-Concurrentの使用例を簡単に紹介します。Concurrentの処理については別記事を参考にしてください。

#背景
iOSアプリの開発において、メインスレッドでのUIの操作と並行して、バックグラウンドで何らかの処理を実行したい時があります。たとえばサーバから何らかのデータをダウンロードする処理であったり、あるいは端末側に溜め込んだデータをサーバ側に送信する場合などです。そのような場合、Operationクラスを用いて非同期に処理を行うことが可能です。

#Operationクラスの実装
まずはOperationを継承したクラスを作成し、mainメソッドをoverrideします。下記の例では、dataを用いて何らかの処理を行うSomeOperationクラスを実装しています。

```swift:dataを用いて何らかの処理を行うSomeOperationクラス
class SomeOperation: Operation {
    var data: Any
    
    init(data: Any) {
        self.data = data
    }
    
    override func main() {
        doSomething(data: self.data)
    }
}
```

#OperationQueueにOperationを追加
次に、下記のようにOperationQueueにOperationを追加していきます。これだけでSomeOperationクラスのmainメソッドの処理が順次走ることになります。


```swift:
let operationQueue = OperationQueue.main

for data in dataList {
    operationQueue.addOperation(SomeOperation(data: data))
}
```

#参考
- [Operation(NSOperation)について](https://qiita.com/ysn551/items/ecd8cd9fff5fb3d77f66)
- [iOSで最も簡単にマルチスレッド処理を行う方法(NSOperationQueue)](https://qiita.com/koyopro/items/2432b01ebfe449272812)
- [NSOperationを使って並列処理をするシンプルなサンプル](https://qiita.com/edo_m18/items/c121d0cb42a6e20cefbd)
Rspec + Capybara で順序をテストする


featureテストにおいて、要素の出現順をテストしたい。

`String`の`index`メソッドを利用することで、そのテストが可能。


```rb
scenario 'type order' do
  visit examples_path

  expect(page.body.index(precede.target.str)).to be < page.body.index(non_preced.word.str)
end
```

### 解説

現在表示しているページのbodyを文字列として取得する。
その中から出現順序をテストしたい要素の位置を`index`メソッドで算出する。
算出した出現位置を単純に比較することで、要素の出現順序をテストしている。

テスト対象と同じ文字列が複数あると正常に動作しないためその点のみ注意。



### 参考
[index (String) - Rubyリファレンス](https://ref.xaio.jp/ruby/classes/string/index)
http://www.rubydoc.info/github/jnicklas/capybara/Capybara/DSL#page-instance_method
個人的に作業効率が上がる最低限のemacs設定

Linux系のデフォルトインストールエディタはご存知「vi」ですが、
個人的には「emacs」派なので、個人的に便利な設定について備忘メモ。

まずは後の設定で使う下準備としてフォルダ作成。

```linux-config
$ mkdir ~/.emacs.d/backup-file
$ mkdir ~/.emacs.d/auto-save-file
```

次に、使用アカウントのルート(~/)にある`.emacs`(なければ作るべし)に下記を追加。

```emacs:~/.emacs
; 「¥C-h」にてbackspaceを代替する
(global-set-key "\C-h" 'delete-backward-char)

; デフォルトで勝手に作られるbackupファイルの保存先を任意箇所にする
(setq backup-directory-alist
  (cons (cons ".*" (expand-file-name "~/.emacs.d/backup-file"))
        backup-directory-alist))

; 編集中の異常終了の際などに作られるauto-saveファイルの保存先を任意箇所にする
(setq auto-save-file-name-transforms
  `((".*", (expand-file-name "~/.emacs.d/auto-save-file") t)))
```

上記記載後に一度emacsを落として起動すると設定反映されます。(もちろん再起動とかでもOK)

backupファイル（○○~）やauto-saveファイル(#○○#)は、必要性はわかるものの、
いざフォルダに意図せず作成されると良からぬ動作を引き起こす原因になりかねません。

とはいえ作成されない設定を入れるのもいざってときに怖いので、
だったらどっかにまとめましょうという考えに至ったので、上記設定を基本的には使ってます。
rbenvインストール時に Peer reports incompatible or unsupported protocol version. がエラーが出力されたときの対処法

# 概要

今回の投稿では、rbenvインストール時の ```rbenv install``` コマンド実行時に **BUILD FAILED** が出力されてしまい躓いたときに対応した方法をまとめていきます。

# 1. エラーログの確認

まず、rbenvインストール時に ```/tmp/ruby-build.xxxx``` ファイルが生成されるので、そこに出力されているエラーログを確認します。 

```bash
$ cat /tmp/ruby-build.20180203142646.3916.log
/tmp/ruby-build.20180203142646.3916 ~
curl: (35) Peer reports incompatible or unsupported protocol version.
```

# 2. 最新版の**curl**をソースインストール

```curl: (35) Peer reports incompatible or unsupported protocol version.``` エラーの対処法を調査したところ **curl** コマンドのバージョンが古いことが原因で発生している問題であることが判明したため、[こちら](https://qiita.com/maangie/items/4af8b813ed9ddce4a0db)の投稿を参考に curlのバージョンアップを行います。
具体的に実行したコマンドは以下の通りです。

```bash:curlをソースインストール
$ cd /usr/local/src/
$ wget https://curl.mirror.anstey.ca/curl-7.58.0.tar.bz2
$ sudo tar xf curl-7.58.0.tar.bz2
$ cd curl-7.58.0
$ sudo ./configure --enable-libcurl-option
$ sudo make
$ sudo make install
```

以下の通り、2018/02/03 時点で最新の curlバージョンをインストールしていることを確認します。

```bash:curlバージョン確認
$ curl --version
curl 7.58.0 (x86_64-pc-linux-gnu) libcurl/7.58.0 OpenSSL/1.0.2k zlib/1.2.7
Release-Date: 2018-01-24
Protocols: dict file ftp ftps gopher http https imap imaps pop3 pop3s rtsp smb smbs smtp smtps telnet tftp
Features: AsynchDNS IPv6 Largefile NTLM NTLM_WB SSL libz UnixSockets HTTPS-proxy
```

# 3. ```rbenv install``` を実行

再度 ```rbenv install``` コマンドを実行し、問題なく rubyがインストールされていることを確認して作業完了です。

```
$ rbenv install 2.5.0
$ rbenv versions
  2.5.0
$ rbenv global 2.5.0
$ ruby -v
ruby 2.5.0p0 (2017-12-25 revision 61468) [x86_64-linux]
```


# 参考文献
1. rbenvでrubyを追加しようとしたら Peer reports incompatible or unsupported protocol version. - 東京伊勢海老通信, https://altarf.net/computer/ruby/3925, Online; accessed 3-February-2018.
1. How to install curl 7.37.0 with CentOS 6.5 - Qiita, https://qiita.com/maangie/items/4af8b813ed9ddce4a0db, Online; accessed 3-February-2018.
Githubのdiffで空白やスペースを無視する(ブックマークレット付き)

commitやPull Requestのdiffの空白、スペースを無視したい場合はURLのパラメータ（末尾）を以下のように書き換えましょう。

#### before
https://github.com/quiye/ignore_space_sample/commit/855397c4169cdad1d1da6aa35356923bfb3e7987

#### after
https://github.com/quiye/ignore_space_sample/commit/855397c4169cdad1d1da6aa35356923bfb3e7987?w=1

## ↑を1クリックで実行する（ブックマークレット）
次のリンクをブラウザのブックマークに保存して、diffが見える状態の時に押しましょう。

- `javascript:location.href=location.href+'?w=1';`

別タブで開く版

- `javascript:window.open(location.href+'?w=1');`
  

  
## 参考記事
- [Githubで空白を無視してdiffを見る \- Qiita](https://qiita.com/awakia/items/6a7028aa46928e376f32)
- [「Githubで空白を無視してdiffを見る」のブックマークレット \- Qiita](https://qiita.com/shindo-r@github/items/83ee8f569de95b22ea01)
PHPでUTCタイムスタンプ

UTCのタイムスタンプ形式で0時の値のみ受け付けるというAPIがありましたので必要に迫られてUTCタイムスタンプを取得してみました。

# strtotimeの場合

```php
$utc_timestamp = strtotime(date('Y-m-d').' UTC');
```

# DateTimeの場合

```php
$datetime = new DateTime(date('Y-m-d'), new DateTimeZone('UTC'));
$utc_timestamp = $datetime->getTimestamp();
```

# DateTimeImmutableの場合

```php
$datetime = new DateTimeImmutable(date('Y-m-d'), new DateTimeZone('UTC'));
$utc_timestamp = $datetime->getTimestamp();
```

オブジェクト指向型

```
$datetime->setTimezone(new DateTimeZone('UTC'));
```
LibreOfficeで文書に電子署名

# 文書への電子署名

いろいろ言われますが、ハンコ認証を追い出したいなら、ちゃんとしたものが使えないとですよね。
せめて、社内への通達くらいは署名してほしい。

---

## で

なんか、[LibreOfficeでできるようになった](https://forest.watch.impress.co.jp/docs/news/1104230.html)という話を見ました[^1]。

---

## 実験

試してみた。

---

### 環境
LibreOffice: Writer 6.0.0.3 PortableApps.com版
Windows : 10 Pro
GnuPG : 2.2.4 (Gpg4Win 3.0.3)
gpg-agent & git for winのssh-pageant常駐環境
GNUPGHOMEを定義してる(=%USERPROFILE%\\.gnupgで)

---

適当な文書を作る。
![スクリーンショット1](https://farm5.staticflickr.com/4677/40026238692_9637a4f087_o.png)

---

ファイル->デジタル署名->デジタル署名...を選択。
![スクリーンショット2](https://farm5.staticflickr.com/4662/40026238542_599f7771d1_o.png)

---

ここで「ドキュメントに署名」でこうなる、選択して「署名」を実行。
![スクリーンショット3](https://farm5.staticflickr.com/4607/39348070214_7e9a2e499f_o.png)

---

GnuPGのpinentryでパスフレーズを確認され、署名が実行される。
![スクリーンショット4](https://farm5.staticflickr.com/4665/39348070014_1250a4910c_o.png)

---

完了。文書を更新して保存などした場合は署名が解除される。
![スクリーンショット5](https://farm5.staticflickr.com/4623/39348069904_febf147cd6_o.png)

---

## あと

保存時に、相手の鍵で暗号化することもできます。
むしろこっちで暗号化ZIP運用撲滅したいなあ。

[^1]: [参考にしたページ](http://text.baldanders.info/openpgp/git-extensions-and-libreoffice-6-with-openpgp/)
fluentdのpluginを作成する （fluent-plugin-generateコマンド利用）

# 概要
fluentdのpluginを作成する際に、[v0.14.13](https://github.com/fluent/fluentd/blob/master/CHANGELOG.md#release-v01413---20170217)からfluent-plugin-generateコマンドが利用できるようになった。（ちなみにv0.14の次はv1.0になっている。）　今回は、このコマンドを利用して、pluginを作成して、ローカルでテストできる環境を作ってみた。

# 事前準備
gem最新化, bundler / fluentd / test-unitのインストールを実施する。(fluentdのテストコードはtest-unitを利用している)

```
$ gem update --system
$ gem install bundler
$ gem install fluentd
$ fluentd --version
fluentd 1.1.0
$ gem install test-unit
```

# plugin作成
## generate コマンド実行
このコマンドを実行すると、plugin用のプロジェクトフォルダを作成してくれる。めっちゃ便利。
試しに、下記では`filter`プラグインを作成するコマンドを実行。

```
$ fluent-plugin-generate filter hogehoge
License: Apache-2.0
	create Gemfile
	create README.md
	create Rakefile
	create fluent-plugin-onekeyparse.gemspec
	create lib/fluent/plugin/filter_hogehoge.rb
	create test/helper.rb
	create test/plugin/test_filter_hogehoge.rb
Initialized empty Git repository in /xxxx/fluent-plugin-hogehoge/.git/
```

## 動作確認
- fluentd.conf作成
filterの`@type`に今回作成するpluginの`hogehoge`を設定

```
<source>
  @type forward
</source>

<filter **>
  @type hogehoge
</filter>

<match **>
  @type stdout
</match>
```

- fluentd起動

```
$ fluentd -c fluent.conf -p lib/fluent/plugin
```

- ログ送信

```
$ echo '{"a":"foo","b":"bar"}' | fluent-cat raw.test
```

- テスト

```
$ rake test
Finished in 0.004382 seconds.
・・・

---------------------------------------------------------------------------------------------------------------------------------------------
1 tests, 1 assertions, 1 failures, 0 errors, 0 pendings, 0 omissions, 0 notifications
0% passed
---------------------------------------------------------------------------------------------------------------------------------------------
228.21 tests/s, 228.21 assertions/s

//テストが失敗すればOK。 コードを実装してテストが通るようにする。
```

# まとめ
自分でpluginを書くのはハードル高そうですが、このgeneratorがあれば、なんとなく作れそうな気になってきますよね。私もチャレンジしてみたいと思います。plugin周りについては、2016年の[Fluentd meetup](https://techplay.jp/event/588701)で統一されてないplugin開発を整理するという話があり、実際に実現されて嬉しい限りです。
以下参考サイトです。
- [Fluentd v0.14.13で追加されたコマンドのご紹介](http://www.clear-code.com/blog/2017/3/9.html)
- [Fluentd v0.12 Filter プラグインの使い方と作り方](https://qiita.com/sonots/items/25a354b5e8aa524faeef)
Processing - 06 - rectとforを使った描画

<img width="398" alt="スクリーンショット 2018-02-03 23.26.46.png" src="https://qiita-image-store.s3.amazonaws.com/0/45520/ab0c68a8-6eeb-bc1a-ecdd-9570e8f9c52a.png">

```java
size(400, 400);
background(255);
colorMode(HSB,100);
noStroke();

for (int i=0; i<10; i++) {
  fill(100,10*i,99);
  rect(0, 0, width - 40*i, height - 40*i);
}
```
sudoできるユーザの追加をDockerfileに書いてみた

環境
Windows 10 Pro 1709(16299.192)
Docker version 17.12.0-ce, build c97c6d6
CentOS Linux release 7.4.1708 (Core)

## 前提
・「Docker for Windows」のインストール済み
・「CentOS7」の「Dockerイメージ」をダウンロード済み または 作成済み
Refer to [Window10にCentOS7のdockerコンテナを作ってみた](https://qiita.com/0ashina0/private/f8b960e822a40a6a2eed)

## １．「Dockerfile」を作成
```:Dockerfile
FROM centos
LABEL maintainer "michiru <0ashina0@gmail.com>"

# ROOTにパスワードをセット
RUN echo 'root:newpassword' |chpasswd

# ユーザを作成
RUN useradd newuser
RUN echo 'newuser:newuserpass' |chpasswd
RUN echo "newuser    ALL=(ALL)       ALL" >> /etc/sudoers

# インストール済みのパッケージをアップデート＆キャッシュのクリア
RUN yum -y update && yum clean all

# sudoをインストール
RUN yum install -y sudo

```

## ２．「Dockerイメージ」の作成

```
PS C:\Users\UserName> docker build ./ -t useradd
```


## ３．確認
### 「Dockerコンテナ」の作成＆起動

```
PS C:\Users\UserName> docker run -it useradd
```

### 追加ユーザの確認

```:CentOSで実行
[root@7d831becc17d /]# su - newuser
[newuser@7d831becc17d ~]$ sudo ls

We trust you have received the usual lecture from the local System
Administrator. It usually boils down to these three things:

    #1) Respect the privacy of others.
    #2) Think before you type.
    #3) With great power comes great responsibility.

[sudo] password for newuser:
[newuser@7d831becc17d ~]$ su - root
Password:
Last failed login: Sat Feb  3 14:14:57 UTC 2018 on pts/0
There was 1 failed login attempt since the last successful login.
[root@7d831becc17d ~]# logout
[newuser@7d831becc17d ~]$ logout
[root@7d831becc17d /]# exit
PS C:\Users\UserName>
```

### 「Dockerコンテナ」の再起動

```
PS C:\Users\UserName> docker start 7d831becc17d
PS C:\Users\UserName> docker attach 7d831becc17d
```

### 追加ユーザで2回目のsudoでコマンド実行。（パスワードなし）

```
[root@7d831becc17d /]# su - newuser
Last login: Sat Feb  3 14:14:20 UTC 2018 on pts/0
[newuser@7d831becc17d ~]$ sudo touch aaa
[newuser@7d831becc17d ~]$ sudo ls
aaa
[newuser@7d831becc17d ~]$ su - root
Password:
Last login: Sat Feb  3 14:15:09 UTC 2018 on pts/0
Last failed login: Sat Feb  3 14:19:39 UTC 2018 on pts/0
There was 1 failed login attempt since the last successful login.
[root@7d831becc17d ~]#
```
Serverless FrameworkでAPI Gatewayバイナリサポートを設定する

API Gatewayでバイナリを扱いたい場合、バイナリサポートを有効にする設定が必要になります。
その設定をServerless Frameworkで定義しました。

ServerlessFrameworkのデフォルトではバイナリサポートの設定パラメータが用意されていないためプラグインを使用します。

調べたところ現時点では以下の２つのプラグインが見つかりました。

- [serverless-apigw-binary](https://www.npmjs.com/package/serverless-apigw-binary)
- [serverless-plugin-custom-binary](https://www.npmjs.com/package/serverless-plugin-custom-binary)

一つ目の**serverless-apigw-binary**は試してみたときに、デプロイは成功していてもAPI Gatewayに反映されていないということがあったため、二つ目の**serverless-plugin-custom-binary**を使うことにしました。

# 環境
```
$ npm -v
5.5.1

$ serverless -v
1.22.0
```
# 設定方法
### プラグインのインストール
```bash
$ npm install --save-dev serverless-plugin-custom-binary
```

### 設定を追加
```serverless.yml
plugins:
  - serverless-plugin-custom-binary

custom:
  apigatewayBinary:
    types:
      - multipart/form-data
```

### デプロイ！ :beer: 

```bash
$ serverless deploy
```

デプロイ完了後、API Gatewayのコンソールで確認するとちゃんと設定されています。
<img width="413" alt="スクリーンショット 2018-02-03 22.20.23.png" src="https://qiita-image-store.s3.amazonaws.com/0/99248/daad8c83-5975-277f-e4d4-1cb2dfcf8774.png">

以上です。
NanoPi NEOのカーネルをソースからビルドする

#カーネルをソースからビルドする理由

カーネルのソースコードを修正したいということはあまりないかもしれませんが、カーネルコンフィグをカスタマイズしたいということはよくあります。

組み込みLinuxで、ある特定用途に特化する場合は必要となるカーネルドライバや機能などが絞られます。カーネルはRAM上に常駐することになるので、不要な機能は削除してカーネルサイズを減らすとメモリの節約になります。
例えば、NanoPi NEOの場合は画面表示用のフレームバッファデバイスはビルトインになっていますが、ボード上に画面出力するデバイスは無く、LCDなどを追加でつけるのでなければ、これは削除することができます。

また、使用するUSBのデバイスが決まっている場合には、それ用のカーネルドライバをモジュールでなくビルトインにし、必要なもの全てをビルトインにすることができればカーネルモジュールが一切不要になるので、構成がシンプルになります。ビルドやインストールが楽になります。

#ソースコードなど必要なもののありか

https://www.mediafire.com/folder/n5o8ihvqhnf6s/Nanopi-NEO

#ツールチェインの準備

```
wget http://www.mediafire.com/file/qejfdcehoci225k/arm-cortexa9-linux-gnueabihf-4.9.3-20160512.tar.xz
sudo tar xf arm-cortexa9-linux-gnueabihf-4.9.3-20160512.tar.xz -C /usr/local
```


#カーネルのソースコードの入手

```
wget http://www.mediafire.com/file/57urrfmb7irxlbb/linux_4.11.2_20170707.tar.gz
tar xf linux_4.11.2_20170707.tar.gz 
cd linux/
```
#カーネルのビルド

```
export ARCH=arm
export CROSS_COMPILE=/usr/local/4.9.3/bin/arm-cortexa9-linux-gnueabihf-

make sunxi_defconfig
make menuconfig
make zImage dtbs
```

make menuconfig のときに必要になるカーネルモジュールは全てビルトインにしてしまうとカーネルモジュールのビルドとインストールが不要になります。

#カーネルのインストール

次の2つのファイルを起動SDカードのbootパーティションのものと差し替えます。

arch/arm/boot/zImage
arch/arm/boot/dts/sun8i-h3-nanopi-neo.dtb

カーネルモジュールも更新する場合は、rootfsのパーティションの/lib/modules を更新します。このページが参考になります。
[Linuxカーネルモジュールのインストールに使うスクリプト](https://qiita.com/tetsu_koba/items/92f22fc6a302f0f66fe7)

#参考
http://wiki.friendlyarm.com/wiki/index.php/NanoPi_NEO
NotificationCenterを用いたライフサイクルイベントの検知

#背景
iOSアプリの起動、終了、バックグラウンドへの移行、フォアグラウンドへの復帰等のライフサイクルイベントを検知するには、AppDelegateクラスの各メソッドを利用するのが最も簡単な方法です。ただし、何らかの理由によりそれ以外の方法が求められる場合があります。例えばアプリではなくSDKの開発において、それらのイベントを検知したい場合等です。そういった場合、NotificationCenterを利用することによりアプリの起動や終了といったイベントを検知し、それに伴った処理を実装することが可能です。

#ライフサイクル監視用のクラスを作成
下記のようにイベント検知用のクラスを作成し、NotificationCenterに自身のメソッドを登録してイベントを検知できるようにします。その際、オブジェクトをシングルトンとして使用できるよう、sharedInstanceの指定とprivate初期化メソッドの定義を行います。

```swift
class AppEventHandler: NSObject {
    static let sharedInstance = AppEventHandler()

    override private init() {
        super.init()
    }
    
    deinit {
        NotificationCenter.default.removeObserver(self)
    }

    // 各イベントの通知を受け取れるよう、NotificationCenterに自身を登録
    func startObserving() {
        // アプリ起動時
        NotificationCenter.default.addObserver(self, selector: #selector(self.didFinishLaunch),
                                               name: UIApplication.didFinishLaunchingNotification, object: nil)
        
        // フォアグラウンド復帰時
        NotificationCenter.default.addObserver(self, selector: #selector(self.willEnterForeground),
                                               name: UIApplication.willEnterForegroundNotification, object: nil)
        
        // バックグラウンド移行時
        NotificationCenter.default.addObserver(self, selector: #selector(self.didEnterBackground),
                                               name: UIApplication.didEnterBackgroundNotification, object: nil)
        
        // アプリ終了時
        NotificationCenter.default.addObserver(self, selector: #selector(self.willTerminate),
                                               name: UIApplication.willTerminateNotification, object: nil)
    }
    
    // アプリ起動時の処理
    @objc func didFinishLaunch() {
    }

    // フォアグラウンドへの復帰時の処理
    @objc func willEnterForeground() {
    }

    // バックグラウンドへの移行時の処理
    @objc func didEnterBackground() {
    }

    // アプリ終了時の処理
    @objc func willTerminate() {
        // NotificationCenterから自身を削除
        NotificationCenter.default.removeObserver(self)
    }
}
```

#使用方法
下記のようにAppDelegateクラスのdidFinishLaunchingWithOptionsメソッドにて監視を開始することで、以降はアプリの終了やフォアグラウンド復帰といったタイミングで通知を受け取ることができます。

```swift
class AppDelegate: UIResponder, UIApplicationDelegate {
    var window: UIWindow?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        AppEventHandler.sharedInstance.startObserving()

        return true
    }

...

}
```
ゼロから学ぶディープラーニング - AWS上のJupyterを使ったハンズオン

[![](https://scontent.fngo1-1.fna.fbcdn.net/v/t1.0-9/22815614_1724789167594612_2013643824872588581_n.jpg?oh=a614d605819f5cac67d290c417f2a8d8&oe=5B155FFA)](https://github.com/yoshihiroo/programming-workshop/tree/master/deep_learning_jupyter)

### Japanese
| ファイル | 内容 |
----|----
| [ハンズオン・レクチャー資料](https://www.slideshare.net/YoshihiroOchi/ss-85592219) | グロービス 人工知能研究会／テクノベート勉強会で用いたレクチャー資料 |
| [AWS_SETUP.md](https://github.com/yoshihiroo/programming-workshop/blob/master/deep_learning_jupyter/AWS_SETUP.md) | AWS上にJupyter環境を構築するためのガイド |
| [file1_vector_and_matrix.ipynb](https://github.com/yoshihiroo/programming-workshop/blob/master/deep_learning_jupyter/file1_vector_and_matrix.ipynb) | ベクトルと行列 |
| [file2_two_layer_NN.ipynb](https://github.com/yoshihiroo/programming-workshop/blob/master/deep_learning_jupyter/file2_two_layer_NN.ipynb) | ニューラルネットワークを行列計算で表現する |
| [file3_gakusyu.ipynb](https://github.com/yoshihiroo/programming-workshop/blob/master/deep_learning_jupyter/file3_gakusyu.ipynb) | 手書き文字(数字)認識の実践 |
| [file4_hyper_parameter.ipynb](https://github.com/yoshihiroo/programming-workshop/blob/master/deep_learning_jupyter/file4_hyper_parameter.ipynb) | より高い精度を出せるハイパーパラメータの探求 |
| [file5_CNN.ipynb](https://github.com/yoshihiroo/programming-workshop/blob/master/deep_learning_jupyter/file5_CNN.ipynb) |  畳み込みニューラルネットワークの評価 |

### English
| File | Contents |
----|----
| [AWS_SETUP_E.md](https://github.com/yoshihiroo/programming-workshop/blob/master/deep_learning_jupyter/AWS_SETUP_E.md) | Building Jupyter Environment on AWS |
| [file1_vector_and_matrix_E.ipynb](https://github.com/yoshihiroo/programming-workshop/blob/master/deep_learning_jupyter/file1_vector_and_matrix_E.ipynb) | Vector and Matrix |
| [file2_two_layer_NN_E.ipynb](https://github.com/yoshihiroo/programming-workshop/blob/master/deep_learning_jupyter/file2_two_layer_NN_E.ipynb) | Neural-Network Expression by Matrix |
| [file3_gakusyu_E.ipynb](https://github.com/yoshihiroo/programming-workshop/blob/master/deep_learning_jupyter/file3_gakusyu_E.ipynb) | Hand-writing Digits Recognition |
| [file4_hyper_parameter_E.ipynb](https://github.com/yoshihiroo/programming-workshop/blob/master/deep_learning_jupyter/file4_hyper_parameter_E.ipynb) | Finding Hyper Parameters for Higher Accuracy |
| [file5_CNN_E.ipynb](https://github.com/yoshihiroo/programming-workshop/blob/master/deep_learning_jupyter/file5_CNN_E.ipynb) | Convolutional Neural Network Estimation |
Golangにおけるポインタと値の暗黙的変換

# はじめに
ご存じの方も多いかとは思いますが、備忘録の意味も含めて、
ポインタと値が暗黙的に変換される場合とそうでない場合を、
レシーバー、引数、返り値についてまとめてみました。

# TL; DR

レシーバー以外は型が完全に一致していないといけません。

# レシーバー

```go:test.go
package main                                                                                         
                                                                                                     
import "fmt"                                                                                         
          
type Person struct {
        name string
        age  int64
}

// レシーバーがポインタの場合
func (p *Person) AddAgePointer() { 
        p.age += 10
}

// レシーバーが値の場合
func (p Person) AddAgeValue() {
        p.age += 10
}

func main() {
        p := Person{"john", 20}
        pp := &p
        p.AddAgePointer()
        fmt.Println(p)
        p.AddAgeValue()
        fmt.Println(p)
        pp.AddAgePointer()
        fmt.Println(p)
        pp.AddAgeValue()
        fmt.Println(p)
}
```

ちなみに、上のコードの実行結果は以下の通り。オブジェクト(`p`、`pp`)の型に関係なく、レシーバーの型で結果が変わってきていることがわかると思います。

```bash
$ go run test.go
{john 30}
{john 30}
{john 40}
{john 40}
```

# 引数

```go
func AddAgePointer(p *Person) {
        p.age += 10
}

func AddAgeValue(p Person) {
        p.age += 10
}

func main() {
        AddAgePointer(&Person{"hitoshi", 12}) //　仮引数の型がポインタ、実引数もポインタ
        AddAgeValue(Person{"hitoshi", 12})    //　仮引数の型が値、実引数も値
　　　　　AddAgePointer(Person{"hitoshi", 12})  //　仮引数の型がポインタ、実引数は値
        AddAgeValue(&Person{"hitoshi", 12})　　//　仮引数の型が値、実引数はポインタ
}
```
仮引数の型がポインタ、実引数もポインタの場合と、仮引数の型が値、実引数も値の場合でした。
要するに、返り値は型が完全に一致していないとダメということですね。

# 返り値

以下のように**返り値のオブジェクトの型**と**シグネチャの返り値の型**がそれぞれポインタの場合と値の場合で試してみました。

```go
// 返り値のオブジェクトの型が値、返り値の型が値
func NewPersonValueToValue() Person {
        return Person{name: "hoge", age: 12}
}

// 返り値のオブジェクトの型が値、返り値の型がポインタ
func NewPersonValueToPointer() *Person {
        return Person{name: "hoge", age: 12}
}

// 返り値のオブジェクトの型がポインタ、返り値の型がポインタ
func NewPersonPointerToPointer() *Person {
        return &Person{name: "hoge", age: 12}
}

// 返り値のオブジェクトの型がポインタ、返り値の型が値
func NewPersonPointerToValue() Person {
        return &Person{name: "hoge", age: 12}
}
```

コンパイルができたのは、`NewPersonValueToValue`と`NewPersonPointerToPointer`でした。
引数と同様、返り値は型が完全に一致していないとダメということですね。

# まとめ
レシーバー以外は型が完全に一致していないといけない。
C#からPHPにPOSTする

C#のプログラムからWebサーバー上のPHPにHTTPのPOSTで送信したデータをもとにサーバー上で処理を行うプログラムを作るときのメモです。

#C#からPHPに普通にPOST送信
単純なPOSTでPHPに複数の文字列を送信する方法

```client.cs
var hc = new HttpClient();
var dic = new Dictionary<string, string>();
dic["hiragana"] = "ほげ～";
dic["katakana"] = "ホゲ～";
var cont = new FormUrlEncodedContent(dic);
var url = "http://〇〇.com/server.php";
var req = await hc.PostAsync(url, cont);
var html = await req.Content.ReadAsStringAsync();
Console.WriteLine(html);
```

```server.php
$hoge1 = $_POST['hiragana'];
$hoge2 = $_POST['katakana'];
echo $hoge1 . $hoge2;
```

これを実行すると、client.csのhtmlには、"ほげ～ホゲ～" が代入されています。
（参考：[第7回 C#で自作Android アプリを作ろう：簡易アンケートを作ろう](https://sys-guard.com/post-11679/#POST) ）


#C#からPHPにファイルも併せてPOST送信

```client.cs
var hc = new HttpClient();
var dic = new Dictionary<string, string>();
dic["hiragana"] = "ほげ～";
dic["katakana"] = "ホゲ～";
dic["FileName"] = "hogehoge.jpg";

var fileName = @"C:\hoge.jpg";
var fileContent = new StreamContent(File.OpenRead(fileName));
fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
  FileName = Path.GetFileName(fileName),
  Name = @"userfile[]"
};

var content = new MultipartFormDataContent();
foreach (var param in dic)
{
    content.Add(new StringContent(param.Value), param.Key);
}
content.Add(fileContent);

var hc = new HttpClient();
var url = "http://〇〇.com/uploadfile.php";
var req = await hc.PostAsync(url, content);
var html = await req.Content.ReadAsStringAsync();
Console.WriteLine(html);
```


```uploadfile.php
$hoge1 = $_POST['hiragana'];
$hoge2 = $_POST['katakana'];
echo $hoge1 . $hoge2;

//アップロードされたファイルの数をカウント
$count = count($_FILES['userfile']['name']);
if($count==0){
  echo 'File is not uploaded';
  return;
}

for ($i=0; $i<$count; $i++) {
  $tem_fname = $_FILES['userfile']['tmp_name'][$i];
  if (!is_uploaded_file($tem_fname)) {
    echo "There is no temporary file";
    return;
  }
  if (!move_uploaded_file($tem_fname, $fname)) {
    echo "Unable to move file";
    return;
  }
}

```

hogehoge.jpgという名前で、サーバーにファイルが保存されます。
※ファイル属性（権限）が777とかになっていないと、PHPによる書き込みが制限されるため移動でません。

（参考：[HttpClient を使ってPOSTでマルチパートのファイルを送受信する](https://qiita.com/volpe28v/items/b86e0bc9db8e42688cc3)）

#PHPからPHP
PHPからPHPにファイルを送信する場合、[PHPのcliからcurlでファイルアップロード](https://qiita.com/tukiyo3/items/4162bd793be47d8651a8) にまとめてあった（すごくお世話になりました。感謝です！）ので省略しました。
AutoHotKeyの1.1.27.07にしたらInvalid hotkeyエラー

Windows10の開発環境を新しくした際にAutoHotKeyも最新版をインストールしました。
するとそれまで使っていたスクリプトが`Invalid Hotkey`のエラーが出て対処法を備忘録として残しておきます。

# エラー内容

実際のエラーコードは以下のようなものでした。

```
Error at line:199.

Line Text: $^vkBAsc028::Send, {BS}
Error: Invalid hotkey.

The program will exit.
```

`Ctrl`と`:`の同時押しで`Backspace`扱いにするところでエラーみたいです。
以前の環境ではこのスクリプトで動いていたので、おそらくバージョン関連だろうと思い公式のChangesを読んでみました。

# 原因と解決方法

`1.1.27.00`で仮想キーコードやスキャンコードまわりの変更があったようです。

> Added proper validation for vk or sc key names, so names such as "sc01notvalid" are no longer recognized as keys.

>> Scripts containing hotkeys of the form VKnnSCnnn:: will need to be corrected by removing SCnnn, which was previously ignored.

https://autohotkey.com/docs/AHKL_ChangeLog.htm#v1.1.27.00

「`vk`と`sc`のバリデーションを追加して`scXXX`は使えなくなったよ。」とのこと。

なので、`vkBAsc028`のようにスキャンコードを使っている箇所のスキャンコード部分を削除して`vkBA`のよう問題なく起動しました。
DockerでVolumeをマウントするとき一部を除外する方法

例えば次のようなディレクトリ構成のプロジェクトで、`node_modules`だけ除外しつつその他はすべてDockerコンテナにマウントしたいといった場合を想定する。

```
.
├── docker-compose.yml
├── node_modules … ここだけDockerコンテナに置きたくない
├── package.json
├── src
└── yarn.lock
```

まず、普通にマウントするdocker-compose.ymlを書く。この状態では当然node_modulesもマウントされる。

```yaml:docker-compose.yml
services:
  app:
    image: node
    volumes:
      - .:/app
```

次に、適当な名前のボリュームを作る。

```diff:docker-compose.yml
+volumes:
+ hoge:
services:
  app:
    image: node
    volumes:
      - .:/app
```

最後に、`/app/node_modules`にそのボリュームをマウントするようにする。

```diff:docker-compose.yml
volumes:
  hoge:
services:
  app:
    image: node
    volumes:
      - .:/app
+     - hoge:/app/node_modules
```

これでホストマシン側のnode_modulesとコンテナのnode_modulesの中は同期されなくなる。
ブラウザからcookieを制御できないときに確認すべき3つのこと

今回のケースでは、自身が管理するドメインに対する`cookie`を話題としている。
もし異なるドメインに対する`cookie`や`httpレスポンス`について興味がある場合は、[CORS](https://qiita.com/rooooomania/items/4d0f6275372f413765de)も参照のこと。

## Httponly属性がついていないか
この属性がついている`cookie`は、javascriptで操作できない。

“クッキーの紹介の中で、クッキーをJavaScriptから触ることができることを紹介したが、この属性を付けるとJavaScriptエンジンから、クッキーを隠すことができる。クロスサイトスクリプティングなど、悪意のあるJavaScriptが実行されるセキュリティリスクに対する防護となる”

抜粋:: 渋川　よしき  “Real World HTTP”。 ::

## Domain属性が指定されていないか
この属性がついている`cookie`は、そのドメインおよびサブドメインが送信対象のサーバとしてブラウザに認識される(`.exampl.com`というように頭に`.`がつく)。この`cookie`を操作する際には次のように`domain`オプションを明示的に指定する必要がある[^1]。

```javascript:クッキーを削除する`
document.cookie=“Key=;max-age=0;domain=.example.com”
```

[^1]: 指定しないと、暗黙に`example.com`が指定されることになる。


Domain属性の有無による挙動の違いについてはこちらを参照 
[CookieのDomain属性は *指定しない* が一番安全
 徳丸浩の日記](https://blog.tokumaru.org/2011/10/cookiedomain.html)
[ HTTP State Management Mechanism RFC6265 4-1-2](https://tools.ietf.org/html/rfc6265#section-4.1.2)

## Secure属性がついていないか
この属性が付いている`cookie`は、http接続の場合はサーバに送信されない。

“https接続での安全な接続時以外は、クライアントからサーバーへのクッキー送信をしない。クッキーはURLをキーとして送受信するかどうかを決めており、これにはDNSのハッキングによってURLが詐称されることで利用者が意図しないサーバーにクッキーを送信してしまうリスクがある。DNSのハッキングは、マシンを操作しなくても無料のWifiサービスなどを詐称するなどの方法で簡単に実行できる。Secure属性をつけることで、http接続が使われる時にはブラウザが警告を出し、ページヘのアクセスを止めるため、流出を防げるようになる”

抜粋:: 渋川　よしき  “Real World HTTP”。 ::
AngularでGlobal上の外部ライブラリを呼び出してcallbackで戻ってくる方法+Observable

弊社ではangularを使っているのですが、
利用している外部サービスのjavascriptで、
**処理完了したらglobal上に定義した指定の名前の関数を通して処理結果を返す**
というものがあり、どうしても以下のような流れで組む必要がありました。

1.angularから外部のライブラリを呼び出す。その際、callbackのメソッド名を指定しておく
↓
2.外部ライブラリは処理完了したら、global上に定義された"1"のcallbackの名前のfunctionを呼び出す
↓
3.global上の定義されたfunctionからangularに戻ってくる


更に"1"~"3"までの処理をひとまとまりとしてobservableな感じで使いたい。

という場合、以下のようにしたらなんとかなった。

```:SampleService.ts

declare const window: any; // tslint回避のため

@Injectable()
export class SampleService{
  private isDone = false;
  private response;
  public constructor(...) {
    window.SampleService = this; // thisでglobal上に渡す。
  }

  /**
   * これが目的のメソッド。一旦外部ライブラリになげるが、Observableとして扱いたい。
   */
  public exec(): Observable<...> {
     const params = ...;
     // これが外部提供のライブラリ。 global上に定義された"callbackFunctionName"が呼び出される。
     // 同等のものを自前実装しようかとも思ったが、結構ヘビーだったのと、内部で仕様変更があった時に追随するのが大変なので諦めて使うことにした。
     OtherCompanyLibrary.call(params, "callbackFunctionName");

     return Observable
            .interval(100)
            .timeInterval() // 100ms毎のinterval
            .filter(() => {
                return this.isDone;
            })
            .take(1)
            .map(() => {
                return this.response;
            });
  }

  public callback(response) {
    this.response = response;
    this.isDone = true;
  }
}
```

```:index.html
<script>
function callbackFunctionName(response) {
  window.SampleService.callback(response);
}
</script>
```


windowを介してServiceクラスをやり取りするのと、
Observableのintervalをつかって、処理が完了するのを待つのがポイント。
RSpec + Capybara + Selenium でUserAgent設定 備忘録

# 設定

```rb:Gemfile
gem 'selenium-webdriver'
```

```rb:spec/rails_helper.rb

require 'selenium-webdriver'


# それぞれのUserAgentを持ったドライバを定義しておく
Capybara.register_driver :piyo_driver do |app|
  useragent = "piyo"
  capabilities = Selenium::WebDriver::Remote::Capabilities.chrome(
    chrome_options: {
      args: %W(headless disable-gpu window-size=1680,1050 user-agent=#{useragent})
    }
  )
  Capybara::Selenium::Driver.new(app, browser: :chrome, desired_capabilities: capabilities)
end

```

```rb:spec/features/piyo_spec.rb
require 'rails_helper'

# System Spec ができるようにまだしてない... :cry:

describe 'サンプルテスト' do
  it 'piyoというUserAgentでアクセスする', driver: :piyo_driver do
    # piyoというUserAgentが設定された状態でのテストができる
  end
end
```



# 参考
- [Configuring User Agents with Capybara + Selenium Webdriver « Plataformatec Blog](http://blog.plataformatec.com.br/2011/03/configuring-user-agents-with-capybara-selenium-webdriver/)
- [GitHubGist - Configure User Agent for selenium webdriver in Capybara](https://gist.github.com/carlosantoniodasilva/640361)
- [RSpec の feature spec でヘッドレス Chrome を使う - Speee DEVELOPER BLOG](http://tech.speee.jp/entry/2017/06/15/135636)
- [ruby - How to use headless chrome with capybara and selenium - Stack Overflow](https://stackoverflow.com/q/44591612)
- [capybara/README.md at master · teamcapybara/capybara](https://github.com/teamcapybara/capybara/blob/master/README.md)