OmniAICreator/Qiita-1.07M huggingface dataset:
eclipseにlombokを入れるのに手間取った(Mac)

Springでのプロジェクトにlombokを取り入れるのに手間取りました。
次回のセッティングがスムーズになるように情報をまとめておく。

## 依存性の注入〜〜〜
mvnrepository
http://mvnrepository.com/artifact/org.projectlombok/lombok
Mavenプロジェクトならpom.xmlに、Gradleプロジェクトならbuild.gradleに追加する。

## lombokをダウンロード
https://projectlombok.org/download からlombok.jarをダウンロード
lombok.jarを開き（ダブルクリック等）、http://web-dev.hatenablog.com/entry/eclipse/lombok にあるようにインストーラを操作

## 注意点
ダウンロードしたlombok.jarとMVNRepositoryで指定したバージョンは合わせた方が良いと思われる。

## eclipse再起動！
インストーラの操作をするとインストーラで指定したeclipseのディレクトリ階層にlombok.jarが配置される。
同じ階層にeclipse.iniというファイルがあり、中を覗いてみると下のような記述が増えている。（ディレクトリ階層は環境に依ります）
```-javaagent:/Applications/Eclipse.app/Contents/Eclipse/lombok.jar
```
eclipseを起動する際の設定ファイルなので、ここでlombok.jarが読み込まれる。




以上で動くようになるはずです。

## 補完機能をいいものに
① eclipse code recommendersをeclipseマーケットプレイスでインストール
② 設定を変えよう　http://ser1zw.hatenablog.com/entry/20110130/1296393620

## lombokの補完候補の表示位置がおかしい
以下のように、code recommendersだけが動くように設定すると自分はいい感じでした。
[スクリーンショット 2018-02-28 23.08.29.png](https://qiita-image-store.s3.amazonaws.com/0/92926/13d5b765-af16-28b6-ef8c-9f13f570172e.png)

参考記事：
http://www.eclipse.org/recommenders/manual/#completions-preferences
https://matome.naver.jp/odai/2135281431483912301


### Eclipse に lombok 1.14.4 を導入したらコンテンツアシストが超絶遅くなったという記事
http://blog.rakugakibox.net/entry/2014/07/20/eclipse_lombok_slow!
VimでTypeScriptのsyntax highlight 〜Vundleのインストールから〜

こんばんは。フリーターです。

大学時代から研究や趣味でプログラミングする際にはvimを使っている僕ですが

とうとう生のvimではなくプラグインをインストールすることになったので、自分用のメモを兼ねてやり方を残しておきます。

どうせプラグイン入れるなら、いろいろ入れてみるのも楽しそうですけどね。

今回はプラグインを導入して、TypeScriptのsyntax highlightを行います。

#Vundleのインストール

Vundleというのは、vimのプラグインを管理するツールです。

同じ働きをするものは他に

- VimPlug
- NeoBundle
- Pathogen

あたりがあるみたいです。


では、ここを参考に入れましょう。
https://github.com/VundleVim/Vundle.vim

下記を実行します。

```
git clone https://github.com/VundleVim/Vundle.vim.git ~/.vim/bundle/Vundle.vim
```

一瞬、カレントディレクトリはどこにいればいいんだ、とか思ったけど、インストール先としてチルダから始まる絶対パスを指定してるから別に現在地はどこでもいいですね。


# .vimrcの場所を確認

なにげに、こういうしょうもない所で結構困るんですよね。

この後、vimの設定ファイルである.vimrcに記述をしますが、場所がわからなきゃどうしようもない。

僕の場合は、普通にホームディレクトリ

````
cd ~/
````

にありました。

# .vimrcに記述

一応、

```
cp .vimrc .vimrc1
```

としてバックアップしてから
次のコードを.vimrcの最上部に追加します。

```:.vimrc
set nocompatible              " be iMproved, required
filetype off                  " required

" set the runtime path to include Vundle and initialize
set rtp+=~/.vim/bundle/Vundle.vim
call vundle#begin()
" alternatively, pass a path where Vundle should install plugins
"call vundle#begin('~/some/path/here')

" let Vundle manage Vundle, required
Plugin 'VundleVim/Vundle.vim'

Plugin 'leafgarland/typescript-vim'

" All of your Plugins must be added before the following line
call vundle#end()            " required
filetype plugin indent on    " required
```

既にTypeScript用の記述も入ってます。

```
Plugin 'leafgarland/typescript-vim'
```
の行がそうです。
https://github.com/leafgarland/typescript-vim/wiki/Installation
を参考にやってます。

#プラグインをインストール

vimを起動して次を実行します

```
:source ~/.vimrc
:PluginInstall
```

一行目で、さっきいろいろ書いた.vimrcをロードして、二行目でプラグインをインストールしてます。


以上！
Jestによるテスト

#コンポーネントのテスト

```react
import React from 'react';
import { shallow } from 'enzyme';
import HogeButton from './HogeButton';

describe('HogeButton', () => {
  it('onClickEvent Test', () => {
    const testMock = jest.fn();

    const wrapper = shallow(<HogeButton/>);

    wrapper.setProps({ actions: {actionHoge : testMock }})

    wrapper.find('Button').simulate('click');

    expect(testMock).toHaveBeenCalled();
  });
});
```
上記は、onClickイベントの呼び出しの確認用のコード

テストするコンポーネントのインポートを行ない
shallowでレンダリングを行なう

onClickイベントで呼び出される関数を用意し、
simulateで実行

最後にtoHaveBeenCalledで呼び出されていることを確認する。

#ファンクションのテスト
```react
import React from 'react';
import Fuga from './Fuga';

describe('Fuga', () => {
  it('getFuga Test', () => {

    const testFunc = Fuga.getFuga ();

    expect(testFunc).toEqual('FugaFuga');
  });
});
```
テストするクラスのインポートを行ない。
testFuncにテストするファンクションを格納

toEqualでテスト結果を確認
AWS Lambdaにクエリ文字列(get値)を引数で渡すトリガを設定する

# やりたいこと

クエリ文字列(get値)付きのURLをキーに`Lambda`を実行させたい。  
そして、必須のクエリ文字列がない場合はエラーで弾きたい。

# 先にまとめ

1. `Lambda`のトリガーに`API Gateway`を設定
2. `API Gateway`で`Get`メソッドを作成
3. Getメソッドの`メソッドリクエスト`を開く
 - `リクエストの検証` -> **クエリ文字列パラメータおよびヘッダーの検証**に変更
 - `URL クエリ文字列パラメータ ` にクエリ文字列を追加で、必要なgetのkeyを追加(必要に応じて、必須にチェックを付ける)
4. Getメソッドの`統合リクエスト`を開き、`本文マッピングテンプレート`を開く
 - `リクエスト本文のパススルー`-> **`テンプレートが定義されていない場合 (推奨)`**を選択
 - `application/json`を追加する
 
記載は、以下の形(`foo`を任意で書き換える)

```json:application/json
{
  "foo": "$input.params('foo')"
}
```

**アクション**で**APIデプロイ**を実行すると反映される。

# 実装の流れ

[Amazon API GatewayでAWS Lambda関数にクエリ文字列をパラメータとして渡す - Qiita](https://qiita.com/yuyakato/items/89fcef9746afbf48977a)を参考に実装する

## 1. Lambda関数を準備する

確認用のfuntionを設定する

```js:lambda関数コード(nodeJs)
exports.handler = function(event, context) {
    console.log(JSON.stringify({event: event, context: context}, null, 2));
    context.succeed({event: event});
};
```

## 2.URLを処理するAPI Gatewayのメソッドを準備する

Designerから、`API Gateway`を選択し、`トリガーの設定`

* API名 -> APIの設定名
* デプロイされるステージ -> 識別としてURLの値に使われる値
(セキュリティは今回はオープンを選択)

設定が終わったら、ページ上部の`保存`でLambda全体の設定を保存する

## 3.API Gatewayの詳細設定

### メソッドを作成

API Gatewayで、作成したAPI名のメッソドをのリソースを開く

1. リソースで`ANYメソッド`がある場合、今回は必須のGet値がない場合は弾くため`アクション`から`メソッド`を削除する。
![any削除.PNG](https://qiita-image-store.s3.amazonaws.com/0/90529/835ea469-ccf1-98a7-619d-8c5463031bb8.png)

2. `アクション`で`メソッドを作成`で`Get`を作成
 - 総合タイプは`Lambda関数`を選択する
 
### メソッドリクエストで、必須の値をURL クエリ文字列を指定

* リクエストの検証で、**クエリ文字列パラメータおよびヘッダーの検証**を選択
* URL クエリ文字列パラメータ に**追加したいパラメータ文字**を入力する(必須を選択することで、パラメータが存在しない場合はエラーにできる)

![メソッドクエスト作成.PNG](https://qiita-image-store.s3.amazonaws.com/0/90529/468d443e-6524-5ca1-a369-7a6c819a3759.png)


### 統合リクエストで、パラメータをマッピングする

`本文マッピングテンプレート `を開き、

* `リクエスト本文のパススルー`で**テンプレートが定義されていない場合(推奨)**を選択
* `マッピングテンプレートの追加`を選択
 - Content-Typeに**application/json**を入力
 - テンプレートを以下のように入力し、「保存」する

```json:application/json*
{
  "Lambdaで受け取る値": "$input.params('URLパラメータ')",
  "foo": "$input.params('hoge')"
}
```

![統合リクエスト作成.PNG](https://qiita-image-store.s3.amazonaws.com/0/90529/7bfa05bc-6130-7b0d-47fb-6f9fc8441715.png)


### テストで文字列引数を流してみる

![テスト実行前.PNG](https://qiita-image-store.s3.amazonaws.com/0/90529/0e595ade-da43-cf3a-d37d-b590ef6c2782.png)


```json:テスト例
{
  "event": {
    "foo": "fuga"
  }
}
```

### `アクション`から**APIのデプロイ**を実行することで公開される


以上です。
お疲れ様でした!!
いつからIAMビジュアルエディタが正しいと錯覚していた？

#IAMビジュアルエディタの警告に困惑したお話

※投稿主は初投稿なので不手際ございましたら申し訳ございません。

最近IAMポリシーをjsonではなくマネジメントコンソールから簡単かつわかりやすく作成でき、さらにはポリシーの内容を自動レビューしてくれる機能が追加されたのは皆さんもうご存知でしょうか。

最近CLBからALBに切り替えたついでにIAMポリシーも見直していたところビジュアルエディタのポリシーレビュー画面で警告が表示されていくらポリシーの内容を修正しても改善されなく困惑していました。。。

今回はビジュアルエディタのポリシーレビュー機能について投稿してみます。

##結論
いきなり結論ですが**ビジュアルエディタの不具合**でした。

ELBには2018/02/28現在では三種類あり、CLBとALB/NLBを操作するAPIが異なります。

>[AWSCLIリファレンス]
https://docs.aws.amazon.com/cli/latest/reference/
 CLB → ELB
 ALB/NLB → ELBv2

このようにAWSでは区別されています。

どうやらレビュー機能では2つのうち個別で使用するアクションを指定すると
ELB(CLB)固有のアクションはELBv2としても認識されて、
ELBv2(ALB/NLB)固有のアクションはELBとしても認識され警告が表示される。
という現象が発生しています。

ちょっと何言ってんだこいつ？と思われそうなので再現してみます。

##やってみた
jsonの内容は以下の通りです。
ELBv2固有のアクションのみを記載したIAMポリシーを作成します。

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "elasticloadbalancing:RegisterTargets",
                "elasticloadbalancing:DeregisterTargets"
            ],
            "Resource": "*"
        }
    ]
}
```
内容は

- ターゲットグループへターゲット(EC2インスタンス等)を追加する
- ターゲットグループからターゲットを外す

2つのアクションを許可するです。

ではビジュアルエディタを見てみましょう。

![1.JPG](https://qiita-image-store.s3.amazonaws.com/0/240644/f0084b58-3e7b-c019-a8a8-0d78d8404bf9.jpeg)

**IAM によって 1 つ以上のアクションが認識されません。このアクション名にタイプミスがあるか、プレビューされたサービスまたはカスタムサービスの一部である可能性があります。**

いやいやビジュアルエディタの画面からポチポチ作ったのにタイプミスするかいなww。
警告が出ているのはELBv2ではなくELBの箇所で出ているのがわかりますでしょうか。
ただしELBv2の箇所でもきちんとポリシーの概要は表示されています。

今度はELB(CLB)固有のアクションのみ記載したIAMポリシーです。

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "elasticloadbalancing:RegisterInstancesWithLoadBalancer",
                "elasticloadbalancing:DeregisterInstancesFromLoadBalancer"
            ],
            "Resource": "*"
        }
    ]
}
```
内容は

- CLBへEC2インスタンスを登録する
- CLBからEC2インスタンスを登録解除する

2つのアクションを許可するです。

ではビジュアルエディタを見てみましょう。

![2.JPG](https://qiita-image-store.s3.amazonaws.com/0/240644/b6369fbf-e709-3d10-045c-4dc3889149d4.jpeg)

今度はELBではなくELBv2で出ていますね！


さらに今度はELBで共通のアクションを織り交ぜてみます。

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "elasticloadbalancing:DescribeLoadBalancers",
                "elasticloadbalancing:RegisterTargets",
                "elasticloadbalancing:DeregisterTargets"
            ],
            "Resource": "*"
        }
    ]
}
```

ELBv2固有のアクションに加えて2つ共通のDescribeLoadBalancersを加えました。
このアクションはELBのリスト・読み取りを許可します。

ではビジュアルエディタへ

![3.JPG](https://qiita-image-store.s3.amazonaws.com/0/240644/c8566724-9b11-6408-59be-6b00124f5c85.jpeg)

ELBでRegisterTargetsとDeregisterTargetsに警告が表示されていますがDescribeLoadBalancersには特に警告は出ていません。

##まとめ
- ELB共通のアクションは問題ない
- ELBとELBv2固有のアクションは別のタブで警告が表示される

ちなみにAWSサポートにも問い合わせてみて不具合ですとの回答いただきました。
修正はいずれ発生すると思いますが、普段使用していて特に問題ないです。

ただ、警告表示されるとなんか構えてしまいます（笑）

いかがでしたでしょうか。すごいどうでもいい記事ですが上司に
「エラーでてるぞ!!氏ね!!!!!」と言われてもしビジュアルエディタ画面を根拠に出されたらこんな不具合もあるってことを頭の片隅においておけば自分のせいにされずに済むかもしれませんw。

以上です。
error trying to exec 'cc1': execvp: No such file or directory

# はじめに
以下のような現象に遭遇した。

```
$ aarch64-linux-musl-gcc test.c
aarch64-linux-musl-gcc: error trying to exec 'cc1': execvp: No such file or directory
```

`which aarch64-linux-musl-gcc`しても反応なし。

# 解決方法

`echo $PATH`するとこうなっていた

```
$ echo $PATH
~/...:~/...:/usr/bin....
```

この`~`を具体的なパス(`/home/lesmi`など)にすると治った。
これは難しい。

# 結論
`~`はコマンドだけに使え
RubyでYAMLをインライン形式で書き出す方法


YAMLはコンピュータで読み込め人にも優しい形式ですが、最下層だけでもインライン形式で書き出してくれれば、さらに読みやすくなるように思いますので、その方法を紹介します。

##その1
Psychのソースコードを読む限り対象クラスにencode_withメソッドを追加することでYAMLの出力を変えることができます。それを利用した方法です。

###Hashクラスの場合
Hashクラスの場合をはじめに説明します。
基本的には、対象とするクラスにencode_withメソッドを追加するだけです。
最下位の要素だけをインライン形式にしたいので、全ての要素の値がNumericかStringである場合だけを対象にしています。

```Ruby:yaml1.rb
require 'yaml'

class Hash
  def encode_with(coder)
    if self.all?{|k, v| Numeric===v or String===v}
      coder.style = Psych::Nodes::Mapping::FLOW
    end
    coder.tag = nil
    coder.map = self
  end
end

puts [{"a"=>2, "b"=>3}, {"c"=>4}].to_yaml
# 出力結果
# ---
# - {a: 2, b: 3}
# - {c: 4}
```

###Arrayクラスでは
Hashと同じようにしてもインライン形式で出力してくれませんでしたので、ここではemit_coderメソッドをオーバーライドしています。とは言ってもwhen :seqの次の1行を変更しているだけです。
おそらくPsychのバグではないかと思います。

```Ruby:yaml2.rb
require 'yaml'

module Psych
  module Visitors
    class YAMLTree < Psych::Visitors::Visitor
      alias_method :emit_coder_orig, :emit_coder
      def emit_coder c, o
        case c.type
        when :seq
          @emitter.start_sequence nil, c.tag, c.tag.nil?, c.style
          c.seq.each do |thing|
            accept thing
          end
          @emitter.end_sequence
        else
          emit_coder_orig c, o
        end
      end
    end
  end
end

class Array
  def encode_with(coder)
    if self.all?{|c| Numeric===c or String===c}
      coder.style = Psych::Nodes::Mapping::FLOW
    end
    coder.tag = nil
    coder.seq = self
  end
end

puts ({"a"=>[1,2,3], "b"=>[4,5]}).to_yaml
# 出力
# ---
# a: [1, 2, 3]
# b: [4, 5]
```

##その2
(2018.5.19追記)
acceptをオーバーライドして強引?にインライン出力する方法です。
YAMLStyle.flow_style()の中にインライン出力したいオブジェクトを入れることで、そのオブジェクトIDを登録し、YAML展開するときにstyleをFLOWに書き換えています。
こちらの方が出力の自由度は高いです。

```Ruby:yaml3.rb
require "yaml"

class YAMLStyle
  @@flow_style_ids=[]
  def self.flow_style(obj)
     @@flow_style_ids << obj.__id__
     obj
  end
end

module Psych
  module Visitors
    class YAMLTree < Psych::Visitors::Visitor
      alias_method :accept_orig, :accept
      def accept target
        acpt=accept_orig target
        acpt.style=Psych::Nodes::Sequence::FLOW if YAMLStyle.class_variable_get(:@@flow_style_ids).include?(target.__id__)
        acpt
      end
    end
  end
end

puts [YAMLStyle.flow_style({"a"=>2, "b"=>3}), YAMLStyle.flow_style({"c"=>4})].to_yaml
puts ({"a"=>YAMLStyle.flow_style([1,2,3]), "b"=>YAMLStyle.flow_style([4,5])}).to_yaml
# 出力
# ---
# - {a: 2, b: 3}
# - {c: 4}
# ---
# a: [1, 2, 3]
# b: [4, 5]
```

使用したrubyのバージョンは2.5.1p57です。
プロトタイピングで使える広域無線通信モジュール

IoT でエリアを限定せず使えるデバイスを開発する場合に必要となる通信方式・モジュールを探すときのまとめ。

# 条件

- 日本国内で合法的に利用可能
- 日本国内で一般入手可能

# 早わかりのために大雑把に方式比較

| 通信方式 | 通信速度 | 価格 | 消費電力 | エリア | 備考
|:-:|:-:|:-:|:-:|:-:|:-:
| LTE Cat.1 | 速い | プラン・通信量次第 | 多い | 全国 | セルラー
| LTE Cat.M1 (LTE-M, eMTC) | ∨ | プラン・通信量次第 | ∨ | 全国に広がる予定（キャリア対応次第） | セルラー/ライセンスバンドLPWA
| LTE Cat.NB1 (NB-IoT) | ∨ | プラン・通信量次第 | ∨ | 全国に広がる予定（キャリア対応次第） | セルラー/ライセンスバンドLPWA
| SenseWay Mission Connect (LoRaWAN) | ∨ | 安い | 少ない | [2019年3月までに「人口カバー率60％」を目指す] | アンライセンスバンドLPWA(https://ascii.jp/elem/000/001/663/1663697/)
| Sigfox | 遅い | 安い | 少ない | [国内人口カバー率 95% (2019年3月時点)](http://www.kccs.co.jp/sigfox/coverage/) | アンライセンスバンドLPWA

- 3Gは停波が現実的になってきたので除外

# LTE Cat.1

## Wio LTE JP Version

- [SORACOMユーザーコンソールで購入](https://soracom.jp/products/module/wio_lte/)
- [秋月電子通商](http://akizukidenshi.com/catalog/g/gM-12855/)

## 他を探す

- https://www.nttdocomo.co.jp/biz/support/iot/product/
- https://open-dev.kddi.com/information?type=2
- https://www.softbank.jp/biz/mobile/solution/m2m/product/

# LTE Cat.M1 / Cat.NB1

## Wio LTE M1/NB1(BG96)

- [SORACOMユーザーコンソールで購入](https://soracom.jp/products/module/wio_lte_m1_nb1/)

## 他を探す

https://www.gsma.com/iot/mobile-iot-modules/

# LoRaWAN

## LoRaWAN Shield for Arduino

https://store.senseway.net/items/15182297

## 他を探す

- [LoRaWAN 対応製品ガイド](https://www.senseway.net/lorawan-service/item/item-tag/certified/)

# Sigfox

## Sigfox Shield for Arduino (UnaShield V2S)

https://www.marutsu.co.jp/pc/i/952284/

## Sigfox Breakout board BRKWS01 RC3

https://www.switch-science.com/catalog/5373/

## 他を探す

- [IoTネットワーク「Sigfox」対応製品](http://www.kccs.co.jp/sigfox/product/#product-module)
- [Modules | Sigox Partner Network](https://partners.sigfox.com/products/module)
絶対最大量指定子(possessive quantifier)について

Rubyの公式サイトを見ていた際に、
__絶対最大量指定子__(possessive quantifier)について文章だけでは分からなかったのでまとめます。

説明の為、最大量指定子・最小量指定子についても記載します。

# 最大量指定子(greedy quantifier)
> 直前の部分式を何回繰り返すかを指定します。このような繰り返しを 表すメタ文字列を量指定子(quantifier)と呼びます。
> 
> \* 0回以上
> \+ 1回以上
> ? 0回もしくは1回
> {n} ちょうどn回(nは数字)
> {n,} n回以上(nは数字)
> {,m} m回以下(mは数字)
> {n,m} n回以上m回以下(n,mは数字)

> これらは「欲張り(greedy)」にマッチします。 マッチが成功する、最長の文字列にマッチしようとします。 そのため、これらの量指定子は特に最大量指定子(greedy quantifier) と呼ばれます。

※引用：[Ruby 2.5.0 リファレンスマニュアル > 正規表現](https://docs.ruby-lang.org/ja/latest/doc/spec=2fregexp.html)

# 最小量指定子(reluctant quantifier)
> 一方、以下のメタ文字列(普通の繰り返しメタ文字列に ? を付加したもの) はマッチが成功する、最短の文字列にマッチします。そのため、これらの 量指定子は特に最小量指定子(reluctant quantifier)と呼ばれます。
>
> \*? 0回以上
> \+? 1回以上
> ?? 0回もしくは1回
> {n,}? n回以上(nは数字)
> {,m}? m回以下(mは数字)
> {n,m}? n回以上m回以下(n,mは数字)

※引用：[Ruby 2.5.0 リファレンスマニュアル > 正規表現](https://docs.ruby-lang.org/ja/latest/doc/spec=2fregexp.html)

# 絶対最大量指定子(possessive quantifier)
※__強欲な数量子__とも呼ぶそうです。
> 以下のメタ文字列は、最大量指定子のように最長のマッチをしますが、 一度マッチすると、その後マッチに失敗してもバックトラックしません。 つまりマッチ済みの文字列を手放さずにマッチに失敗します。 これらの量指定子は絶対最大量指定子と呼ばれます。
>
> \*+ 0回以上
> \++ 1回以上
> ?+ 0回もしくは1回

※引用：[Ruby 2.5.0 リファレンスマニュアル > 正規表現](https://docs.ruby-lang.org/ja/latest/doc/spec=2fregexp.html)

# 絶対最大量指定子の説明で分からなかった箇所

> 一度マッチすると、その後マッチに失敗してもバックトラックしません。 つまりマッチ済みの文字列を手放さずにマッチに失敗します。

まず、__バックトラック__とはなんぞや？ということでググりました。
調べたところバックトラック自体は正規表現固有の用語ではないんですね。
[Wikipedia > バックトラッキング](https://ja.wikipedia.org/wiki/%E3%83%90%E3%83%83%E3%82%AF%E3%83%88%E3%83%A9%E3%83%83%E3%82%AD%E3%83%B3%E3%82%B0)

正規表現のバックトラックについては、以下のブログの内容が分かりやすかったです。
[Shin x Blog > パフォーマンスを意識して正規表現を書く](http://blog.shin1x1.com/entry/regex-performance)

# 検証
上記を踏まえてRubyの正規表現を試してみました。

## 最大量指定子
```ruby:最大量指定子
 /^\d+\d/.match('123')
=> #<MatchData "123">
```
^\d+ が 123 にマッチ成功。その後 \d がマッチに失敗、バックトラックします。
^\d+ が 12  にマッチ成功。その後 \d が 3 にマッチ成功。
マッチ結果は "123" となります。

## 絶対最大量指定子
```ruby:絶対最大量指定子
 /^\d++\d/.match('123')
=> nil
```
^\d++ が 123 にマッチ。その後 \d がマッチに失敗、バックトラックしません。
マッチ結果は nil となります。

# あとがき
絶対最大量指定子については今のところ使う場面が思い付かないですが、正規表現のパフォーマンスを気にする場面で使うものなのでしょうか？
いずれ正規表現についてもっと詳しく調べてみたいなーと思いました。
フォームを作ってファイルをアップロードする


HTMLでは、下記のようにするらしい

```html
<form method="post" action="" enctype=""></form>
```

で、HTMLって結構便利だと思う。

なぜかといえば、HTML＝WEBブラウザがデフォルトになっていて、
すでに窓が開き、そこにGUIがセットされている。


これ、すごいことだと思う。


もし同じことをＶＢＡでやろうとしたら、
WINDOWSの窓を開いて、そこにフォームオブジェクトを貼り付けて
なんやら処理を書いたりしないといけない。


で、ますますＨＴＭＬ言語というものを覚えたくなった。


しかしなー、
ＨＴＭＬといえば、ホームページを作るだけの言語だと思っていたが、
時代がどんどんすごくなっている感じ


で、これをＰＨＰとかに渡したりするんだと思うが、
まだまだ覚えないといけないことがあって、さあ大変。


さて、他の言語で同じことをやろうとしたら、
どんなに大変なんだろうか？


それぞれどうなるの？

ＰＹＴＨＯＮの場合

ＪＡＶＡの場合

ＲＵＢＹの場合

おまけで

ＢＡＳＨ

ＶＢＳｃｒｉｐｔ



1行ずつを串刺しにして、プログラミング勉強をしていると、
これは、外国語を全部やっている感じになってくる。


あまりにも、これは欲張りすぎではあるまいか

# AI comment

HTMLでファイルをアップロードするには、formタグのenctype属性にmultipart/form-dataを指定します。これにより、ブラウザは、ファイルのアップロードを適切に処理することができます。

他の言語でも、同様にformタグのenctype属性にmultipart/form-dataを指定することで、ファイルをアップロードすることができます。

以下に、各言語の例を示します。

### Python
```Python
import requests

def upload_file(file_path):
    url = "https://example.com/upload"
    files = {"file": open(file_path, "rb")}
    response = requests.post(url, files=files)
    return response.text

if __name__ == "__main__":
    file_path = "test.txt"
    result = upload_file(file_path)
    print(result)
```

# Java
```Java
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

public class UploadFile {

    public static void main(String[] args) throws IOException {
        URL url = new URL("https://example.com/upload");
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("POST");
        connection.setRequestProperty("Content-Type", "multipart/form-data");

        File file = new File("test.txt");
        InputStream inputStream = new FileInputStream(file);
        byte[] bytes = new byte[inputStream.available()];
        inputStream.read(bytes);

        connection.setRequestProperty("Content-Length", String.valueOf(bytes.length));
        connection.setDoOutput(true);

        connection.getOutputStream().write(bytes);

        connection.getResponseCode();
    }
}
```

# Ruby
```Ruby
require "net/http"

def upload_file(file_path)
    url = "https://example.com/upload"
    request = Net::HTTP::Post.new(url)
    request.set_form_data({ "file" => File.open(file_path, "rb") })
    response = Net::HTTP.start(url.host, url.port) {|http| http.request(request) }
    return response.body
end

if __name__ == "__main__":
    file_path = "test.txt"
    result = upload_file(file_path)
    print(result)
```

# Bash
```Bash
curl -F "file=@test.txt" https://example.com/upload
```

# VBScript
```VBScript
Set objHTTP = CreateObject("MSXML2.XMLHTTP")
objHTTP.Open "POST", "https://example.com/upload", False
objHTTP.setRequestHeader "Content-Type", "multipart/form-data"
objHTTP.send("file=@test.txt")

wscript.echo objHTTP.responseText
```


HTMLやPHPのように、フォームタグでファイルのアップロードをサポートしている言語の場合は、比較的簡単にファイルをアップロードすることができます。一方、フォームタグでファイルのアップロードをサポートしていない言語の場合は、HTTPリクエストのヘッダーやボディにファイルを指定するなど、より複雑なコードを書く必要があります。

プログラミング言語を複数学ぶことは、大変なことですが、学習することで、さまざまな開発の選択肢が広がります。欲張りに学習を進めるのも良いでしょう。
[Ethereum] macで俺々トークンを作ってみる（調査）

# 概要
SmartContractで自由にトークン発行できるらしいので、
とりあえずエミュレータ上でデプロイと動作確認までやってみる。

## Tokenの規格
メジャーなのはこんな感じ。ERC20以外はまだドラフトぽい

- ERC20
  - 一番ベーシックかつメジャー。弱点はアドレス間違うと戻せない
- ERC223
  - 間違えた時にリバートできる機能を追加。今後こっちがメジャーになるんじゃないかとの噂
- ERC721
  - メタデータぶっこめる＋委譲できないトークンの作成が可能
  - クリプトキティーはこれ

他165,820などがあるので後日調査

## とりあえずERC20で練習
truffleとzeppelinを入れるといいらしい。

```
npm install -g truffle
mkdir my_erc20_token
cd my_erc20_token
truffle init
-bash: truffle: command not found
```
パス通ってない。ログ見よう

```
#これか
> /Users/hoge/.anyenv/envs/ndenv/versions/v6.11.2/bin/truffle -> /Users/hoge/.anyenv/envs/ndenv/versions/v6.11.2/lib/node_modules/truffle/build/cli.bundled.js
```

```
vim ~/.bashrc
export PATH=$PATH:/Users/hoge/.anyenv/envs/ndenv/versions/v6.11.2/bin
source ~/.bashrc
```

```
truffle init
> Unbox successful. Sweet!
npm init -f
npm install zeppelin-solidity --save

```

初期設定が済んだので、必要なファイル作成。

```
vim contracts/MaruToken.sol
===========================
pragma solidity^0.4.19;

contract ERC20Interface {
    function totalSupply() public constant returns (uint);
    function balanceOf(address tokenOwner) public constant returns (uint balance);
    function transfer(address to, uint tokens) public returns (bool success);
    event Transfer(address indexed from, address indexed to, uint tokens);
}

contract MaruToken is ERC20Interface {
    string public symbol;
    string public  name;
    uint8 public decimals;
    uint public _totalSupply;

    mapping(address => uint) balances;
    function MaruToken(uint initialSupply) public {
        symbol = "MRTK";
        name = "MARUTOKEN";
        decimals = 18;
        _totalSupply = initialSupply;
        balances[msg.sender] = initialSupply;
    }

    function totalSupply() public constant returns (uint) {
        return _totalSupply - balances[address(0)];
    }

    function balanceOf(address owner) public constant returns (uint balance){
        return balances[owner];
    }

    function transfer(address to, uint value) public returns (bool success) {
        require(balances[msg.sender] >= value && value > 0);
        balances[msg.sender] = balances[msg.sender] - value;
        balances[to] = balances[to] + value;
        Transfer(msg.sender, to, value);

        return true;

    }
}
```

```
vim migrations/2_deploy_contracts.js
========================================
// 拡張子をとったsolidityファイル名を指定
var MaruToken = artifacts.require('MaruToken');

module.exports = function(deployer) {
    const initialSupply = 50000e18
    deployer.deploy(MaruToken, initialSupply);
}
```

```
truffle compile
truffle develop 
truffle(develop)> migrate
##確認
truffle(develop)> maruToken = MaruToken.at(MaruToken.address)
truffle(develop)> maruToken.name()
truffle(develop)> maruToken.totalSupply()
truffle(develop)> maruToken.balanceOf(web3.eth.accounts[0])
truffle(develop)> maruToken.transfer(web3.eth.accounts[1], 1000e18)
```

できた。なーんか通貨として使うにはガバガバな気がする。
あとで調整。

### 参考
https://qiita.com/amachino/items/8cf609f6345959ffc450

# メモ
solidityが会話に出ると「ソリッディ...」「ソリッド...」等、後半よく聞き取れない事が多かったので調べてみた。

サァリィダァティィ　　
http://en.hatsuon.info/word/solidity
Kuromoji を使ってブラウザ上で形態素解析を行う (Reactあり/なし)

**目的**: ブラウザで入力された文章を形態素解析する。

:thinking: React 勉強がてら自然言語処理のプロトタイプ画面を作っているところに形態素解析が必要となった。形態素解析 API をもったサーバを別に立てなきゃいけないかなー ([自分のサイトの形態素解析デモ](https://hazm.at/mox/machine-learning/natural-language-processing/morphological-analysis.html)では API 化していたし)。
:bulb: 意外にもクライアントサイドの JavaScript のみ行けました。

形態素解析器には Kuromoji 0.1.1 を使用しています。
この記事ではReact で使うケースと、React を使わないで kuromoji.js を直接使うケースを紹介します。

## React で使う方法

`npm install kuromoji` で [Kuromoji](https://www.npmjs.com/package/kuromoji) をインストールした時にバンドルされている辞書 `node_modules/kuromoji/dict/`  (多分 IPADIC かな?) をブラウザからアクセスできる公開ディレクトリにコピーします。

```
$ npm install kuromoji --save
$ cp -a node_modules/kuromoji/dict public/
```

公開した辞書の URI を指定して `kuromoji` で形態素解析します。

```javascript
import kuromoji from "kuromoji"
// ...

const text = "親譲りの無鉄砲で小供の時から損ばかりしている"
kuromoji.builder({ dicPath: "/dict" }).build((err, tokenizer) => {
  if(err){
    console.log(err)
  } else {
    const tokens = tokenizer.tokenize(text)
    console.log(tokens)
  }
})
```

build() のコールバックは非同期で行われる点に注意。1,067 文字の文章に対するパフォーマンスは:

1. build() のコールバックまで 1,197ms。
2. tokenize() の処理が 26ms。

形態素解析だけであれば意外に速い。

`build()` のたびに辞書の読み込みを行っているようで体感速度のボトルネックになっている。`Tokenizer.js` のソースを読む限り `tokenizer` は状態が変更されないようなので、一度構築した後の使い回しは可能と思われる (確証はないが)。

2度目以降の辞書のアクセスは 304 Not Modified レスポンスなので辞書のダウンロードではなく読み込みと解析に時間がかかっている。このため ServiceWorker で辞書をローカルにキャッシュさせてもあまり効果はないと推測する。

tokenize() が成功した場合、以下のような形態素情報の配列を返してくる。

```json
[
  {
    "word_id": 564230,
    "word_type": "KNOWN",
    "word_position": 1,
    "surface_form": "親譲り",
    "pos": "名詞",
    "pos_detail_1": "一般",
    "pos_detail_2": "*",
    "pos_detail_3": "*",
    "conjugated_type": "*",
    "conjugated_form": "*",
    "basic_form": "親譲り",
    "reading": "オヤユズリ",
    "pronunciation": "オヤユズリ"
  },
  ...
]
```

## React を使わない方法

React を使用しなくても通常の JavaScript と同じように Kuromoji を利用することができます。必要なのは React のケースでコピーした辞書に加えて `node_modules/kuromoji/build/kuromoji.js` 。これらをブラウザからアクセス可能な公開ディレクトリにコピーします。

Kuromoji を利用する HTML 側で `<script>` 要素を記述します。これでグローバルスコープで `kuromoji` オブジェクトが利用可能になるので React の場合と同じように記述できます。

```html
<script src="/js/kuromoji.js"></script>

<script>
var text = "親譲りの無鉄砲で小供の時から損ばかりしている"
kuromoji.builder({ dicPath: "/dict" }).build(function(err, tokenizer){
  if(err){
    console.log(err);
  } else {
    var tokens = tokenizer.tokenize(text);
    console.log(tokens);
  }
});
</script>
```
NICのリンクアップを確認する方法

# 目的 
どのLANポートがどのNIC(eth0、1)か判別する。
 
_放置されている物理サーバ(複数LANポート)を使用するときがあり、どのポートがeth0? eth1?となった。
この状態を解消できそう_

# 環境
RHEL6
 →複数ポーﾄ
※RHEL7でも同様

# 手順
① サーバにコンソール接続し、サーバ背面にあるいづれかのLANポートにLANケーブルを接続する。
※LANケーブルの対向先もスイッチなどに接続する。


② 試しにeth0で確認する。

```
[root@test ~]# ethtool eth0
```

③ 最下行のLink detectedが「Yes」であればLANケーブルを接続したLANポートがeth0である。

```
Settings for eth0:
        Supported ports: [ TP ]
        Supported link modes:   10baseT/Half 10baseT/Full
                                100baseT/Half 100baseT/Full
                                1000baseT/Full
        Supports auto-negotiation: Yes
        Advertised link modes:  10baseT/Half 10baseT/Full
                                100baseT/Half 100baseT/Full
                                1000baseT/Full
        Advertised pause frame use: No
        Advertised auto-negotiation: Yes
        Speed: 1000Mb/s
        Duplex: Full
        Port: Twisted Pair
        PHYAD: 0
        Transceiver: internal
        Auto-negotiation: on
        MDI-X: Unknown
        Supports Wake-on: d
        Wake-on: d
        Current message level: 0x00000007 (7)
        Link detected: yes
```
UnityのInputFieldでカーソルが表示されない問題の解決策

# InputFieldのカーソルがpositionによって表示されたり非表示になったりする人向け

全角日本語がバグったり、5.2系でcaretバグだったりで困ってる方は、Google先生にググって助けてもらいましょう。

私がハマったのはSceneViewではカーソルが点滅してるのに、GameViewではカーソルが表示されなかったりする。の問題を解決します。

![スクリーンショット 2018-02-28 20.54.25.png](https://qiita-image-store.s3.amazonaws.com/0/14560/b31128f2-e330-8dcf-f934-7d3656502ec7.png)

#・解決方法
![スクリーンショット 2018-02-28 21.11.39のコピー.png](https://qiita-image-store.s3.amazonaws.com/0/14560/b7bc1083-4dcd-f910-fd03-925bb0e90d40.png)

#・感想
Canvasのサイズが大きいとカーソルが小さくなりすぎて見えてないだけなのかな。。。
Imageでも幅が1pxで長さが400px等のいわゆる線みたいな使い方すると太さがバラバラに見えたり歯抜けになったりするからなあ。。。
Git ignore file

##1) To start ignoring changes to a single already versioned file
```git update-index --assume-unchanged "main/dontcheckmein.txt"```
and to undo that 
```git update-index --no-assume-unchanged "main/dontcheckmein.txt"```

check here

##2) To completely ignore a specific single file preventing it from being created at repository

First look at this Git global ignore not working

and at .gitignore add the relative path to the file without leading ./

so if your file is at MyProject/MyFolder/myfile.txt (where .git is also at MyProject), at .gitignore you put just this MyFolder/myfile.txt

you can confirm what rule is related to the ignore with git check-ignore "MyFolder/myfile.txt"

About global ignore

That link speaks about ~/.gitignore_global; but the file is related to your project; so, if you put the exclude pattern MyFolder/myfile.txt at ~/.gitignore_global, it will work but will not make much sense...

In the other hand, if you setup your project with git config core.excludesfile .gitignore where .gitignore is at MyProject; that setup will override ~/.gitignore_global that can have very useful rules...

So, for now, I think the best is to make some script to mix your .gitignore with ~/.gitignore_global at .gitignore.
Kotlin のスコープ関数早見表

詳細な説明は [Kotlin スコープ関数 用途まとめ - Qiita](https://qiita.com/ngsw_taro/items/d29e3080d9fc8a38691e) を参照。

|関数   |`this`      |`it`|戻り値|定義|
|-------|-----------|-----|---|---|
|`let`  |-          |レシーバ|ラムダ式の戻り値|`<T, R> T.let(f: (T) -> R): R`|
|`with` |第一引数の値|-      |ラムダ式の戻り値|`<T, R> with(receiver: T, f: T.() -> R): R`|
|`run`  |レシーバ   |-       |ラムダ式の戻り値|`<T, R> T.run(f: T.() -> R): R`|
|`apply`|レシーバ   |-       |レシーバ     |`<T> T.apply(f: T.() -> Unit): T`|
|`also` |-         |レシーバ |レシーバ     |`<T> T.also(block: (T) -> Unit): T`|

**言葉の説明**

- **ラムダ式**
    - ここでの「ラムダ式」とは、スコープ関数の引数に渡す関数のこと
    - `"hoge".let {...}` の `{...}` の部分
- **this 列**
    - ラムダ式の中で `this` が指すもの
- **it 列**
    - ラムダ式に渡される引数
- **戻り値列**
    - スコープ関数の戻り値が何になるか
- **レシーバ**
    - スコープ関数のレシーバ
    - `"hoge".let {...}` の場合は `"hoge"` がレシーバ
- **ラムダ式の戻り値**
    - ラムダ式が返した値
    - `"hoge".let {"fuga"}` の場合は `"fuga"` のこと
- **第一引数の値** (`with`)
    - `with("hoge") {...}` の `"hoge"` のこと


```kotlin:検証コード
test("let") {
    "hoge".let {
        println("this=$this, it=$it")
        "return value"
    }
}
/* 出力結果
=====let=====
this=Scope_function@6eb089e6, it=hoge
returnValue=return value
*/

test("with") {
    with("hoge") {
        println("this=$this")
        "return value"
    }
}
/* 出力結果
=====with=====
this=hoge
returnValue=return value
*/

test("run") {
    "hoge".run {
        println("this=$this")
        "return value"
    }
}
/* 出力結果
=====run=====
this=hoge
returnValue=return value
*/

test("apply") {
    "hoge".apply {
        println("this=$this")
    }
}
/* 出力結果
=====apply=====
this=hoge
returnValue=hoge
*/

test("also") {
    "hoge".also {
        println("this=$this, it=$it")
    }
}
/* 出力結果
=====also=====
this=Scope_function@6eb089e6, it=hoge
returnValue=hoge
*/

fun test(name: String, testCase: () -> Any) {
    println("\n=====$name=====")
    val returnValue = testCase()
    println("returnValue=$returnValue")
}
```
psqlを叩くとWarningが出るので消してやった

PostgreSQLのバージョンは9.5を入れたはずなのに8.4を指し示しているようなので、その参照を更新しました。

```
-bash-4.2$ psql postgres deploy
psql (9.2.15, server 9.5.4)
WARNING: psql version 9.2, server version 9.5.
         Some psql features might not work.
Type "help" for help.
```

実行ファイルを探します

```
-bash-4.2$ which -a psql
/bin/psql
/usr/bin/psql
```

```
# find / -name psql 2>/dev/null
/usr/pgsql-9.5/bin/psql
/usr/bin/psql
```

/usr/bin/psqlの方が古いのでこちらをリネームして、9.5の方のpsqlのシンボリックリンクを張ることで置き換えます。

まずはリネームして残しておきます。名前は「.old」というのを書き足しましたがなんでもいいです。

```
# mv /usr/bin/psql /usr/bin/psql.old
```

これで一応再起動して確認します。

```
-bash-4.2$ psql
psql (9.5.4)
Type "help" for help.
```
CentOS7に新しいバージョンのPostgresqlをyumでインストールする

CentOS7.1の64bit版のyumリポジトリにPostgreSQLを追加し、最新バージョンをインストールする方法を以下に示します。

CentOS7.1のyumで標準インストールできるPostgreSQLのバージョンは、9.2.14と古いです。PostgreSQLのyumリポジトリを利用することで、最新バージョンのPostgreSQLをyumコマンドによりインストールすることができるようになります。

##PostgreSQLのリポジトリ設定パッケージをダウンロード
-以下のコマンドを実行して、PostgreSQLのリポジトリ設定パッケージを入手します。
※ここでは、PostgreSQL9.5をCentOS7 64bit用のリンクからダウンロードしています。

```
$ wget https://download.postgresql.org/pub/repos/yum/9.5/redhat/rhel-7-x86_64/pgdg-centos95-9.5-2.noarch.rpm
```
- なお、PostgreSQL9.6はテストバージョンなので避けましょう

##PostgreSQLのリポジトリをインストール
以下のコマンドを実行して、PostgreSQLのリポジトリ設定をインストールします。

```
$ rpm -Uvh pgdg-centos95-9.5-2.noarch.rpm
```

- デフォルトの設定では、yumコマンドの実行時にPostgreSQLのリポジトリは、自動的に使用されるようになっています。明示的に使用されるようにしたい場合は、インストールされたPostgreSQLのリポジトリの設定ファイル「/etc/yum.repos.d/pgdg-95-centos.repo」を、以下のように編集します。

```
[pgdg95]
：（略）
enabled=1
↓変更
enabled=0
```

- yumコマンドの実行時にPostgreSQL9.5のリポジトリを使用するには、以下のようにオプション「--enablerepo=pgdg95」を付けて実行します。

```
$ yum --enablerepo=pgdg95 list | grep postgresql
```

###PostgreSQLのインストール
- 以下のコマンドを実行して、PostgreSQL9.5の最新バージョンのインストールを行うことができます。

```
# yum --enablerepo=pgdg95 install postgresql9５-server
```

Rails用なので、pgがインストール出来ない可能性が高いから、develを入れましょう。

```
$ sudo yum -y install postgresql-devel
```

##データベースの初期化
- PostgreSQLをインストール後、初めにデータベースの初期化を行う必要があります。

###以下のコマンドを実行して、データベースの初期化を行います。絶対してください。

```
$ /usr/pgsql-9.５/bin/postgresql9５-setup initdb
```

###インストール後の設定
- PostgreSQLのサービスを起動
以下のコマンドを実行して、PostgreSQLのサービスを起動することができます。

```
$ systemctl start postgresql-9.５.service
```

###PostgreSQLのサービスを自動で起動させる
- PostgreSQLのサービスは、インストール時点では自動起動設定がされていません。
自動起動設定の状態は、以下のコマンドで確認できます。

```
$ systemctl is-enabled postgresql-9.５.service
disabled
````
- 自動起動する設定になっている場合は「enabled」、なっていない場合は「disabled」と表示されます。
- 自動起動する設定になっていない場合、以下のコマンドで自動で起動するように設定できます。

```
$ systemctl enable postgresql-9.4.service
```

- 自動起動しないようにしたい場合は、以下のコマンドを実行します。

```
$ systemctl disable postgresql-9.4.service
```

###PostgreSQLへの接続
PostgreSQLへの接続の認証に関する設定は、PostgreSQLの設定ファイル「/var/lib/pgsql/9.5/data/postgresql.conf」と「/var/lib/pgsql/9.5/data/pg_hba.conf」で行われています。
デフォルトの設定は、以下のようになっています。

PostgreSQLをインストールすると、データベース「postgres」、データベース接続ユーザー「postgres」が作成され、CentOS上にもユーザー「postgres」が作成されます。
よって、PostgreSQLのインストール後の最初の接続は、ローカルからUnixドメインソケットで、ユーザー「postgres」を使用したpeer認証で行うことができます。
接続するには、以下のようなコマンドを実行します。

```
$ su - postgres
# psql
```

「su」コマンドで、ユーザーを「postgres」に切り替えます。

postgresユーザーにパスワードを設定
デフォルトでは、postgresユーザーにパスワードが設定されていません。以下のようなステートメントを実行して、パスワードの設定を行うことができます。

```
# postgres=# ALTER ROLE postgres PASSWORD 'xxxxxxxxxx';
```
Git error:1407742E


# エラー
突然error:1407742Eが出るようになった。

error:1407742E:SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert protocol version



![image](https://qiita-image-store.s3.amazonaws.com/0/49910/76ca60e3-a3da-26c5-2107-563980831cf2.png)


# 解決法

Gitのサイトから最新版を取得してバージョンアップを行う！

[Git \- Downloading Package](https://git-scm.com/download/win)


2017/2/22にTLS1が廃止になった事が原因の模様です。
[Weak cryptographic standards removal notice \| GitHub Engineering](https://githubengineering.com/crypto-removal-notice/)



## 参考

[git pull が急にできなくなったときの解決模索記録 \- Qiita](https://qiita.com/TYuko/items/04c26073bc83efbdd009#tls12%E3%82%92%E4%BD%BF%E3%81%86%E6%96%B9%E6%B3%95%E8%A9%A6%E3%81%97%E3%81%A6%E3%81%BF%E3%81%9F)



[GitHub への push/pull/clone が突然「error:1407742E:SSL routines:SSL23\_GET\_SERVER\_HELLO:tlsv1 alert protocol version」エラーで使えなくなった件 \- stamemo](http://stakiran.hatenablog.com/entry/2018/02/24/174941)
QueryBuilderを使うときのfetchAll系に気をつけろ

# 概要

働いていてやばいなーと思ったこと(PHP)があったので、戒めを込めて書く。

# fetchAll

大変便利。しかし何も考えずに使うと


### **サービスが大きくなった時に痛い目見る。**



# 痛い目=> BadGateWay 502

要するにメモリオーバーが起こる。よく見るエラーはこんな感じ。

> PHP Fatal error: Allowed memory size of 536870912 bytes exhausted (tried to allocate 32 bytes) in phar:[ファイル名].php on line [~行目]

もともとあまり多くselectしねーだろとか思って油断していると起こる。
例えば100件とか程度の負荷を想定しててもユーザに1万件とかやられるとただただ辛い。

# 対策

## 運用面

fetchAllを使うのであれば、何件程度まで耐えられるのか**負荷テストをする**のがオススメ。そして耐えられる件数にバッファを考慮した件数をユーザに伝える。

例：

負荷テストで落ちなかった限度の件数： 100件
ユーザに伝える件数：50件

=> ユーザに伝える件数はサービスやどの機能に適用したか(その機能が頻繁に使われるか)によるのでそこは考える必要がある。

## 技術面

1. クエリにLimitかける。
2. クエリのパフォーマンス改善

だいたいこの二つかと考えられる。


他にもあれば、コメントいただけると助かります。
フロントエンド・テストツール比較 Puppeteer #01環境構築編

## :metal:この記事でやること
Puppeteerの環境構築を行い、Headless-Chromeが動くのを確認するまで。

## :metal:自己紹介
[株式会社Creaith](http://creaith.jp/)の上田です。
社員の[曽宮](https://qiita.com/ryosomiya)が、フロントエンドテストツールはpuppeteerが最高などとって言ってたら
同僚の[モトキ](https://qiita.com/pickles)が「seleniumでも同じことやってやる」と言い出したので。 
社員の[曽宮](https://qiita.com/ryosomiya)が記事を書き、私はそれを見守る事になりました。 
えぇ　全力で見守るだけです。 
もちろん対決なので負けたら、一蓮托生、私もそれに巻き込まれてゴニョゴニョゴニョ

いろいろ比較していきPuppeteerを活用できる様になれるとこまでを連載して行こうと思います。  
比較対象：[フロントエンド・テストツール比較 Selenium #01環境構築編](https://qiita.com/creaith/items/c138c0417470a17cc4b4)



## <img src="https://qiita-image-store.s3.amazonaws.com/0/240629/de493f31-fb7c-e67f-7c16-00996b66b17c.png" width="30px">Puppeteerとは

###### 「ぱぺってぃ~あ」はとにかく環境構築がメタクソに楽なのです
  
先日Google Chromeにヘッドレス機能が追加追加され、CLIでブラウザを操作できるよになりました。  
それを使ってSPAのレンダー後の状態に対してテストできるんですが、環境構築が常軌を逸する程に楽ちんちんです。

1. ChromeDevTools開発チームがメンテナンスしてるよ
1. Chrome以外のブラウザはムリ
1. ReduxのActionなんかも横取り出来ちゃう
1. ドロ沼化しやすいE2Eテスト環境に向いてる...ハズ

SPAとの合性も良さげなのでデファクトになる可能性メタくそ高いですね


## :metal:まずは環境構築

ローカルでpuppeteerが動く環境をつくっていきます。
[公式ドキュメント](https://github.com/GoogleChrome/puppeteer)を元にサクっと動くまで

### 前提条件
|使用する技術|バージョン番号|
|---|---|
|macOS HighSierra|10.13.3|
|Homebrew|1.5.3|
|nodebrew|0.9.8|
|node|v8.9.4|
|npm|5.6.0|

公式によると
>Usage
Caution: Puppeteer requires at least Node v6.4.0, but the examples below use async/await which is only supported in Node v7.6.0 or greater.

と、Nodeのバージョンは`v6.4.0`以上が必要で、`async``await`を使うには`v7.6.0`以上が必要です。なのでNodeのバージョンは`v7.6.0`以上にしておきましょう。

### 作業ディレクトリにてpuppeteerをインストール
```
$ mkdir puppeteer && cd puppeteer
$ npm i --save puppeteer
```

これだけでローカルで動かす準備が既に整いました。簡単ですね！

## :metal:puppeteerを実行する
簡単なテストをしてみます。
`https://example.com`にアクセスし、スクリーンショットを撮るだけのテストをしてみましょう。

### テスト用のファイルを作成する
テスト用のファイル`script.js`を作成し、以下のように編集する。

```script.js
const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch({
    args: [
      '--no-sandbox',
      '--disable-setuid-sandbox'
    ]
  });
  const page = await browser.newPage();
  await page.goto('https://example.com');
  await page.screenshot({ path: 'example.png' });

  browser.close();
})();
```

## :metal:テストを実行する
`script.js`にテストコードを記述したら、コマンドを叩きテストを実行する

```bash
$ node script.js
```
スクリーンショットは`puppeteer/example.png`という名前で保存されている。

## :surfer:次回は...
まだ何やるかまだ決めてませんが
本来ならここからシナリオテストを作製して
結果の表示まで自動化したり
CIテストで利用できる様にしたい所です。

### 18/03/29追記
続きを投稿しました。
[フロントエンド・テストツール比較 Puppeteer #02テスト編](https://qiita.com/creaith/items/cde0cbf56c88021b534d)

## Creaithメンバー
この記事の著者：[上田](https://qiita.com/uedashuhei)、[曽宮](https://qiita.com/ryosomiya)
その他メンバー：[志村](https://qiita.com/naoto1222)、[モトキ](https://qiita.com/pickles)
Rails Stripe 単発(都度)決済の実装

# 概要

RailsでAPIを使うまでの事前準備はこちら。
[Rails Stripe サブスクリプション決済実装 初期設定をしてAPIを使える状態にする](https://qiita.com/ss_watanabe/items/8c5ec353a842d5d30e77)

今回は単発決済の実装の紹介をします。

# 管理ページから単発決済の登録
Stripe管理ページでの「支払い」から支払いの一覧が閲覧できます。
管理ページからの単発決済はこの画面の「新規」より追加できます。
<img width="1401" alt="スクリーンショット 2018-02-28 19.41.03.png" src="https://qiita-image-store.s3.amazonaws.com/0/147005/54be2f48-99fe-395e-bc54-99300a01dae1.png">

こんな感じです。
<img width="1409" alt="スクリーンショット 2018-02-28 19.56.05.png" src="https://qiita-image-store.s3.amazonaws.com/0/147005/0793692a-1456-b3a5-d6de-e2d915e914bd.png">
その他のオプションでは住所など細かい情報も登録できます。

# Railsから単発決済の登録
それでは本丸、Railsでの実装を見ていきましょう。
単発決済の実装には```Stripe::Charge```クラスの```create```メソッドを使用します。
前回```Stripe```モジュールを使用できる設定は完了させているので、適切なパラメータを設定するだけで支払いが作成されます。
任意のカスタマーに対して支払いを登録します。
[公式リファレンス：Create a charge](https://stripe.com/docs/api/ruby#create_charge)

## 実装
```rb
def create_plan
  ::Stripe::Charge.create(
    amount: 10000,
    currency: 'jpy',
    customer: "StripeのカスタマーID cus_XXXX",
    description: "メモ"
  )
end
```

細かい設定をしようと思えばパラメータは5倍、10倍になってきます。


## 確認
API側からも確認できますが、
手っ取り早くStripe管理ページでみてみましょう。
無事追加されています。
<img width="1398" alt="スクリーンショット 2018-02-28 20.14.53.png" src="https://qiita-image-store.s3.amazonaws.com/0/147005/405795ef-aedf-fc91-ee6d-0d2846c9d573.png">

詳細も正常ですね。
<img width="1398" alt="スクリーンショット 2018-02-28 20.16.58.png" src="https://qiita-image-store.s3.amazonaws.com/0/147005/3333a981-16ed-9577-01c9-08fffeaea911.png">



# 所感
やっぱりStripeわかりやすいなあ
英語がもう少しわかればもっとできること広がりそう（小並感）
前から管理画面日本語対応してたっけ...

# 参考

- Stripe API Reference<br>
https://stripe.com/docs/api

ブログで見たい方はこちら
[Rails Stripe 単発(都度)決済の実装](http://nabesys.com/article/2018/02/28391/)
javascriptでiframeの中身全てを書き換える

# この記事を書くきっかけ

テキストエリアに入力されたHTMLの内容をまるっと
iframeに反映できないかなーと思ってやってみたところできたのでそのメモです。


# コード

```html:sample.html
<iframe id="preview"></iframe>
<textarea id="text" rows="8" cols="80"></textarea>
<button id="apply" name="button">適用</button>

<script>
$("#apply").on('click', function(){

    // textareaの中身をDataURIスキーマにする。
    var dataUri = "data:text/html;charset=utf-8,"+$("#text").val();
        
    // iframeのsrc属性に指定。
    $('#preview').attr('src', dataUri);

});
</script>
```

- bodyタグ内のみ記載
- jQuery.3.2.1.min.jsを使用

# 悩んだところ
headタグやbodyタグの操作は普通にできると思ったのですが
中身全てとなるとどうやればいいんだろうと思いました。

# 解決方法
DataURIスキームを使う。
base64画像みたいにリソースを外部ファイルではなく、ページに埋め込め要領でやればいけるなと

# まとめ
DataURIスキームは便利だなぁ、あまり使わないので存在を忘れかけていました。
というわけで今回はこんな方法で実現できました。
できましたけども、もっといい方法があるんだろうなと思う日々
gitで変更があったファイルを列挙する

今作業しているブランチで変更・追加を行ったファイルを列挙したい。

具体的には、 lint チェックの対象を作業中のファイルだけに絞って省力化したい、というイレギュラーじみたケースのためにやってみました。

## `master` と作業中ブランチとで差があるファイルを列挙

次のコマンドで `master` と `HEAD` (作業中ブランチ)とで差があるもののファイル名を列挙できます。

```sh
git -c core.quotepath=false diff master HEAD --name-only
```

`-c core.quotepath=false` を付けているのは、取得したファイル名を他コマンドのパラメータにする目的があるのでこの時点でエスケープとかやってほしくなかったからです。
`master` と `HEAD` はベースにするブランチ・対象にするブランチで読み替えましょう。

ただし、このコマンドでは `master` に対しての作業中ブランチのファイルだけでなく、作業中ブランチに対して差がある `master` のファイルも出てきてしまいます。

## `master` ではなく `master` から作業中ブランチを生やしたベースコミットから差があるファイルを列挙

GitHub の Pull Request みたいにベースコミットからその作業中ブランチで変更したファイルだけを列挙したいです。
なのでベースコミットを見つけてくればよい。

```sh
git -c core.quotepath=false diff `git show-branch --merge-base master HEAD` HEAD --name-only
```

さっきのコマンドの `master` を `git show-branch --merge-base master HEAD` に置き換えただけです。
読みづらいので、シェルスクリプトの中で使う場合は次のように一度変数に入れたほうがよいでしょう。

```sh
BASE_COMMIT=`git show-branch --merge-base origin/master HEAD`
git -c core.quotepath=false diff $BASE_COMMIT HEAD --name-only
```

## 列挙したファイル名を他コマンドのパラメータにする

こんな事し出した目的は、 Pull Request に含まれるファイルだけを対象に lint チェックかけたかったからでした。
そこで最終的に出来上がったのが次のようなシェルスクリプトです。

```sh
#!/bin/bash -eux

BASE_COMMIT=`git show-branch --merge-base origin/master HEAD`
files=()
while read file
do
    files+=("${file}")
done < <( git -c core.quotepath=false diff $BASE_COMMIT HEAD --name-only | grep -E '\.md"?$' )

if [ ${#files[@]} -gt 0 ]; then
    npm run lint "${files[@]}"
fi
```

本当はスクリプトの実行パスの正規化のために ``cd `dirname $0` `` とか他にもやってるんですが割愛してます。
今回チェックしたいのは Markdown のドキュメントだったので `grep -E '\.md"?$'` でファイルをさらに絞り込んでます。
ファイル名に空白が含まれたりして面倒くさかったんですが、[参考記事](#参考)などのおかげでエスケープとか深く考えずになんとかなりました。

そういうわけで、できあがったスクリプトを CI で動かしています。

## 参考

- [[bash] スペースが入ったファイル名の処理](https://qiita.com/daei/items/76635f9fbf25824b525e)
- [パイプ出力を現在のシェル上のwhileに喰わせる上手いやり方](https://qiita.com/kawaz/items/6fd4cd86ca98af644a05)
[redux-saga]フォームに高速で入力するとガックガクになる問題

# 課題
`redux-saga` でテキストボックスなどの値が変更されるたびにバリデーションを実行したい時、アクションが発行されすぎて入力がガックガクになってしまうことがありますよね。
(止まっているように見えますがgifアニメです)
![saga.gif](https://qiita-image-store.s3.amazonaws.com/0/45330/88cc8517-a311-c7a8-54d1-3b00b2fa2542.gif)

コードはこんな感じです。

```saga-slow.js
import { all, takeLatest, select, call, put } from 'redux-saga/effects'

export function* validateProduct(key) {
  const product = yield select(productSelector)
  const messages = yield call(productValidator, product, key) // バリデーションして
  yield put(finishValidate(key, messages)) // バリデーション完了アクションの発行
}

export default function* rootSaga() {
  yield all([
    takeLatest('CHANGE_COMMENT', validateProduct, 'comment')
  ])
}
```

# 解決方法

## **redux-saga の delay を使う！**

```saga-fast.js
import { delay } from 'redux-saga'
import { all, takeLatest, select, call, put } from 'redux-saga/effects'

export function* validateProduct(key) {
  yield call(delay, 100) // 100ms Delay!

  const product = yield select(productSelector)
  const messages = yield call(productValidator, product, key) // バリデーションして
  yield put(finishValidate(key, messages)) // バリデーション完了アクションの発行
}

export default function* rootSaga() {
  yield all([
    takeLatest('CHANGE_COMMENT', validateProduct, 'comment')
  ])
}
```

こんな感じで高速に大量に入力してもスムーズになりました。
![saga-fast.gif](https://qiita-image-store.s3.amazonaws.com/0/45330/74541d39-a555-9ef5-6f16-c57a10bf812c.gif)

## 何が起きているのか
100msのディレイを掛けてからバリデーションを実行するようになったことで、 `takeLatest` の効果で100ms以内にもう一度 `CHANGE_COMMENT` アクションが来た場合に前に実行していたものがキャンセルされるという仕組みです。
100ms以内に入力され続けるとエラーメッセージが表示されないという難点はありますが、入力を止めた瞬間に表示されるので自然な挙動になっていると思います。

(追記)
[redux-sagaのドキュメント](https://redux-saga.js.org/docs/recipes/)によると `throttle` というエフェクトでも同じことが実現できるみたいです。

```saga-throttle.js
import { all, throttle, select, call, put } from 'redux-saga/effects'

export function* validateProduct(key) {
  const product = yield select(productSelector)
  const messages = yield call(productValidator, product, key) // バリデーションして
  yield put(finishValidate(key, messages)) // バリデーション完了アクションの発行
}

export default function* rootSaga() {
  yield all([
    throttle(100, 'CHANGE_COMMENT', validateProduct, 'comment')
  ])
}
```
rack-traffic-signalにヘッダーを見てルールを適用させるかどうか決めることができるヘルパーを実装しました

# そもそもなにそれ

## 概要

半年ほど前に作成したgem(Rackミドルウェア)です。そのときの記事はこちら↓。

https://qiita.com/k5trismegistus/items/6a645ceab53396aed0f8

Rubygemsのページは

https://rubygems.org/gems/rack-traffic-signal

Githubリポジトリは

https://github.com/k5trismegistus/rack-traffic-signal

です。

改めて説明すると、次のようなことが実現できます。(以下Webサービスという言葉が出てきますが、Rackミドルウェアである以上Rackを利用しているRuby製アプリのことです。)

- Webサービスを特定のIPアドレスからのアクセスに対してだけ公開する
- インターネット上に公開されているWebサービスに増やした新機能(ルーティング, API)だけを社内限定公開にする
- Webサービスに不具合が起きたとき、一時的にアクセスしてもメンテナンス画面が出るようにする。APIもそれ用のレスポンスを返すようにする。

## 機能

特定のパスへのリクエストに対して、次のRackミドルウェア/Rackアプリケーションにリクエストを渡さずに静的なHTMLやJSONを返せるようにする、というのが基本機能です。

そういうのってnginxとかがやるもんじゃないの？と思う人も多いでしょう。Rackミドルウェアにすることによって、

- 設定が柔軟にできる
- 有効かどうか切り替えがかんたん

といったメリットを得られます。

また、対象となるパスへのアクセスではあるが条件を満たしていたら対象外とするという仕組みを備えています。あらかじめ設定してあるブロックの評価した結果を利用するので、Rubyで条件を記述することができます。

このときに使えるヘルパーメソッドとして、よく使われるんじゃないか(というか自分のケースで必要だった)

- リクエスト元IPアドレスが事前に定義したリスト上にあるか
- リクエスト先がパスが無視するパスリスト上にあるか

の２つを用意していました。もちろん、判定を行うブロックは自由に書けるので"毎時0~10分の間だけ通す"みたいな判定も可能です。

## 今回の変更

適用条件判定に使えそうなヘルパーとして、HTTPヘッダが特定の値を持っているかどうかを見るメソッドを追加しました。

このメソッドは `X-RACK-TRAFFIC-SIGNAL` というキーの値が特定の値を持っているかどうかを判定します。

これによって、社内IPアドレスからのアクセスかつヘッダーを適切にセットしている場合のみリクエストを通すことが可能になります。社内でも特定の人にしかアクセスさせない、といったことが可能になりますね。

ヘッダーの追加はブラウザ拡張でかんたんに行うことができます。
https://chrome.google.com/webstore/detail/modheader/idgpnmonknjnojddfkpgkljpfnnfcklj
画像を変えよう

#画像をある条件のもと登場させる方法
##まず画像つくろう
この記事参照しよう↓↓↓↓
https://unity3d.sakura.ne.jp/unity/canvas-text-image.html

##次に画像をスクリプトでつけたり消したりしよう
使うコードはこちら
上が一般的な表し方、下がわかりやすく？具体的に説明したもの

```
GameObject.SetActive(bool値);

"CubeとかTextとか".SetActive(false か true);
```


レファレンス（説明書きはこちら）→https://docs.unity3d.com/jp/540/ScriptReference/GameObject.SetActive.html

こいつはどんな役割をするかというと、下の画像のチェックの部分をいじるものなんです！

![image.png](https://qiita-image-store.s3.amazonaws.com/0/181142/22317d43-db67-8b59-fb72-0dc1e3d5e2ad.png)

これを外すとゲーム画面に現れなくなります！
ということでこいつをコードを書いて消してやりましょう！
チェックを付けたい(アクティブ状態)ときは
```GameObject.SetActive(true);```
外したい（非アクティブ状態）ときは
```GameObject.SetActive(false);```
とやってやればおっけ！




##実際にやってみよう！
まずは画像を作ります！こんな感じ！
![image.png](https://qiita-image-store.s3.amazonaws.com/0/181142/7316864c-025f-a152-3c66-e1c79c2d854b.png)

さて、これをゲーム開始と同時に写真を消しましょう！
まずはスクリプトを作って、こんな感じでコードを書きます

```
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class NewBehaviourScript : MonoBehaviour {
    //こうなってるところは説明だから、書かなくてもいいよ！
    //GameObjectの名前を決めるよ！ここではpictureにしたけど、違くても大丈夫！
    public GameObject picture;

	// Use this for initialization
	void Start () {
        //ゲーム開始時に非アクティブ状態にするよ
        picture.SetActive(false);
	}
	
	// Update is called once per frame
	void Update () {
		
	}
}
```

そしたら、Unityの画面に戻って次の操作をしよう！
１、スクリプトをキャンバスにアタッチ！

![image.png](https://qiita-image-store.s3.amazonaws.com/0/181142/9e42cc16-9a28-e0fa-713e-55429f0b2a16.png)

２、キャンパスのスクリプトの部分に目的のGameObjectをアタッチ！
　　（ここでは、食事の写真！）
![image.png](https://qiita-image-store.s3.amazonaws.com/0/181142/aa2db250-f759-03b0-961e-dc6c66ce62b3.png)

３、これでさいせいしてみよう！
そしたら画像が消える！
完成！

##条件付きでやってみよう！
１、まずUnityで画像を非アクティブ状態にしよう！

２、スクリプトを書いていこう
ここで使うのはif文を使うよ！
ScoreScriptに次のようなコードを追加していこう！

```
public class ScoreScript : MonoBehaviour {

    //これ追加！
    public GameObject picture;
    
	// Use this for initialization
	void Start () {

    }

    // Update is called once per frame
    void Update() {
        //Update()｛ここに｝下のコードを書いていこう！
        //scoreの値が１００を超えたらpictureをアクティブ状態にするものだよ！
        if (score <= 100) {
            picture.SetActive(true);
        }
    }
}
```

３、再生して、カウントしていこう！
１００になると画像があらわれる！？
現れなかったらメッセしてね！笑
Viewの動的生成をUIスレッドで実行するのは間違っている件について

# TL;DR
- Viewの作成は別スレッドでも可能。
- 動的なView生成は別スレッドで実行し、addViewだけUIスレッドで実行するとANR回避できるかも。
- iOSではXcode9から警告？が出るとのこと。

# はじめに
UIスレッドで動的にViewを生成してaddViewするということをしていました。
今まではそれがパフォーマンスに影響するほどの量のViewを生成していなかった、Viewの生成が複雑なロジックではなかったため、問題はありませんでした。
しかし、複雑なロジックでViewの動的生成をする画面が出てきました。
それだけが原因ではないのですが、画面が表示されるまで体感5秒近くかかるし、パフォーマンスが極めて悪いことが分かりました。
これではいかんということで、全体的にロジックを見直し、それに合わせてViewの構築についても見直しすることにしました。

# 実装
難しいことはしていません。
Viewの生成を別スレッドで実行、生成したViewをコールバックで返すだけです。
Contextなど必要なものはパラメータで渡します。

```別スレッド.java
List<View> views = new ArrayList<>();

LinearLayout.LayoutParams params =
        new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
TextView textView = new TextView(context);
textView.setLayoutParams(params);
textView.setText("test");

views.add(textView);
```


```UIスレッド.java
LinearLayout container = findViewById(R.id.container);

for (View view : views) {
    container.addView(view);
}
```

これで画面にtestと書かれたTextViewが配置されることを確認できました。

# おわりに
Viewの生成を別スレッド、addViewはUIスレッドをすることでUIを止めることがなくなります。
Viewの動的生成が複雑な場合にANRを回避できるかも。（そこまで確認してません。）
そもそも動的にViewを作るのであれば、また別の手段を考えるべきなんだろうなぁと思っています。
Contextを渡す必要があるので、メモリーリークしないように対策が必須です。