OmniAICreator/Qiita-1.07M huggingface dataset:
ブロックチェーン関連用語

## DApp

Distributed Application (分散アプリケーション)

バックエンドが分散P2Pネットワークで動いているオープンソースのアプリケーションのことをいう。 P2Pネットワーク参加者の誰かひとりがスーパー権限を持つようなものではない。

### 長所 Advantage

* 分散されているため、単一障害点がない。
* 権威ある機関によって強制的に停止させられることがない。 中央サーバがあるようなシステムでは、政府によってそこが抑えられたり、そこからのネットワークが強制的にストップさせられることはあるが、分散P2Pネットワークで各国に参加者がいる場合は簡単には止められない。 (局所的にあるエリア内で使用が制限されることはありうる。)
* 信頼がおける。 誰かひとりがスーパーユーザになって利権を独り占めするということがない。

### 短所 Disadvantage

* DApp のバグ修正などを行った場合に、全ての参加者に更新後のアプリケーションを配布するのが困難。
* 中央機関が存在しないため、 KYC (Know Your Customer) のような参加者チェックの仕組みはそれぞれの DApp プロジェクトにおいて考える必要がある。
    * BitCoin では、 アプリケーション内で KYC を行うのではなく、 日本円やドルに交換する取引所 (日本では BitFlyer など) において本人確認を行う方法をとっている。

### アカウント認証方法

最もよく行われているのは、 公開鍵と秘密鍵での認証。 公開鍵のハッシュはアカウント固有のもので、そのアカウントのデータを変更するには変更を秘密鍵で暗号化する。 もちろん、秘密鍵を忘れたらそのアカウントにはアクセスすらできなくなる。

## Consensus Protocol

PoW などのこと。 P2Pネットワークでは、誰かがスーパー権限を持っているわけではないので、なんらかの方法で合意形成をする必要がある。 (参考: [ブロックチェーンのコンセンサス構築メカニズム](/KenjiOtsuka/items/bf2e6c9a2a667d6f36b0))

## Ledger レッジャー

台帳のこと。 ブロックチェーンは分散台帳といわれることがある。 台帳とデータベースは異なるところがあり、台帳が追加のみできるのに対して、データベースは追加・更新・削除が可能でさらにトランザクションも扱える。 もちろん、データベースを台帳のように使うことは可能。

## IPFS InterPlanetary File System

分散ファイルシステム。 DHT (Distributed Hash Table) と Merkle DAG (Directed Acyclic Graph) データ構造 を使用する。 IPFS では Git のようなファイルのバージョン付けが可能。

IPFS では それぞれのノードが、 そのノードにとって必要なファイルを保持する。

InterPlanetary なので、 惑星間ファイルシステム と訳されることが多い。

ひとつのファイルが IPFS に登録されるとき、 256KB 未満 の チャンクに分割され、 各チャンクのハッシュが作成される。 ネットワーク内のノードはそれらを保持する。

IPFS には 4つのファイルタイプがある。 (調査中)

* blob: ファイルのチャンク
* list: blob または他のリストへの参照で、 完全なファイルを表す。
* tree: tree は blob, list, commit を保持するディレクトリ 
* commit: バージョン履歴の中の他のファイルのスナップショット
heroku は無料でどれくらい使えるのか？

##Herokuで無料のスペースがどれくらい使えるか調査
はてなブログなどその他の無料ブログサービスでは容量に制限があります。Herokuには同じように制限があると思いますので、それがどれくらいなのか調査をしてみようと思います。
[こちら](https://stackoverflow.com/questions/17508852/how-much-disk-space-do-heroku-plans-have)で情報があったので、共有してみます。
この情報までたどり着くようにするには次の英語入力で十分だと思います。

>how much space is available in Heroku free plan

この情報からすると２００MB使えるようですね。もうすこし、調査を進めていきます。

一方[こっち](https://www.heroku.com/policy/aup#quota)のページを見れば、５００MBぽいですね。こちらが公式サイトなのでこっちのほうが正しいかな。

以下の[情報](https://devcenter.heroku.com/changelog-items/1145)から、３００MBから５００MBにアップしたとの情報がありますね。
Python学習のためのリンク集

# Python学習のためのリンク集

『いちばんやさしいPythonの教本』を参考に、自分なりの味付けを。


## ドキュメント類

- [3\.6\.5 Documentation](https://docs.python.jp/3/)　：　公式ドキュメントに必要なものが大体揃っている
    - [Python のセットアップと利用](https://docs.python.jp/3/using/index.html)　：　まずここから
    - [Python チュートリアル](https://docs.python.jp/3/tutorial/index.html)
    - [Python 言語リファレンス](https://docs.python.jp/3/reference/index.html)

- [Dive Into Python 3 日本語版](http://diveintopython3-ja.rdy.jp/) :  Python2からPython3へ移植したケーススタディや、イテレータについて詳しい
- [Python\-izm](https://www.python-izm.com/)　：　Python基礎から応用まで幅広くカバーされているのがよい


## リンク集
- [Python リンク集](http://evansmode.hatenablog.jp/entry/2018/05/10/Python_%E3%83%AA%E3%83%B3%E3%82%AF%E9%9B%86)　：　初心者向け。忘れがちな内容など


## 学習サイト
- [ITプログラマ・エンジニア向け転職・就活・学習サービスのpaiza](https://paiza.jp/)　：　ブラウザで完結する開発環境が用意されているのでお勧め。スキルアップが転職に結びつくのもよい
- [PyQ \- 本気でプログラミングを学びたい人のPythonオンライン学習サービス](https://pyq.jp/)　：　学習に100時間～150時間かけることになっているため、時間を確保した上で学ぶことがお勧め。やりきればかなりPythonのコードが身に付くことが期待される。こちらもブラウザだけでOK
- [Project Euler](https://projecteuler.net/)　：　プログラミングで計算問題を解くサイト。例題がたくさんあるため、解くのは楽しい。英語かつ上記2サイトよりはやさしくない
- [CheckiO \- coding games and programming challenges for beginner and advanced](https://checkio.org/)　：　ゲームを遊びながら学習できる。ゲームを動かすため、それなりのリソースが必要（上記3つよりは重い）


## ツール類
- [Python Tutor](http://pythontutor.com/)　：　Pythonプログラムの動作を1ステップずつ視覚的に把握できる
![image.png](https://qiita-image-store.s3.amazonaws.com/0/151198/9e2bd730-0327-9224-5fc5-9be59f396a35.png)
- [Pythonのスタイルガイドとそれを守るための各種Lint・解析ツール5種まとめ！](http://blog-ja.sideci.com/entry/python-lint-pickup-5tools)　：　スタイルガイドを守るためのツール類。見やすいコードを書くためにPEP 8が便利


## Q&A
　疑問点は各種コミュニティで聞いてみることもお勧めです。

- [Stack Overflow](https://stackoverflow.com/)　：　プログラムに関するQ&Aを問い合わせる。ただし英語
- [teratail【テラテイル】｜思考するエンジニアのためのQAプラットフォーム](https://teratail.com/)　：　こちらは日本語


## コミュニティ
　まだまだたくさんあると思いますが……。

- [PyCon JP](https://pycon.jp/)　：　このリンクから最新のPyCon JPサイトへ転送される。毎年開催されるPyCon JPのリンク
- [Python mini Hack\-a\-thon \- connpass](https://pyhack.connpass.com/)　：　自分でやりたいことを持ってきて、勝手に開発を進めるイベント。参加費は無料
- [PyLadies Tokyo \- connpass](https://pyladies-tokyo.connpass.com/)　：　女性のみのPythonコミュニティ
- [PyData\.Tokyo \- connpass](https://pydatatokyo.connpass.com/)　：　「Python という言語の特徴とデータという流行りのトピック活かして、大企業・ベンチャー・学会で活躍してる Pythonista の皆さんがバランスよく交流することのできるコミュニティーづくりを目指しています。」とのこと
- [Python Boot Camp\(初心者向けPythonチュートリアル\) — PyCon JP](https://www.pycon.jp/support/bootcamp.html)　：　初心者向けチュートリアルイベント。全国各地で開催しておりイベント運営者も募集中
SigfoxクラウドAPI

#Sigfox Backend Cloud APIとは
Sigfox Backend Cloud APIは、エンドポイントから、[Sigfox Backend Cloud](https://backend.sigfox.com)に対し、クラウドのグループ・ユーザー管理、デバイス管理を可能にするAPIです。
本APIを使用するためには、Sigfox Backend Cloudのアクセス権を取得してください。

#Sigfox Backend Cloud APIの利用方法
クラウドアクセス権を取得したら、下記の方法でAPIを利用できます。（APIの利用はグループ単位です）

1.[Groupタブ](https://backend.sigfox.com/group/list)からAPIを利用するグループを選択
2.左メニューの「API ACCESS」をクリック

![image.png](https://qiita-image-store.s3.amazonaws.com/0/172313/614e9f5a-a7b7-a97d-2440-0e376edf52ea.png)

3.右上の[New]ボタンをクリック
![image.png](https://qiita-image-store.s3.amazonaws.com/0/172313/b966e75e-25e7-05f9-82b9-682b4a8296e7.png)

4.「Api access information」が表示されるので、NameはAPIに付ける名前（適当で結構です）、Profilesには、ログイン中のユーザーに与えられたアクセス権に該当するロールが一覧表示されます。ここでは、"DEVICE MANAGER[W]"を選択し、[OK]ボタンをクリックします。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/172313/7b39ba3d-aab2-5ebd-e74d-5ee1d95e7f1d.png)

5.設定した名前のAPIアクセス情報が表示されます。APIはBasic認証でのアクセスとなり、Login、PasswordがBasic認証の時に必要ですので、控えておいてください。また、「API documentation」をクリックすると、利用可能なAPIが表示されます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/172313/f2991247-fddf-e5c2-7f30-5bd3053b3d86.png)

>ここで作成したAPI Credential（アカウント）は、設定したグループおよび、その配下のグループに対して有効です。

#デバイスメッセージを取得するAPIを触ってみる
APIのひとつ「Messages sent by a device」を叩いてみましょう。このAPIは下記のURIになっています。ここで、{device-id}のところに、メッセージを取得したいデバイスIDを入力します。
API V2: `GET https://api.sigfox.com/v2/devices/{device-id}/messages`

ABCDEFというデバイスIDのメッセージを取得する場合を例に、ブラウザでAPIを叩いてみます。
ブラウザで、
`https://api.sigfox.com/v2/devices/ABCDEF/messages`
にアクセスすると、Basic認証の確認ダイアログが表示されます。ここで、先ほどのLogin、Passwordを入力すると、下記のようなJSONが返ってきます。

```
{
"data": [
  {
  "device": {
    "id": "ABCDEF"
  },
  "time": 1556780732000,
  "data": "0adb27370147ffe4002203f6",
  "rolloverCounter": 0,
  "seqNumber": 1814,
  "rinfos": [
  {
    "baseStation": {"id": "587C"},
    "delay": 1.8849999904632568,
    "lat": "36.0",
    "lng": "140.0"
  },
  {
    "baseStation": {"id": "8798"},
    "delay": 2.063999891281128,
    "lat": "36.0",
    "lng": "140.0"
  },
  {…}
  ],
  "nbFrames": 3,
  "operator": "SIGFOX_Japan_KCCS",
  "country": "JPN",
  "computedLocation": [ ],
  "lqi": 3
  },
  {...}
]}
```
device（デバイスID）、time（Sigfoxゲートウェイでの受信時刻：unix timestamp）、data（デバイスメッセージ）、seqNumber（シーケンス番号）に続き、rinfosという配列が続きます。このrinfosに、basestation->id（SigfoxゲートウェイのID）、delay（各ゲートウェイからSigfoxクラウドまでの遅延時間）、lat,lngは、Sigfoxゲートウェイの緯度経度（小数点以下省略）を取得できます。
この情報がメッセージ毎に続きます。
**※ただし、Sigfoxクラウドへのアクセス権次第では、取得できない項目もあります。**

#APIで取得可能な情報
APIで取得可能な情報は、先に設定したアクセス権のロールにより異なりますが、DEVICE MANAGER[W]で取得可能な情報は下記のようなものになっています。

|項目|内容|
|:---|:---|
|Groups|グループ一覧、作成、編集、削除|
|Users|ユーザ一覧|
|Device Types|デバイスタイプ一覧、作成、編集、削除、デバイス登録、Callback設定
|Devices|デバイス編集、削除、デバイスメッセージ取得|
|Coverage|Sigfoxサービスエリア情報|
※詳しくは、公式の[API documentation](https://support.sigfox.com/apidocs#section/Authentication-and-security)を参照ください。

[Sigfox Japan KCCS](https://qiita.com/organizations/sigfox)
パスワードの保存方法について

# 目的
こんどモブプログラミング会で認証部分を作るので、知っていることを棚卸してみます。

# パスワードの保存
IPAの[安全なパスワードの作り方](https://www.ipa.go.jp/security/vuln/websecurity.html)でも紹介されてます。salt付ハッシュ値の形でパスワードは保管しておきます。
## なぜsalt付ハッシュ値？
大前提として、データは盗まれる可能性があります。プログラムをちゃんと作っていても、標的型攻撃や、内部犯には対抗できません。それに、完璧なプログラムなんてないと思います。
そうすると「盗まれても大丈夫」な方法でパスワードを保存しておく必要があります。（大丈夫、は言い過ぎかな。。）
### 暗号化すればいいじゃん
確かに、暗号化すれば読み取れません。しかし、復号方法がばれてしまえばパスワードがすべて読み取られてしまいます。別途復号方法を盗まれるなりすれば一大事です。生パスワードを保存しているよりははるかにいいですが。
### ではハッシュ化すれば十分か
一方向ハッシュ化すれば復号できません（一応できるけどとても時間がかかる）。しかし、復号できなければOKかといったらそうではありません。あらかじめ同じハッシュ関数をつかってありそうなパスワードからハッシュ値の辞書を作っておくこともできます（レインボーテーブルと呼ぶそうです）。その辞書から逆引きすれば、パスワードがばれてしまいます（すべてのユーザが複雑なパスワードを設定しているとは限りませんので）。
### だからsalt付ハッシュ値
`salt`と呼ばれるユーザ毎に異なる文字列をくっつけてハッシュ化します。辞書を作ってパスワードを割り出そうにも、作らなければならないパターンが膨大になり、解読は現実的でなくなります。とはいっても時間をかければ解読できないくもないので、
パスワードデータが漏洩したことが発覚したら、ユーザーに対してパスワード変更の依頼を迅速に出すことも大事そうです。不正なアクセスがないかどうか、監視の目は光らせる必要がありそうです。
airportで通信環境を知る

#コマンド**airport**を使用してRSSI，SSIDを確認した
自身で使用したものだけ記述します．

    airport -s # 現在接続可能なAP（アクセスポイント）の状況を取得
    airport -I # 現在接続しているAPの情報を取得

    airport -s >> ap.txt # ap.txtに情報を書き込める


他にもtcpdumpやtsharkといったコマンドからwiresharkなどのソフトでも確認可能なので後々試してみたい
tblsでデータベースドキュメントを生成する（3. CI連携編）

> 1. [ドキュメント生成編](https://qiita.com/k1LoW/items/2010413a8547b1e6645e)
> 2. [テーブル情報補完編](https://qiita.com/k1LoW/items/92d1be1437a259827338)
> 3. [CI連携編](https://qiita.com/k1LoW/items/1517fc4470de3f121f11)

[tbls](https://github.com/k1LoW/tbls)にはCIと連携することを想定したコマンドがあります。

## `tbls diff` コマンド

`tbls diff`は対象データベースと既に作られたドキュメントのdiffを確認するコマンドです。

例えば [.tbls.ymlを設置したうえで](https://qiita.com/k1LoW/items/2010413a8547b1e6645e) `tbls doc` でドキュメントを生成していた場合、

```console
$ tbls doc
```

`doc` を `diff` にするだけでDSN先のデータベースと既に作られたドキュメントとのdiffを確認できます。

```console
$ tbls diff
```

これをCIに組み込むことで、「ドキュメントが正しく更新されているか」をチェックすることができます。

例えば、　`.travis.yml` などにワンライナーで組み込むとしたら以下のような形で組み込むことが可能です。

```yaml
script:
  - tbls diff
```

Makefileなどであれば以下のように`make doc` `make testdoc` を作成できます。

```makefile
doc: ## Document database schema
	tbls doc

testdoc: ## Test database schema document
	tbls diff
```
---

たったこれだけでtblsとCIを連携することができました。

データベースを持つアプリケーションのCIでは大抵データベースのマイグレーションが走ると思います。

そのあとに `tbls diff`　を使えば、データベースドキュメントの更新テストを合わせて実施することができます。
UnityでニコニコAPI使おうとしたら詰まった件


ニコニコのAPI経由で動画を取得しようとすると以下のような手順が必要です。

- ログインAPIにIDとパスワードをPOSTしてCookie user_sessionを取得
- user_sessionを含むCookieを持たせ動画URLにGETリクエストしCookie nicohistoryを取得
- getflv APIにuser_sessionとnicohistoryを含むCookieを持たせGETリクエストして動画URLを取得
- 動画URLにuser_sessionとnicohistoryを含むCookieを持たせGETリクエストして動画を取得

非常にめんどくさいですが全部WebRequestなのでURLとCookie用のHashtableさえ用意すれば簡単に行く

はずなんですが。

ログインAPIにPOSTしてもSet-Cookieヘッダにuser_sessionが含まれないのです。


というわけで数時間思考した結果に見つけた結論を以下にはっつけておきます。

``` NiconicoAPI.cs
using UnityEngine.Networking;

public class NiconicoAPI {
    public const string NICONICO_LOGIN_URL = "https://secure.nicovideo.jp/secure/login?site=niconico";
    public string userSession = null;

    public IEnumerator Login() {    
        string id = "your@mail.address";
        string pass = "yourpassword";
        
        WWW form = new WWWForm();
        form.AddField("mail_tel", id);
        form.AddField("password", pass);
        
        UnityWebRequest www = UnityWebRequest.Post(NICONICO_LOGIN_URL, form);
    
        //これがめっちゃ重要
        www.redirectLimit = 0;
        
        yield return www.SendWebRequest();
        
        Dictionary<string, string> headers = www.GetResponseHeaders();
        
        string setCookieHeader = null;
        try {
            setCookieHeader = www.GetResponseHeader()["set-cookie"];
        } catch(KeyNotFoundException keyNotFoundException) {
            //post情報が間違っててSet-Cookieすら含まれない状態
            Debug.Log(keyNotFoundException.Message);
        }
        
        //Set-Cookieヘッダに含まれるuser_sessionは3つあって、そのうち必要なものはuser_sessionから始まる
        //他は"deleted"とsecureなんたらとかいうの。いらない。（知らんけど)
        foreach(string cookie in setCookieHeader.Split(new string[] {"user_session="}, StringSplitOptions.None)) {
            if(cookie.StartsWith("user_session")) {
                this.userSession = cookie.Split(';')[0];
            }
        }        
        www.Dispose();
    }
}
```
    
とこんな感じになります。

ニコニコのログインAPIって、ログイン情報渡した後に公式サイトかユーザーページにリダイレクトしてくるっぽいのです。


そしてリダイレクト時に新たなSet-Cookieヘッダがセットされる？ためログイン時にセットされたSet-Cookieヘッダが消える？のです。

なので、UnityWebRequestのインスタンスのredirectLimitを0にしてやるとRedirectを許さないリクエストになりLoginサーバーがセットしたSet-Cookieヘッダがそのまま受け取れます。


ちなみに、残りのGETリクエストに関してはredirectLimitは必要ないです。
rubyで配列をCSVに書き込み,読み込み

##何かしらの配列(array)をCSV(hoge.csv)へ書き込み

配列を一つ一つ**.each**で書き込んでいくイメージ

```rb
   CSV.open('hoge.csv','w') do |csv| # output to csv file
         array.each do |bo|
             csv << bo
         end        
    end
```

##CSV(hoge.csv)を配列(array)に読み込んで格納する
```rb
    CSV.foreach("hoge.csv") do |line|
        p line #一行ずつ出力する
        array.push(line) # arrayに格納する
    end
```
書き方はたくさんあるし，書きやすいコードを見つけてください！
テキストに特定の文字(列)が含まれているか調べる

`C#`です。
`String.Contains`を使うやり方、`LINQ`を使うやり方、正規表現を使うやり方で調べます。

## 特定の文字列(`string`)が含まれているか調べる

`String.Contains`を使う。
`IndexOf`を使って戻り値が0以上か調べるより直感的です。

```csharp
using System;
⋮
var text = "How razorback - jumping frogs can level six piqued gymnasts!";
var target = "jumping";
if (text.Contains(target))
   Console.WriteLine($"{target}が含まれています");
```

## 特定の文字(`char`)が含まれているか調べる

`String`は`IEnumrable<char>`を実装しています。
ですので、LINQ の`Enumerable.Contains<TSource>`が使えます。

```csharp
using System;
using System.Linq;
⋮
var text = "Jackdaws love my big sphinx of quartz";
char target = 'b';
if (text.Contains(target)) // <-拡張メソッドのほうの Contains
    Console.WriteLine($"{target}が含まれています");
```

`Enumerable.Any<TSource>`を使うともう少し柔軟です。
`for`文で探すより直感的です。

```csharp
using System;
using System.Linq;
⋮
var text = "Point of view is worth 80 IQ points.";
if (text.Any(c => char.IsDigit(c)))
    Console.WriteLine("数字が含まれています");
```

## 複数の文字列(`string`)、文字(`char`) のいずれかが含まれているか調べる

複数なら`Contains`を `||` でつなぐより、正規表現を使うと簡単です。

```csharp
using System;
using System.Text.RegularExpressions;
⋮
var text = "The quick onyx goblin jumps over the lazy dwarf.";
var pattern = "dragon|goblin|elf";
if (Regex.IsMatch(text, pattern))
    Console.WriteLine("いずれかが含まれています。");
```

## 参考

「[実戦で役立つ C#プログラミングのイディオム/定石&パターン](https://www.amazon.co.jp/実戦で役立つ-C-プログラミングのイディオム-定石-パターン/dp/4774187585)」
超良書です。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/195024/c4f0e1f4-f558-58f1-38d4-9c09a80f4843.png)
macでIPアドレスのみを知る方法

#mac book air でIPアドレスのみを知る方法
コマンド **ifconfig**を使用

    ifconfig en0 | grep 'inet 10' | grep -v '127.0.0.1' | cut -d: -f2 | awk '{ print $2}



これで確認が可能

他にもhomenameやipといったコマンドでもできます．
Streamでcollect(Collectors.toList())は絶対にnullにならない件

collect(Collectors.toList())を使用した場合、戻り値のnullチェックが必要かどうか調べました。

# 可変リダクション操作（mutable reduction operation）とは
リダクション操作とは、一連の要素に特定の演算を適用して1つにまとめる操作です。
Stream#collectでは、Listのような可変なオブジェクトに要素を収集するため、「可変リダクション操作」と呼んでいるようです。

# Collector
Collectorインターフェースでは4つのメソッドを定義しており、4つのメソッドの戻り値は全て関数オブジェクトになっています。

|     メソッド      |       工程         |
|:-----------------:|:------------------:|
|supplier           |前処理              |
|accumulator        |集積                |
|combiner           |結合                |
|finisher           |後処理              |


# Collector.toList()
toList()のソースを見てみると、前処理はArrayListをnewしているため、
空リストが必ず生成されて、戻り値はnullにはならないことをわかりました。

```java:Collectors.java
public static <T>
Collector<T, ?, List<T>> toList() {
    return new CollectorImpl<>((Supplier<List<T>>) ArrayList::new, List::add,
                               (left, right) -> { left.addAll(right); return left; },
                               CH_ID);
}
```

ということで、null checkは不要、empty checkだけで十分です。
cronの使えないContainer-Optimized OSでスケジュールジョブを実行する

GoogleCloudPlatformで利用できるコンテナ実行向け軽量OSであるContainer-Optimized OSは，すべてのプログラムをdockerコンテナで実行させることを前提に設計されており，aptやyumなどのパッケージ管理システムを意図的に持っていない．そのため，cronなどのスケジュールジョブを実行させたければ，cron自体をdockerコンテナとして動かす必要があるが，コンテナの中で実行されるため，ホスト側にアクセスすることが容易ではない．

コンテナを定期的に再起動しながら運用したい時はあるので困っていたところ，以下の方法で実現できた．

```yaml:docker-compose.tasker.yaml
version: "2"

services:
  tasker:
    image: strm/tasker:1.0.1
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock"
    environment:
      configuration: |
        schedule:
          - every: 2 hours
            task: restart-something
        tasks:
          docker:
            - name: restart-something
              image: docker/compose:1.13.0
              volumes:
                - "/var/run/docker.sock:/var/run/docker.sock"
                - "/home/someuser/somedir/:/code/somedir"
              script:
                - cd /code/somedir/
                - docker-compose up -d --force-recreate something

```

https://github.com/opsxcq/tasker というdockerイメージを使用して，そのdockerコンテナ内でdocker-composeコンテナを実行している．ホストの`/var/run/docker.sock`をマウントすることでコンテナ内でdockerやdocker-composeを実行してもホストのdockerプロセスに命令を出すことができているというわけだ．


###### 補足
configuration内でvolumeマウントしている`- "/home/someuser/somedir/:/code/somedir" ` この部分は 

```yaml
script:
  - cd /code/somedir/
  - docker-compose up -d --force-recreate something
```
と対応している．この例は，/home/someuser/somedirに実行したいプログラムとdocker-compose.yamlファイルがある想定で書いている．
1ヶ月ぶっ通しでペアプロしたスタートアップエンジニアがオススメするペアプロ習慣

#**はじめに**

11月に、[ユリシーズ株式会社](https://kaminashi.jp/)に3人目の[エンジニア](https://www.wantedly.com/projects/210333)として[もう一人](https://qiita.com/kurkuru)と入社しました。
3言語を使いこなす[一人目のエンジニア](https://qiita.com/choujuku)に対し、素人同然のふたり。
そこで、「まず一言語を…」と、iOS (Swift)担当とAPI (Golang) /Web (React.js) 担当に分かれて作業していました。

〜〜〜〜〜〜〜〜

時は流れて入社から5ヶ月。
一人目のエンジニア氏がPMにステップアップしようかというそのとき、ハッと気づきました。

**相手の書いたコードが読めないからレビューができない…！！**

つまり、

**<font color="Red">相手がいなくなったらコードが保守できない……！！！</font>**

これはマズい…！という訳で、我々11月入社二人は立ち上がりました。
**ペアプロで暗黙知を共有するのだ！！**

という状態から早1ヶ月が経ちましたので、ペアプロしている時に大事にしていることをご紹介します。

##**TODOリストをディスプレイする**
どんなに小さなissueでも、細分化してこの順番でやる、というのがあると思います。
最初の方は雰囲気で実装側がごにょごにょ言いながら進めていると、見ている側から「今何してんの…？？？」という遠慮がちなツッコミが入ることがままありました。

* <font color="Blue">今ここまで終わっている</font>
* <font color="Blue">残りの課題はこれ</font>
* <font color="Blue">今からはこれをやっていく</font>

この三つを自分の実装ターン開始前に明示して相手に共有することで、お互い同じ目標を持ってディスプレイと向き合うことができるのでとてもオススメです。

## **好きな音楽をかける**
音楽は全てを癒してくれます。

言いすぎたかもしれません。しかし、我々ふたりは一人で実装しているときも曲を聴きながら仕事をしていたため、音楽があると非常に捗りました。
午後の眠たい時にはアップテンポな曲を流してみるとか、ハワイアンな音楽を流して豊かな気分になってみるとか、
音楽で気持ちを保ったまま仕事ができることはとても重要です。

それだけです。**No Music, No Life.**

##**CubeTimerを買う (休憩を多めにとる)**
ペアプロを開始する前に[ペアプロの心得](https://gist.github.com/j5ik2o/2970973)を読んで、一人30分と決めていたものの、
普段はお昼以外は意識して休憩をとっていなかったので、気づいたら一人が1時間くらいコーディングしてしまっていたこともありました。

ペアプロしたことない方は是非知っておいてほしいんですが、

**ペアプロってめっちゃ疲れます。**

普段は自分のペースで進められるものを、相手がいるので実装側も見ている側も`ひくにひけない`、みたいな状況に簡単に陥ってしまいます。
しかも疲れると、イライラしてしまうという協働作業実施中にあらざる事態に…！
`Webタイマー`を導入したのですが、今度はタイマーを開始するのを忘れる、時間がすぎたのに気づかない、などの問題点が発生しました。

そこで我々が購入したのがこちらの[CubeTimer](https://www.amazon.co.jp/%E3%82%BF%E3%82%A4%E3%83%A0%E3%82%AD%E3%83%A5%E3%83%BC%E3%83%96-Time-Cube-DF-38-5%E5%88%86%E3%80%8110%E5%88%86%E3%80%8120%E5%88%86%E3%80%8125%E5%88%86/dp/B06XS1SSQ5/ref=pd_sim_201_7?_encoding=UTF8&psc=1&refRID=9D8AWMETFK48PB37HX23)。
<img width="300" alt="かわいいCubeTimer" src="https://qiita-image-store.s3.amazonaws.com/0/260490/1f7ed01b-6e3c-b090-4c97-cebffa0928dc.jpeg">

とてもかわいいですね。物理的なものがソフトに勝った瞬間です。
25分実装→5分休憩、というのも一動作で実現できますし、常に目に入ることで忘れにくくなりました！
ちょっと疲れたな…という時のために休憩10分にも対応してます！素晴らしい！！
また、タイマーに付箋を貼り付けてひとつのissueに何ターンかかったか、を記録することで近似的に開発のベロシティを計測することもできます！！
<img width="300" alt="ベロシティ計測用メモ" src="https://qiita-image-store.s3.amazonaws.com/0/260490/a0b055fe-34e9-5654-95b8-8532855dc64a.jpeg">

##**役割にこだわらない**
一般的にペアプロは、`ドライバ`と`ナビゲータ`に別れてやっていくようですが、我々はその役割にこだわりません。
はじめは、暗黙知の共有ということで、自分が不慣れな言語を実装しつつ、相手が口出すスタイルでしたが、
今は上記のTODOリストに従って行くスタイルなので、`しゃべりたい方がしゃべって合意がとれたらコーディングして行く`という感じです。
TODOリストがあるので、お互いで違うことを考えることはほとんどありません。
見ている側は暇なのでは…と思うかもしれませんが、相手が書いているコードに集中していないと、「置換忘れてるやん！」とか「今の魔法 (ショートカット) 何！？」とか**ツッコミそこねてしまうので結構忙しいです。**


##**しゃべり続ける**
一定時間しゃべらないと、不思議なことに人って話し出しづらくなります。(なりませんか？)
なので、「そだねー」とか「おけー」とかだけでもいいのでしゃべり続けておくと、ここぞというときに**ツッコミそこねることがなくなります。**


#**終わりに**
1ヶ月終えて、続けていきたいと思っているところを書いてみました。
これからペアプロを始める方、ペアプロやってみたけどイマイチだったな、と思っている方に参考になれば嬉しいです！
最後になりましたが、[他の人とともペアプロしてみたい](https://www.wantedly.com/projects/210333)ので、よろしくお願いします！！
コミットの時にブランチ名とprefixチェックをしてみた

コミットメセージにブランチ名とプレフィックスを追加するようにしているが、ために忘れることがあるためミスが起きないように以下の２点をgit hookに追加した。

* コミットメッセージの先頭にブランチ名を付けること(prepare-commit-msg)
* コミットメッセージにprefixが記述されているかチェックすること(commit-msg)

## prepare-commit-msg側
ブランチ名を取得してそれをコミットメッセージの先頭に追加すれば問題ないと思いましたが、コミットメッセージの修正のために`git commit --amend`をするとそのたびにブランチ名が追加されてしまいます。
そのため、既にコミットメッセージの先頭にブランチ名が追加されている場合には削除する処理も追加しました。

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

branch = `git branch | grep '*'`.chomp.sub('* ', '')
commit = File.readlines(ARGV[0])

if ARGV.length==0
  return
end

index = commit[0].index(branch)
if index != nil && index == 0
  commit[0] = commit[0].sub(/^#{branch}\s/, "")
end

open(ARGV[0], 'w') {|file|
  file.print "#{branch} "
  file.puts commit
}
```

## commit-msg側
コミットメッセージ内にprefixが記述されているかをチェックし、記述がなければ記述するよう促すメッセージを表示する処理にしました。

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

commit_message = File.readlines(ARGV[0])

filter=/(feat|style|chore|refactore|test|doc|fix)+:/

warning_message=<<COMMIT_WARNING
*****************************************************************************
Add a prefix when committing

feat (feature)
fix (bug fix)
docs (documentation)
style (formatting, missing semi colons, …)
refactor
test (when adding missing tests)
chore (maintain)
*****************************************************************************
COMMIT_WARNING

if !filter.match(commit_message[0])
  print warning_message
end
```

今回は既存のプロジェクトに追加しましたが、新規に作成することも考慮すると[gitのhookを全リポジトリで共有するよう設定](https://qiita.com/k0kubun/items/5cb8209e3d1854ac2e2e)したほうが良いかもしれません。
また、git hookが上手く動作しない場合はエラーメッセージを確認する、もしくは権限設定が漏れていないか確認してみてください。

以下の記事を参考

* https://qiita.com/mima_ita/items/dcaa3789022d2a9ab929
Eclipse環境移行で、起動エラー(Win7→Win10)

Win7→Win10で環境移行したが、Eclipse起動エラー発生した時の対処法メモ

前提条件
・EclipseLuna
・JDK1.7
・jre7
・Eclipse、JDK、jreのフォルダ全部コピー済み
・eclipse.iniのvmの場所変更済み

1. Exlipseを右クリック→管理者実行
2. エラー「A Java Runtime Environment (JRE) or Java Development Kit (JDK) must be available in order to run Eclipse...」

…

Windowsの環境変数やらでJAVA_HOMEとかいろいろ変えてみたけどダメ。

対処したこと

1. JDKのインストーラを再実行→C:\ProgramFiles\Java配下にインストールされる
2. eclipse.ini のvmの場所を再度変更

対応後、Windowsの環境変数みたけど、Win7のときみたく、Java_HOMEとかTomcat_HOMEはなかった。


以上。
Deviseを利用したパスワードを手動で変更する方法


Railsでアプリケーションを作る際、deviseを利用するとログイン認証部分が簡単に作成できます。

deviseを利用するとユーザーのパスワードは暗号化されて保存されます。

開発をしているとデータを直接いじってパスワードを変更したい時があります。
その場合、以下のようにします。

```
user = User.find(パスワードを変更したいユーザーのID)
user.password = '新しいパスワード'
user.password_confirmation = '新しいパスワード'
user.save
```

もっと簡潔に書くならば、[Device::Recoverable#reset_password](https://www.rubydoc.info/github/plataformatec/devise/Devise/Models/Recoverable#reset_password-instance_method) を利用して、以下のようにパスワードを変更することも可能です。

```
User.find(id).reset_password(password, password)
```

by <a href="https://twitter.com/nishina555" target="_blank" rel="noopener">@nishina555</a>
Deviseでadminの時だけ登録・更新時にメールを送らない設定

###以下のサイトが本当に役に立った。

http://www.tom08.net/entry/2016/12/13/155321
https://qiita.com/colorrabbit/items/ff976c0a6ec2dae9814c

登録時のメール確認スキップ

skip_confirmation!

更新時のメール確認スキップ

skip_reconfirmation!
androidでkotlinの入門　リバーシー

リバーシー≒オセロです

前回のコードで、コンソールで大まかなロジックを確認して
アンドロイドスタジオにコードを持って乗って表示部を追加

盤の表示は

```BOARD_DISP.kt
class BOARD_DISP(context : Context, val boardStatus : GAME_STATUS, val masuSelect : SELECT_MASU )  : View(context) {

    // 
    private val paint = Paint()
    private val res: Resources = this.getContext().getResources()     // 画像準備
    // 画像のサイズは 
    // １マス=48×48 
    private val IMG_NORMAL: Bitmap = BitmapFactory.decodeResource(res, R.drawable.normal)
    private val IMG_READY: Bitmap = BitmapFactory.decodeResource(res, R.drawable.ready)
    private val IMG_BLACK: Bitmap = BitmapFactory.decodeResource(res, R.drawable.black)
    private val IMG_WHITE: Bitmap = BitmapFactory.decodeResource(res, R.drawable.white)
    // ボードは 48*8=384なので 384×384にしました
    private val IMG_BOARD: Bitmap = BitmapFactory.decodeResource(res, R.drawable.board)

    private val masuSize: Float = (IMG_BOARD.width / 8).toFloat()     // 1マスのサイズ
    private val fukantai: Float = masuSize / 10.0F                    // 反応しない幅

    private var boardLeft: Float = 0.0F
    private var boardTop: Float = 0.0F

    override fun onDraw(c: Canvas) {
        // 
        boardLeft = ((c.getWidth() - IMG_BOARD.width) / 2).toFloat()
        c.drawBitmap(IMG_BOARD, boardLeft, boardTop, paint)
        
        for (x: Int in 0..7) {
            for (y: Int in 0..7) {
                val img: Bitmap = when (boardStatus.banStatus[x][y]) {
                    GAME_STATUS.MASU_STATUS.BLACK -> IMG_BLACK
                    GAME_STATUS.MASU_STATUS.WHITE -> IMG_WHITE
                    GAME_STATUS.MASU_STATUS.READY -> IMG_READY
                    else -> IMG_NORMAL
                }
                // ステータスに応じて画像を表示
                val masuLeft = (x * masuSize + boardLeft).toFloat()
                val masuTop = (y * masuSize + boardTop).toFloat()
                c.drawBitmap(img, masuLeft, masuTop, paint)
            }
        }
    }
}
```

として、
各処理が終わったら
invalidate()
をコールして、ゲーム盤を表示するようにしました

![reversi.png](https://qiita-image-store.s3.amazonaws.com/0/258658/a65cfa7a-ab07-088e-43fd-8415d538b7b6.png)

こんな感じになります
Azure Data Science VM (DSVM) の Chainer + CuPy を最新バージョンにする

# 状況
残念ですが、古いバージョンの Chainer と CuPy が入っている場合があります。ここでは、最新バージョンへのアップデート手順を説明します。

# 必要なもの
- Azure のサブスクリプション (契約)

  - お持ちでない方は、こちらから。
  - https://azure.microsoft.com/ja-jp/free/

- 注意点: 無料版では、GPU の使えるコア数が割り当てられていません。GPU などのコア数増加については、こちらをご参照ください。
  - https://qiita.com/satonaoki/items/a1d2545ca78adf540f8e

# Azure DSVM の作成

Azure のポータルにログインして、Ubuntu の Data Science VM を作成します。
GPU インスタンスは料金高めなのでご注意ください!

- Linux (Ubuntu) データ サイエンス仮想マシンのプロビジョニング
  - https://docs.microsoft.com/ja-jp/azure/machine-learning/data-science-virtual-machine/dsvm-ubuntu-intro

# Chainer のバージョン確認
ssh などで DSVM にインストールされている Chaienr のバージョンを確認します。

```Bash
pip freeze | grep -e 'chainer' -e 'cupy'
```
執筆時点 (2018/6/12) に作成したDSVMですと、以下が取得できます。

```Bash
chainer==3.4.0
chainercv==0.8.0
chainermn==1.2.0
chainerrl==0.3.0
cupy==2.4.0
```

残念...
最新にしましょう!

# CUDA のバージョン確認
こちらのコマンドで...

```Bash
nvcc -V
```
結果。9.0 ですね。

```Bash
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2017 NVIDIA Corporation
Built on Fri_Sep__1_21:08:03_CDT_2017
Cuda compilation tools, release 9.0, V9.0.176
```

# Chainer ＋ CuPy のアップデート手順

Chainer は CuPy も使っていますので、双方を:

- アンインストール
- インストール

する必要があります。

ssh などでログインして、以下を実行します。
途中で (yes/no) を聞かれたら、"yes" にて。

```Bash
pip uninstall chainer
pip uninstall cupy
pip install chainer
pip install cupy-cuda90
```

- CUDAのバージョンが9.0.なので、`cupy-cuda90`を指定しています。
  - 参考: https://qiita.com/mitmul/items/1e35fba085eb07a92560#%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB

# Smake Test - 確認
以下のコマンドにて、ChainerとCuPy が最新になっている事を確認します。

```Bash
python3 -c 'import chainer; chainer.print_runtime_info()'
```

結果

```Bash
Chainer: 4.1.0
NumPy: 1.14.1
CuPy:
  CuPy Version          : 4.1.0
  CUDA Root             : /usr/local/cuda
  CUDA Build Version    : 9000
  CUDA Driver Version   : 9010
  CUDA Runtime Version  : 9000
  cuDNN Build Version   : 7104
  cuDNN Version         : 7104
  NCCL Build Version    : 2104
```

## 次にやること
さぁ! これで安心して、Chainer チュートリアル を DSVM 上でのJupytorNotebook で試しましょう!!!

- DSVM JupyterNotebook
  - https://docs.microsoft.com/ja-jp/azure/machine-learning/data-science-virtual-machine/dsvm-ubuntu-intro#how-to-access-the-data-science-virtual-machine-for-linux

- Chainer v4 ビギナー向けチュートリアル:
  - https://qiita.com/mitmul/items/1e35fba085eb07a92560
外部からPOSTできない？RailsのCSRF対策をまとめてみた

Railsアプリケーションに対して、外からPOST送信しようとすると、422エラー・Can't verify CSRF token authenticityエラーが出ます。
これはRailsが自動で生成してくれるCSRF対策によるものらしく、よくわかっていなかったのでまとめてみました。

# CSRFとは
CSRF（クロスサイトリクエストフォージェリ）は攻撃の一種なのですが、簡単に説明すると「<span style="color: #d32f2f">攻撃者がターゲットに、自分で自分を攻撃させる攻撃</span>」です。

もうちょっと詳しく言うと、「<span style="color: #d32f2f">自分がログインしている（常時ログインなどで）サービスへ、知らぬ間にリクエストを送らされる攻撃</span>」です。

通常、常時ログインなどでは、cookieにセッション情報が格納されますが、Railsではリクエストのたびにcookieを自動的に取得します。

そして、これこそがCSRFがつけいるセキュリティの穴なんです。

どういうことかというと、cookieはブラウザもしくはサーバに保存されているので、<b>別サイトからリクエストが送られたときにも正しいcookieが使用されてしまう（認証が通ってしまう）</b>のです。

画像にコマンドを仕込むなどすれば、リクエストを知らぬ間に送らせることは簡単なので、ユーザーが意図しないリクエストが通ってしまうことになります。

ー 参考
[「Ruby on RailsのCSRF対策」](https://www.transnet.ne.jp/2016/10/26/%E3%80%8Cruby-on-rails%E3%81%AEcsrf%E5%AF%BE%E7%AD%96colnd/)

# CSRF対策の定番
なので、Webアプリ側でそのような攻撃を防ぐ必要があるのですが、そのための方法として、<b>アプリ内でリクエストをする際は認証用のtokenを差し込む</b>というものがあります。

つまり、「お前味方か？」という確認をするということです。そしてその結果として必然的に、<span style="color: #d32f2f">外からのリクエストをすべて弾く</span>ことになります。

# RailsのCSRF対策
Railsではありがたいことに、そのCSRF対策を自動生成してくれています。
それがapplication_controllerが作られるときに自動で書き込まれるprotect_from_forgeryメソッドです。

## protect_from_forgery メソッド
実は、RailsではViewで<b>form_forやform_tagを使うと、自動でCSRF対策用のトークンを埋め込んでくれています</b>。

そして、protect_from_forgeryによって、アクション実行前に正しいトークンが付随されているかをチェックしています。

逆に言えばこのメソッドの適用外は自分で対策をしなければならないということでもあります。

ー 参考
[Rails セキュリティガイド ー 3.クロスサイトリクエストフォージェリ (CSRF)](https://railsguides.jp/security.html#%E3%82%AF%E3%83%AD%E3%82%B9%E3%82%B5%E3%82%A4%E3%83%88%E3%83%AA%E3%82%AF%E3%82%A8%E3%82%B9%E3%83%88%E3%83%95%E3%82%A9%E3%83%BC%E3%82%B8%E3%82%A7%E3%83%AA-csrf)

## Ajax送信を行うとき
じゃあ、AjaxでPOST送信したいときは、form_forなどを使ってないので自分で対策しなくてはいけないかというと、Railsはここまでカバーしてくれています。

Ajaxの場合、Ajax送信する直前に実行されるメソッドで、トークンを指定しているようです。

ー 参考
[RailsのCSRF対策の仕組みについて](http://shindolog.hatenablog.com/entry/2014/09/01/013840)

## 外部からの送信を受けたいとき
このメソッドはCSRF対策しているから大丈夫、しなくても大丈夫、だから外部からリクエストできるようにしたい。という場合はこんな回避方法があるようです。

1. protect_from_forgery with: :null_session
コントローラーごとしなくてOKの場合は、こうすると良いようです。APIを作るとき用のものみたいですね。
ー 参考
[Rails 4.0だとCSRFトークンでエラーになる](https://qiita.com/naoty_k/items/b40b13735fd7f06f8cb7)
2. protect_from_forgery :except => [:action]
そのメソッドだけというときはexceptで指定すると良いようです。
ー 参考
[Rails4のCSRF対策で「Can't verify CSRF token authenticity」エラー](https://qiita.com/chobi9999/items/2b59fdaf3dd8f2ed9268)
use libcloud and aws s3


# create driver

```.py

from libcloud.storage.types import Provider as s3_provider
from libcloud.storage.providers import get_driver as get_s3_driver
        
s3Driver = get_s3_driver(s3_provider.S3_AP_NORTHEAST)
driver = s3Driver(EC2_ACCESS_ID, EC2_SECRET_KEY)

```

# donwload binary on memory

```.py
obj = driver.get_object(container_name='bucket_name', object_name='object_name')
generator = obj.as_stream()
return next(generator)
```

# upload binary on memory
```.py
# upload bytes
bytes_io = io.BytesIO(bytes)
container = driver.get_container(container_name=S3_BUCKET)
driver.upload_object_via_stream(iterator=bytes_io,
                                container=container,
                                object_name='object_name',
                                extra={'content_type': 'application/octet-stream'})
```
[darkflow] YOLOv3 & tensorflow サンプル

#### 導入に関しては、↓のサイトが分かり易いです。
http://ai-coordinator.jp/yolov2-tensorflow-python-

```python
from darkflow.net.build import TFNet
import matplotlib.pyplot as plt
import cv2
import sys
img_path = "./sample_img/dog.jpg"
options = {"model": "cfg/yolo.cfg", "load": "bin/yolo.weights", "threshold": 0.1, "gpu": 0.5}
tfnet = TFNet(options)
img = cv2.imread(img_path)
height, width, channels = img.shape
results = tfnet.return_predict(img)

for item in results:
  tlx = item['topleft']['x']
  tly = item['topleft']['y']
  brx = item['bottomright']['x']
  bry = item['bottomright']['y']
  label = item['label']
  conf = item['confidence']

  if conf > 0.5:
    cv2.rectangle(img, (tlx, tly), (brx, bry), (200,200,0), 2)
    text = label + " " + ('%.2f' % conf)
    cv2.putText(img,
    text,
    (tlx+10, tly-5),
    cv2.FONT_HERSHEY_SIMPLEX,
    0.6,
    (244, 86, 66),
    2)

plt.imshow(img)
plt.show()
cv2.imwrite("./result.jpg", img)
```
[小ネタ] FireMonkey でメインフォームを非表示にする

# 実行時にメインフォームを隠す

タスクトレイにアイコンを表示して常駐するタイプのアプリケーション等、メインフォームが表示されては困る場合があります。

こういったアプリケーションを実現するために VCL には起動時にメインフォームが表示されないようにする仕組みがありました。

FireMonkey はどうかというと、更に柔軟な解決方法が用意されています。

## VCL の場合

VCL では、[TApplication に ShowMainForm プロパティがあり、これに False を入れると MainForm の表示を阻止できました](http://docwiki.embarcadero.com/RADStudio/Tokyo/ja/%E3%83%A1%E3%82%A4%E3%83%B3_%E3%83%95%E3%82%A9%E3%83%BC%E3%83%A0%E3%81%AE%E9%9D%9E%E8%A1%A8%E7%A4%BA)。

```pascal
program Project1;

uses
  Vcl.Forms,
  Unit1 in 'Unit1.pas' {Form1};

{$R *.res}

begin
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.ShowMainForm := False; // ←コレ！
  Application.Run;
end.
```
## FireMonkey の場合

FireMonkey の TApplication は VCL と違い ShowMainForm プロパティはありません。
では、どうするかというと [TCommonCustomForm.CanShow](http://docwiki.embarcadero.com/Libraries/Tokyo/ja/FMX.Forms.TCommonCustomForm.CanShow) メソッドを override して実現します。

具体的には

```pascal
type
  TForm1 = class(TForm)
  public
    function CanShow: Boolean; override; // override
  end;

implementation

function TForm1.CanShow: Boolean;
begin
  Result := False;
end;
```

と、こんな感じです。
MainForm 以外の Form ももちろん同じやり方で非表示化できます。

ただし、上の例のように必ず False を返すようにすると**絶対に表示されない**ので、本来はフラグで管理するといいと思います（初回だけ非表示とか）。

# まとめ
CanShow や [OnClose](http://docwiki.embarcadero.com/Libraries/Tokyo/ja/FMX.Forms.TCommonCustomForm.OnClose) を使うと Form のライフタイムとは別に Visible だけ変化できます。
お試しあれ

…え？ FireMonkey で TaskTray にアイコンが入れられないって？

![tray.png](https://qiita-image-store.s3.amazonaws.com/0/12977/7aa20d21-711b-8160-e616-c6bee05eb8f2.png)

これについては、また今度！
【備忘録】Vimの基本的な使い方

## Vimのモード

■ Normalモード(ノーマルモード) Vim固有の操作を実行するモード。カーソル移動などの基本操作が行える。  
■Insertモード(挿入モード) 普通のエディタのように、テキスト入力が行える。  
■ Commandモード(コマンドモード) :(コロン)から始まるコマンドを実行するモード。保存、終了、置換などのコマンドを実行できる。  
■ Visualモード(ビジュアルモード)「選択モード」。選択範囲に対して操作を行うコマンドを実行できる。選択範囲のコピーなど。


## 起動と終了

ターミナルで以下のコマンドを実行すると起動する。

```sh
$ vim
```

ファイルを指定して起動

```sh
$ vim hoge.txt
```

Vim 起動後にファイルを開く

```sh
# カレントディレクトリのファイルを開く
:e hoge.txt

# ファイルパスを指定して開く
:e ../huga.txt
```

終了するには「:」を入力してコマンドモードに切り替えてから「q」を入力してEnterキーを押下する。

コマンド入力をキャンセルして終了したい場合は、ESCキーを押下したあとに「:q」を入力してEnterキーを押下する。

## 入力

Vimの起動直後はノーマルモードから始まる。
テキスト入力を行うためにはインサートモードに遷移する必要がある。
インサートモードへの遷移の方法は「i」または「a」、「o」で行える。

i、a、oはそれぞれ以下の通り違いがある。

|   |                                         |
|---|---                                      |
|i  |カーソルの位置から入力を開始する。             |
|a  |カーソルの右隣から入力を開始する。             |
|o  |カーソル行の下に新しい行を挿入して入力を開始する。|

## 保存

入力した値の保存はコマンドモードで行う。
入力モードからESCキーを押下してコマンドモードに遷移してから、
「:w」を入力してEnterキーを押下すると保存が完了する。


## ファイルの新規作成

enewコマンドにより新しいバッファが作成される。

```sh
:enew
```

新しいバッファはwコマンドで名前をつけて保存できる。

```sh
:w fuga.txt
```

## 操作の巻き戻し

ノーマルモード時に「u」を押すことで操作を元に戻すことができる。また、CTR キーと「r」を押下することで元に戻した直前の操作をやり直すことができる。
Macで矢印「↑」を「うえ」とかで変換している人へ。←↓↑→

日本語入力で以下を打つとそれぞれこうなる！！！
zh > ←
zj > ↓
zk > ↑
zl > →


打ち間違えてたまたま見つけてすごくビビりました。。。。


##バズったので、初めて作ったサービス載っけておきます！

「小説家になろう」の情報交換サイトを作ってます。
好きな小説をNAVERまとめみたいにまとめられるサイトを目指しています。
[なろう廃人のすすめ](https://narou-osusume.com/osusumes/2)
rails5, herokuにヘッダー画像をつけるまでの具体的な6工程(iPhone)

### 所要時間1時間弱

## 最終的に採用したヘッダー画像(スマホ)
![header.png](https://qiita-image-store.s3.amazonaws.com/0/145707/b521e61b-07df-8bdf-1d5e-b95751354ef1.png)

## スマホ上での見え方
<img width="375" alt="IMG_0518.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/145707/52093d87-30ee-79f1-a571-8e156b663814.jpeg">

# 以下、手順説明

## 1, canvaでヘッダー画像を複数作る [canva](https://www.canva.com/)

めっちゃ簡単に１０分ほどで作れます。

作った画像たち(3枚)
![3.png](https://qiita-image-store.s3.amazonaws.com/0/145707/8f86bf03-e66d-44a6-8f36-cdb9bf384c39.png)
![2.png](https://qiita-image-store.s3.amazonaws.com/0/145707/9ad22a75-868c-7b8e-1fd6-e4251f32d1b8.png)
![1.png](https://qiita-image-store.s3.amazonaws.com/0/145707/0997ea27-4249-d9ac-e2f9-b6c19c61b9cb.png)

## 2, Macのプレビューで切り取って画像作成

・画像をプレビューで開く
・なんとなく、横長だけど長過ぎないくらいに切り取る
・サイズ切り取り＞横幅を750pxに切り取り

iPhoneでは横750pxにすればちょうどよくなります。
(レスポンシブはまだ対応していないです。)


## 3, pngの圧縮をかける

以下サイトにてpngを圧縮。
300kb > 100kbと1/3くらいになりました。
https://tinypng.com/

## 4, railsのpublicフォルダに画像ファイルを置く

置く場所は以下。
/public/assets/images/header.png

## 5, link_toとimage_tagを組み合わせて表示

ヘッダー画像なので、リンクとなるようにlink_toを合わせました。
iphoneの横幅に合わせてwidthを375に設定します。

```haml:show.html.haml
= link_to image_tag("/assets/images/header.png", width: '375', alt: "なろう廃人のすすめ"), topics_path
```

リンクにしない場合

```haml:index.html.haml
= image_tag("/assets/images/header.png", width: '375', alt: "なろう廃人のすすめ")
```

## 6, ローカルでiPhoneの実機を用いて確認、どのヘッダーにするか決定

iPhoneの実機で確認しながら、どのヘッダーにするか決定。

[railsのローカル開発中にスマホで確認する方法（Mac限定）（テザリングでもOK）](https://qiita.com/Kohei_Kishimoto0214/items/c49f3b7fe6580016df4d)


#今後の課題
スマホしかちゃんとしたサイズにしていないので、
ディスプレイサイズで分けるとかで
2種類画像を用意する必要があるかなぁ。。
[Laravel] バリデーションデータに前処理したい

# [Laravel] バリデーションデータに前処理したい

## 当てはまるケース

- フォーム入力データとデータベース保存データの形式が違う．例えば…
  - 全角・半角変換
  - ~~先頭・末尾の空白を取り除く~~
  - ユーザーには090で始まる形式の携帯電話番号を入力してもらっているが，システム的には E164 で扱いたい

バリデーターに流すデータに前処理を施すことで，unique チェックも前処理後のデータでできるようになります．

※ [Laravel にはデフォルトで文字列をトリミングするミドルウェアが含まれている](https://laravel.com/docs/5.6/requests#input-trimming-and-normalization)ので，前処理にトリミングを行う必要はありません．

## Form Request を使う場合

`FormRequest` クラス内部において，

```php:Illuminate\Foundation\Http\FormRequest.php:81
<?php

    /**
     * Create the default validator instance.
     *
     * @param  \Illuminate\Contracts\Validation\Factory  $factory
     * @return \Illuminate\Contracts\Validation\Validator
     */
    protected function createDefaultValidator(ValidationFactory $factory)
    {
        return $factory->make(
            $this->validationData(), $this->container->call([$this, 'rules']),
            $this->messages(), $this->attributes()
        );
    }

    /**
     * Get data to be validated from the request.
     *
     * @return array
     */
    protected function validationData()
    {
        return $this->all();
    }
```

のように，`validationData()` メソッドでバリデーション用データを取得し，バリデーターに流しています．

デフォルトでは `all()` メソッドでフォームの全項目を配列で返しているので，`validationData()` メソッドを上書きし，この配列に前処理すれば良いことがわかります．

```php:CreateUserRequest.php
<?php

class CreateUserRequest extends FormRequest
{
    /**
     * Get data to be validated from the request.
     *
     * @return array
     */
    protected function validationData()
    {
        $data = $this->all();
        // 前処理：例えば全角英数字を半角に変換する
        if (isset($data['name']))
            $data['name'] = mb_convert_kana($data['name'], 'a');
        return $data;
    }
    
}
```

## FormRequest を使わない場合

`Validator` ファサードを使うのが無難でしょう．

[Laravel 本家の例](https://laravel.com/docs/5.6/validation#manually-creating-validators)をもとに書いてみます．

```php:PostController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Support\Facades\Validator;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;

class PostController extends Controller
{
    /**
     * Store a new blog post.
     *
     * @param  Request  $request
     * @return Response
     */
    public function store(Request $request)
    {
        $data = $request->all();
        // ここで前処理
        if (isset($data['name']))
            $data['name'] = mb_convert_kana($data['name'], 'a');
      
        $validator = Validator::make($data, [
            'name' => 'required|string|unique:users',
        ]);
        $validator->validate();
      
        // バリデーション通過後の処理…
    }
}
```

## 注意：バリデーション後のデータ

前処理はバリデーション用のデータにのみ適用されるので，通過後の `$request` に含まれる入力データは前処理がかかっていません．

データを利用する際にはもう一度前処理を実行する必要があります．

## 参考
- [Laravel 5 Form Requests have a sanitize method ?](https://laracasts.com/discuss/channels/general-discussion/laravel-5-requests-have-a-sanitize-method)
- [Easy Laravel 5 Book](https://www.easylaravelbook.com/blog/sanitizing-input-using-laravel-5-form-requests/)
- [洗練された『Laravel』のバリデーションについてご紹介します | 東京上野のWeb制作会社LIG](https://liginc.co.jp/359544)
【Tips】Rubyソースコード内の全角スペースについて

# 概要
 Rubyは変数名・メソッド名・クラス名などに全角文字を利用することができる。それは全角スペース（全角空白）も例外ではない。そのため、コード内の全角スペースは変数名やメソッド名とみなされた上でのエラーメッセージが表示されるので注意する必要がある。

# 確認
　全角スペースを変数名やメソッド名、クラス名の一部として利用してみる。半角スペースと間違えて全角スペースを挿入してしまった際の挙動に関しては[こちらの記事](http://memorandums.hatenablog.com/entry/2018/05/01/201908)を参照のこと。

## 環境
ruby 2.4.1p111 (2017-03-22 revision 58053) [x86_64-linux]
WSL (Windows Subsystem for Linux) 上での実行。

## コードと実行結果
### 変数
```ruby:space1.rb
　　 = "全角スペース" # 変数「　　」（全角スペース2個）
　　のんぼ　　 = 568 # 変数「　　のんぼ　　」

puts 　　
puts 　　のんぼ　　 * 12 == 12*568
```
```bash:実行結果
全角スペース
true
```

### メソッド
```ruby:space2.rb
# メソッド
def 　　　 # メソッド「　　　」（全角スペース3個）
    puts "第一関数"
end
def 　(input) # メソッド「　」（全角スペース1個）
    puts "第二関数：#{input}"
end

　　　
　("文字列")
```
```bash:実行結果
第一関数
第二関数：文字列
```
### クラス
　全角スペースは大文字アルファベットではないのでクラスの名前に全角スペースを用いる場合は冒頭に大文字アルファベットを付加する必要がある。

```ruby:space3.rb
class C　 # クラス「C　」
    def demand(　　　　) # 引数「　　　　」（全角スペース4個）
        puts "存在 is #{　　　　}"
    end
end

space = C　.new
space.demand("ここにいるよ")
```
```bash:実行結果
存在 is ここにいるよ
```

# 考察
　可読性が著しく低下するため全角スペースによる変数名やメソッド名などを実用上使用することはほぼないといえる。ただし、全角スペースがこれらの命名に使用可能であるということを理解しないとエラーメッセージを読み解くことが難しい場合があるため仕様として知っておくと良い。

# 参考文献
- [そう言えばRubyって変数名とかに日本語使えるんだよね](https://qiita.com/masuidrive/items/8973161dced6dfdba460)
- [rubyのコード中に全角空白が入った場合の挙動について](http://memorandums.hatenablog.com/entry/2018/05/01/201908)
rails5でlink_toとimage_tagを一緒に使う

link_toのリンクする文字列を指定するところにimage_tagを入れると使える。

以下にpng画像を配置して、
/public/assets/images/header.png

このようなコードになる。

```ruby:show.html.haml

= link_to image_tag("/assets/images/header.png", width: '375', alt: "サンプル画像"), topics_path

```


## スマホとPC、それぞれのヘッダー画像を用意して出し分けとかしないとダメなのかな。
ディスプレイサイズで見分ける感じ？
S3からGlacierに移行したデータを復元させる画面の日本語が間違っている気がする


S3にアップロードしたファイルにライフサイクルを設定してGlacierに移行させたあとS3に復元する画面で、元の英語は

```
Specify the number of days that your archived data will be accessible
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/12406/57b5b265-d069-a30a-91a3-1ac87785aa8c.png)

となっており、日本語に切り替えると

```
アーカイブされたデータがアクセス可能になるまでの日数を指定します
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/12406/5b9b7a49-2e37-4206-479c-5172652797a0.png)

となるのだが、
```
アーカイブされたデータがアクセス可能な日数を指定します
```
が正しいと思う。

※AWS関係の人に届きますように！
サーバ上にある複数のCSVファイルを読み込み、Mapに格納する

#概要
この記事では、サーバ上に置いてあるCSVファイルを、javascriptの変数に格納するソースコードを紹介しています。何列あってもOKです。

#CSVファイルの形式
CSVファイルは、タブ区切りで全ての要素が「"」で囲われています。加えて、1行目はタイトル行とします。

```csv
"title"	"text"
"タイトル1"	"テキスト1"
"タイトル2"	"テキスト2"
"タイトル3"	"テキスト3"
```

このファイルは、htmlと同じ階層に保存されているとします。

#ソースコード
```js
let map = new Map();
const files = ["data1.csv", "data2.csv"];
```

```js
onload = function() {
  Promise.all(
    files.map((path, index) => {return loadFile(path, index)})
  ).then(values => {
    values.forEach(result => {
      const no = result[1].toString();
      const csv = result[0];
      map.set(no, {data: getCsvToArray(csv)});
    });

  }).catch(reason => {
    console.error(reason);
  });
}
```

```js
function loadFile(path, no) {
  return new Promise((resolve, reject) => {
    const request = new XMLHttpRequest();
    request.open("POST", path, true);

    request.onload = (event) => {
      if (request.status !== 200) reject(request.statusText);
        resolve([request.responseText, no]);
      }
      request.onerror = (event) => {
        reject(request.statusText);
      }
    request.send();
  });
}
```

```js
function getCsvToArray(csv) {
  let keys;
  return csv.split("\n").filter(line => {return line.length !== 0}).reduce((array, line, index) => {
    let column = line.split("\t").map(element => {
      return element.slice(1).slice(0, -1).replace(/""/, '"');
    });

    if(index === 0) {
      keys = column;

    } else {
      let container = keys.reduce((object, key, index) => {
        object[key] = column[index];
        return object;
      }, new Object());
      array.push(container);
    }
    return array;

  }, new Array());
}
```
Azure Machine Learningによる非接触体温推定

![I-03158.jpg](https://qiita-image-store.s3.amazonaws.com/0/177932/3f4d006f-e057-c95c-186b-05709d405de5.jpeg)![センサ.JPG](https://qiita-image-store.s3.amazonaws.com/0/177932/9a877aba-0343-29a5-03a1-9149743e848e.jpeg)

#概要
　これから食中毒が起こりやすい季節となりますが、食品業界にとって、従業員が感染症、特にO157のような食中毒を起こす感染症にかかっていないことをモニタする必要性が高まってきています。
一度事故を起こすと経営に致命的なダメージを与えるため、神経質になっている企業もあるかと思います。食品衛生の国際基準でHACCPがあり、政府も政策的に支援を行っている状況があります。HCAPP対応にあたる高度化整備基盤では、厚生労働省での[高度化整備基盤確認項目](http://www.maff.go.jp/j/shokusan/sanki/haccp/h_housin/other/pdf/keikakusakuseitebiki_betu1.pdf)では多くの項目について定められています。
実際対応を考えていくときに、継続的にモニタを行わないといけなといけないのですが、従業員側からみると手間暇がかかる内容だと、きちんと対応できずに、リスクを高める結果となります。
　この記事では、体温をモニタする目的の
仕組みになります。非接触なので、機会学習で、赤外線アレイセンサからのデータを学習して予測を行います。


#センサーとの接続
[オムロン製のD6T-44L-06センサー](https://www.switch-science.com/catalog/1297/)/[Sharp製GP2Y0A0YK](http://akizukidenshi.com/catalog/g/gI-03158/)の接続は[こちらの記事](https://analyticsai.wordpress.com/2018/06/12/%e8%b5%a4%e5%a4%96%e7%b7%9a%e6%b8%a9%e5%ba%a6%e3%82%a2%e3%83%ac%e3%82%a4%e3%82%bb%e3%83%b3%e3%82%b5%e3%83%bc%e3%81%a7%e3%81%aeiot/)を参照ください
センサー配置のイメージですが、下記の図のようになります。
![data.JPG](https://qiita-image-store.s3.amazonaws.com/0/177932/15e80ac9-531f-a564-b3ec-d4b16a111e32.jpeg)
#AzureMLでモデル作成
AzureMLの基本的な使い方は[こちらを参考](https://docs.microsoft.com/ja-jp/azure/machine-learning/studio/create-experiment)にしてください。作成したモデルは下記のようになります。回帰分析ですので、数値を予測します。
![AzureML3.JPG](https://qiita-image-store.s3.amazonaws.com/0/177932/334d460e-8b47-83b5-a7e3-b5ca86617611.jpeg)
学習に使用したデータは[こちら](https://github.com/yasukit1414/MLRegression/)になります。
#学習と評価
特に、難しくなく、一定の精度で学習を行うことができました。

作成できれば、Webサービスとして発行します。
![AzureML1.JPG](https://qiita-image-store.s3.amazonaws.com/0/177932/3ae03a3d-5254-99c0-a918-4381ec6e0fd5.jpeg)
テストはExcelで行うのが便利で、上記のリンクから、Excelのシートをダウンロードします。
![AzureML2.JPG](https://qiita-image-store.s3.amazonaws.com/0/177932/94c482cf-c48c-c2d5-ce6c-455fadc5ebe5.jpeg)
こちらで、テストを行うことができます。
結果としては、室内で、ある程度空調がきいて気温が一定な環境なので、精度よく予測することができました。
Sublime Text 3のインデント設定を変更する

Sublime Text 3でインデント設定を変更する方法をメモしておきます。

# インデント設定をスペース2つ分に変更する
メニューから [Sublime Text] > [Preferences] > [Settings] をクリック。
![スクリーンショット 2018-06-12 16.31.34.png](https://qiita-image-store.s3.amazonaws.com/0/6380/f4ada9a6-2983-2572-94d8-137138c4e944.png)

設定ファイルに以下の2行を追加します。

```
"tab_size": 2,
"translate_tabs_to_spaces": true,
```
![スクリーンショット 2018-06-12 16.32.56.png](https://qiita-image-store.s3.amazonaws.com/0/6380/3e75836e-e876-e496-c74d-5c6380132069.png)

`tab_size`はインデントの幅設定。
`translate_tabs_to_spaces`を`true`にするとインデントがスペースに、`false`だとタブになります。

# 開いているファイルのインデント設定を変更する

インデント設定はSublime Textのウインドウ右下にも表示されます。
![スクリーンショット_2018-06-12_16_36_28.jpg](https://qiita-image-store.s3.amazonaws.com/0/6380/8a8ddaa0-3c31-b988-2fe4-d1c23fd99c93.jpeg)

こちらクリックすると、開いているファイルに対してインデント設定を適用することができます。
![スクリーンショット 2018-06-12 16.37.03.png](https://qiita-image-store.s3.amazonaws.com/0/6380/f2cb0ece-9848-3fef-2ec6-a1a7ebc7c711.png)
「Convert〜」でスペースorタブへの一括変換も可能です。
Heroku:Buildpackエラーでハマった

#はじめに
基本的すぎてどこにも書いてなかったこと
同じ初心者に光あらんことを･･･(自戒も込めて)
#環境
windows 10
ruby 2.4.4
rails 5.1.6
#ハマったこと
Herokuへのデプロイをスルーしていたので、tutorialの7章が終わったあたりでデプロイしてみようと思ったらハマった。
##エラー内容
```console
C:\Users\root\Desktop\rails\tutorial>git push heroku master
Counting objects: 577, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (553/553), done.
Writing objects: 100% (577/577), 80.14 KiB | 1.05 MiB/s, done.
Total 577 (delta 297), reused 0 (delta 0)
remote: Compressing source files... done.
remote: Building source:
remote:
remote:  !     No default language could be detected for this app.
remote:                         HINT: This occurs when Heroku cannot detect the buildpack to use for this application automatically.
remote:                         See https://devcenter.heroku.com/articles/buildpacks
remote:
remote:  !     Push failed
remote: Verifying deploy...
remote:
remote: !       Push rejected to hoge-app.
remote:
To https://git.heroku.com/hoge-app.git
 ! [remote rejected] master -> master (pre-receive hook declined)
error: failed to push some refs to 'https://git.heroku.com/hoge-app.git'
```
##やってみたこと
エラーメッセージに従いRubyのビルドパックを足してみる

```console
heroku buildpacks:set https://github.com/heroku/heroku-buildpack-ruby.git
```

結果

```console
remote: Compressing source files... done.
remote: Building source:
remote:
remote: -----> App not compatible with buildpack: https://github.com/heroku/heroku-buildpack-multi.git
remote:        More info: https://devcenter.heroku.com/articles/buildpacks#detection-failure
remote:
remote:  !     Push failed
```

どうやら言語設定が合っていないらしい
Rubyですが!?

##原因判明
答えはここにありました。
https://devcenter.heroku.com/articles/buildpacks#detection-failure
要するに「Rubyならアプリケーションの"ルートフォルダ"にGemfileが存在しないと正しく認識されないよ」ってことらしい

##どうやら
勉強メモも一緒にGit管理しており、アプリケーションのルートフォルダの1つ上をリポジトリに登録していたため、RubyのビルドパックがGemfileを見つけられずエラーを出していた。
![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/260430/5db90640-6705-cb02-edec-d7de5c32e26d.png)
これが期待されるGitの状態。