OmniAICreator/Qiita-1.07M huggingface dataset:
parcelでVue.js試す最小構成のpackage.json

# この記事について
さくっとJavascriptのライブラリの動作確認するときに、いつもはvue-cliでwebpackだが、偶然parcelに触れたので、最小構成を調べた。vue.js使ってて、少しparcelに興味がある人向けの記事。

parcelの記事を巡ると `parcel-plugin-vue` を使うケースがあるが、parcel1.7.0から本家でvueのコンパイルがサポートされ現在1.9.6（2018年7月時点）では不要。

# 要点

* `parcel-plugin-vue` は不要
* vueのランタイムビルド使う形に実装すれば
    * `babel-preset-vue` も不要
    * どのビルドを使うかは[この辺の公式ドキュメント](https://jp.vuejs.org/v2/guide/installation.html#%E3%81%95%E3%81%BE%E3%81%96%E3%81%BE%E3%81%AA%E3%83%93%E3%83%AB%E3%83%89%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6)を参照 
* https://github.com/makitosan/simple-parcel-vue
* DEMO https://makitosan.github.io/simple-parcel-vue/

## package.json

```package.json
{
  "name": "simple-parcel-vue",
  "description": "Simple parcel vue.js example",
  "version": "1.0.0",
  "scripts": {
    "watch": "NODE_ENV=development parcel -d docs --no-hmr index.html --open",
    "prebuild": "rm -rf docs",
    "build": "NODE_ENV=production parcel build index.html -d docs --no-minify --public-url /simple-parcel-vue/"
  },
  "dependencies": {
    "vue": "^2.5.10",
    "vue-hot-reload-api": "^2.3.0"
  },
  "devDependencies": {
    "@vue/component-compiler-utils": "^1.3.1",
    "babel-preset-env": "^1.6.1",
    "parcel-bundler": "^1.9.6",
    "vue-template-compiler": "^2.5.16"
  }
}

```

* デモ用に github pages を使いたかったので `-d docs` と `--public-url /simple-parcel-vue/` オプション入れた

## .babelrc

```.babelrc
{
  "presets": [
    "env"
  ]
}
```

## main.js

```main.js
...
new Vue({
    el: '#app',
    render: h => h(App) // this is not required full (including compiler) Vue
});
```

* :exclamation: こんな感じで `render` 使ってコンパイラ無しでいけるようにした
Laravelで手軽に静的解析

# 静的解析をしよう
PhpstanにLaravel用のwrapperをかぶせたその名も[Larastan](https://github.com/nunomaduro/larastan)

## 動作環境
PHP 7.1.3+
Laravel 5.6+

## インストール
```bash
composer require --dev nunomaduro/larastan
```

## 実行
```bash
php artisan code:analyse
```

### オプション
```bash
php artisan code:analyse --level=5
```
オプションで0から7のチェックの度合いを渡せます（0はゆるゆる、7はきびしい）
何も指定しないと5
--level=maxを指定すると7を指定したことになります

```bash
php artisan code:analyse --paths="modules,app,domain"
```
パスも指定できるようになりました

詳しくは[こちら](https://github.com/nunomaduro/larastan)へ
StringBuilderとStringBufferの違い

## 始めに
「StringBuilderとStringBufferの違いを説明してください。」
と言われ、
「StringBuilderの方がパフォーマンス良いです！！」
としか答えられなかった。

なので今回はなぜStringBuilderがパフォーマンスが良いのか、速度の差はどれぐらいなのかを検証してみました。

## 違う所
StringBuilder：スレッドセーフじゃない
StringBuffer：スレッドセーフ

これだけでした。
StringBuilderを導入したTigerさんによると、
「文字列連結にスレッドセーフって必要?」
という考えで作られたらしいです。

[文字列操作 スレッドセーフ vs パフォーマンス StringBuilder](http://www.javainthebox.net/laboratory/J2SE1.5/TinyTips/StringBuilder/StringBuilder.html)

確かに私もスレッドセーフが必要な文字列連結なんて見たことありません。
多くの人があまり気にせず使ってた所でしょうが、そこを捉えたのはすごいと思います。

## 検証
早速簡単に検証をしてみました。
こちらの検証方法を採用させていただきました。
[【Java】StringBuilderとStringBufferの違いをスレッドセーフの観点で検証してみた](http://totech.hateblo.jp/entry/2015/03/18/231124)

100スレッドで同じStringBuilder / StringBufferのインスタンスを共有、1万回appendを繰り返します。
結果、length()が正しく100万になるかを見ています。
処理速度も測定しました。

※StringBuilderとStringBufferの違いだけのソースになります。

```java:StringBuilderTest.java
public class StringBuilderTest {
  
	public static void main (String... args) throws InterruptedException {
		ExecutorService executor = Executors.newFixedThreadPool(100);
		StringBuilder sb = new StringBuilder();
		List<BuilderTask> taskList = new ArrayList<BuilderTask>();
		
		for(int i = 0; i < 100; i++) {
			taskList.add(new BuilderTask(sb));
		}
		
		Long start = System.currentTimeMillis();
		
		executor.invokeAll(taskList);
		
		System.out.println("-----StringBuilder-----");
		System.out.println("TAT : " + (System.currentTimeMillis() - start));
		System.out.println("length() : " + sb.length());
	}
	
	static class BuilderTask implements Callable<Integer> {
		private StringBuilder sb;
		
		public BuilderTask(StringBuilder sb) {
			this.sb = sb;
		}

		@Override
		public Integer call() throws Exception {
			for(int i = 0; i < 10000; i++) {
				sb.append("#");				
			}
			return null;
		}
	}
}

```
```java:StringBufferTest.java
public class StringBufferTest {
  
	public static void main (String... args) throws InterruptedException {
		ExecutorService executor = Executors.newFixedThreadPool(100);
		StringBuffer sb = new StringBuffer();
		List<BufferTask> taskList = new ArrayList<BufferTask>();
		
		for(int i = 0; i < 100; i++) {
			taskList.add(new BufferTask(sb));
		}
		
		Long start = System.currentTimeMillis();
		
		executor.invokeAll(taskList);
		
		System.out.println("-----StringBuffer-----");
		System.out.println("TAT : " + (System.currentTimeMillis() - start));
		System.out.println("length() : " + sb.length());
	}
	
	static class BufferTask implements Callable<Integer> {
		private StringBuffer sb;
		
		public BufferTask(StringBuffer sb) {
			this.sb = sb;
		}

		@Override
		public Integer call() throws Exception {
			for(int i = 0; i < 10000; i++) {
				sb.append("#");				
			}
			return null;
		}
	}
}

```
## 結果
```
-----StringBuilder-----
TAT : 32
length() : 542861

-----StringBuffer-----
TAT : 157
length() : 1000000
```
StringBuilderだと文字がほぼ半分ぐらい失われた結果になりました。
代わりに処理速度は5倍ぐらい早いですね。

私はやはり実業務でスレッドセーフな文字列連結が必要な場合は考えにくいので、パフォーマンス重視でStringBuilder使うかなと思います。
Ruby eachメソッド(配列)

#eachメソッド

Rubyにはeachというメソッドがあります。
***配列***、***範囲オブジェクト***などで用意されているメソッドで、for文に似た動作をします。

eachメソッドは、ブロック変数（ブロックパラメータ）に配列の要素を代入しながら、
配列・範囲オブジェクトの要素数を繰り返します。

***例***

```rb
オブジェクト.each　do　|変数|
繰り返す処理
end
```


範囲オブジェクトの場合

```rb
(1..10).each do |num|
print("num = ", num,"\n")
end

//実行結果
num = 1
num = 2
num = 3
num = 4
num = 5
num = 6
num = 7
num = 8
num = 9
num = 10

```

配列の場合

```rb
fruits = ["orange", "banana", "apple"]

fruits.each do |fruit|
 puts fruit,"\n"
end

//実行結果
orange
banana
apple
```


＊「"\n"」は改行の意味
RealmSwiftのバージョン確認方法について

Swift version 4.0.3 
RealmSwift version 3.7.4
##Realm swiftのバージョンの確認の方法について
swiftとrealmを用いてオリジナルのアプリケーションを作成しています。

qiitaに記事を上げていこうと思った際に`RealmSwift`のバージョンの確認方法が検索してもわからなかったので書いておきます。

違う方法 or よりよい方法等あればぜひ教えてください。

##やること

```
---Pods--------
            |
             -----RealmSwift----
                            |
                             ---SupportFiles-----
                                            |
                                             -----info.plist

```
の順に辿っていただきinfo.plistを開いてみてください。
その中に
![スクリーンショット 2018-07-29 16.48.03.png](https://qiita-image-store.s3.amazonaws.com/0/231063/e8aa74df-7f51-8d03-70aa-dbc561ea7f4e.png)
Bnndle Versions string.short
というプロパティがあるはずです。
その値がRealmSwiftのバージョンとなります。

画像の例では3.7.4ですね。

##まとめ
RealmSwiftのバージョンを確認できるようになった。
Elastic Beanstalkで作ったRDSにSequel Proで接続する

## 概要
- Elastic Beanstalk経由で作ったRDSにSequel Proで接続する
- EC2を踏み台にSSHポートフォワーディングを利用してアクセスする

## 前提
- Elastic Beanstalkでアプリケーション作成時にEC2リモートログイン用のSSH鍵を設定している
- Elastic Beanstalkの設定画面からRDSインスタンスを起動している

## 手順
### 必要情報を洗い出す
| 必要な項目 | 今回の場合 |
|:--:|:--|
| SSH鍵の場所 | ~/.ssh/beanstalk_key |
| EC2のパブリックIPアドレス | xx.xxx.xxx.xxx |
| RDSのエンドポイント | xxxxxxxxxxxxxxx.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com:3306 |

### SSHコマンドを組み立てる
- ssh -f -N -L 3307: `<RDSエンドポイント>` -i `<SSH鍵の場所>` ec2-user@　`<EC2のパブリックIPアドレス>`
- 今回の場合は下記コマンドになる

```bash
$ ssh -f -N -L 3307:xxxxxxxxxxxxxxx.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com:3306 -i ~/.ssh/beanstalk_key ec2-user@xx.xxx.xxx.xxx
```

- 上記コマンドのオプションについては下記の通り（[参考](https://cloudpack.media/9675)）。

| オプション | 説明 |
|:--:|:---|
| -f | SSHをバックグラウンドで実行する |
| -N | リモートコマンドを実行しない |
| -L | バインドするホスト、ポートとリモートホストとポートを指定する |

- なお上記コマンドを実行すると、バックグラウンドで実行されるため結果が何も表示されず不安になるが、プロセスを確認すると確かに起動していることが確認できる。

```bash
$ ps ax | grep ssh
 1001   ??  S      0:00.05 /usr/bin/ssh-agent -l
 1117   ??  Ss     0:00.03 ssh -f -N -L 3307:xxxxxxxxxxxxxxx.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com:3306 -i ~/.ssh/beanstalk_key ec2-user@xx.xxx.xxx.xxx
 1238 s001  S+     0:00.00 grep ssh
```

- 停止したい場合はプロセスをkillする

```bash
$ kill -9 1117 # 上記コマンドで確認したプロセス番号
```

### Sequel Proでリモートログインする
- バックグラウンドでSSHポートフォワーディングが実行されている状態で、Sequel Proで下記情報を入力する

```
ホスト: 127.0.0.1
ユーザ名: xxxx (自身で設定したユーザー名。Elastic Beanstalkの設定画面で確認できる。)
パスワード: xxxx (自身で設定したパスワード)
データベース名: ebdb （Elastic Beanstalk経由で作成した場合のデフォルト値）
ポート: 3307
```

<img width="462" alt="Sequel_Pro.png" src="https://qiita-image-store.s3.amazonaws.com/0/131942/9463d764-46a5-ec10-5a4f-6d4f802da5a6.png" />

- 「接続」ボタンをクリックすると、無事に接続できるはず。
- ちなみにコマンドラインからMySQLにリモートログインしたい場合は下記コマンドを使う。

```bash
$ mysql -u xxxx -h 127.0.0.1 -P 3307 -p
Enter password: xxxxx
```

## 補足
- SSH鍵は暗号鍵ではなくpemファイルでも良いらしい
- EC2のパブリックIPアドレスはパブリックDNSでも良いらしい
- どうでもいいけど `beanstalk` はビーンスターク（bean-stalk）と読むらしい

## 参考
- [Amazon VPC内のRDS(MySQL)にSSHのポートフォワードを利用して接続するメモ - cloudpack.media](https://cloudpack.media/9675)
画面遷移図ツール2018年決定版 Overflowを知っているか	

![overflow.png](https://qiita-image-store.s3.amazonaws.com/0/135757/60288c06-7f77-6d16-cb85-a22764f28c97.png "overflow.png")


有名アプリの画面仕様を調査するために画面遷移図を作っているのですが、少し前まではSketchプラグインの[User Flows](https://abynim.github.io/UserFlows/)を使っていました。
　そっから少し間が空いて、現在ではOverflowというツールが人気になりつつあったため、使ってみたところめちゃめちゃ使い勝手が良かったので、今回それを紹介したいと思います。
　
## 前提
　Overflowは独立したツールなのですが、他のデザインアプリと連携して使うことができ、それがメリットの一つでもあります。
　２０１８年７月現在ベータ版となっていますが利用できるのはmacOSのみで、連携アプリはFigma,Sketchのみですが、将来的にwindowsやAdobe XD、Photoshopも対応予定らしいです。
　今回の記事では、Sketchとの連携を主に紹介していきます。
　
## インストール
[Overflow](https://overflow.io/)
こちらの公式ページからインストールしてください。
インストールできたら、Sketch画面の右上にプラグインアップデートのアイコンが出るので、それをクリックしてアップデートしてください。
そうすると、SketchメニューにはPluginsにOverflow sketch panelが表示されます。

![Kobito.glkAO7.png](https://qiita-image-store.s3.amazonaws.com/0/135757/8691dc0a-7a7c-ca10-77bd-2afbee56aee5.png "Kobito.glkAO7.png")

## Sketch => Overflow
 SketchのArtboardからOverflowに画面を同期します。
インストールのところで説明したPluginsのところで同期するやり方とSketch画面の右下にあるOverflowのところをクリックしても同期することができます。

![スクリーンショット_2018-07-29_6_20_45.png](https://qiita-image-store.s3.amazonaws.com/0/135757/0f93e823-8514-c2e4-dd87-0ba397e14cfb.png "スクリーンショット_2018-07-29_6_20_45.png")

同期すると下のようにSketchの各Artboardが並んで表示されます。
![Kobito.2sFLdE.png](https://qiita-image-store.s3.amazonaws.com/0/135757/d9682bb0-f5a3-26b7-4486-ca194d46baca.png "Kobito.2sFLdE.png")

## Overflowの操作

ここから実際の画面遷移図の作成ですが、基本的に矢印をつなぐのみで直感的な操作で完了します。
　遷移元のアイテムをホバーしたときに出てくる４方向の矢印のどれかから遷移先のアイテムにドラッグ＆ドロップの要領でつなげるだけです。

![Kobito.J3f0Iv.png](https://qiita-image-store.s3.amazonaws.com/0/135757/5ee41398-61ce-5862-c043-db1a24f6bf5f.png "Kobito.J3f0Iv.png")

矢印をダブルクリックすると、その線にコメントをつけることができます

![Kobito.AHIPwq.png](https://qiita-image-store.s3.amazonaws.com/0/135757/b3df2e8b-869d-9238-6392-1b29d59caeea.png "Kobito.AHIPwq.png")

また、線の種類もいくつも用意されており、カスタマイズして自作の線種を作ることも可能です。

![Kobito.qTz668.png](https://qiita-image-store.s3.amazonaws.com/0/135757/440583e5-d505-75b0-cff7-83c5eccd6b59.png "Kobito.qTz668.png")

![Kobito.gr0uMq.png](https://qiita-image-store.s3.amazonaws.com/0/135757/26de4e12-9715-475e-66b4-68c6d686d00e.png "Kobito.gr0uMq.png")

この他にもプレゼンテーションモードで画面遷移を簡単に確認できたりします！

サクッと試したい方にもおすすめです！！
Spring Boot(2系)で Redis Session使用時に同一ユーザの他のセッション一覧を取得する。またそれを破棄する。

WebSecurityConfigurerAdapter を継承したConfigクラスに下記追加。

```java
  @Bean
  public <S extends Session> SessionRegistry sessionRegistry(FindByIndexNameSessionRepository<S> sessionRepository) {
    return new SpringSessionBackedSessionRegistry<>(sessionRepository);
  }
```

生成した SessionRegistry を HttpSecurityの設定に追加する。

```java
  @Override
  protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests().antMatchers("/secure.html").authenticated().anyRequest().permitAll()
        // login settings
        .and().formLogin()
        // ligout settings
        .and().logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout", "GET"))
        // ここから追加分
        .and().sessionManagement()
        // 1ユーザあたりの許容する最大セッション数
        // -1だと無制限
        .maximumSessions(-1)
        // 複数ログアウトに使用するSessionRegistry
        .sessionRegistry(sessionRegistry(null))
        // セッション切れになった場合に遷移するURL(設定しなかった場合、その画面でエラーメッセージが出る)
        .expiredUrl("/login?logout");
  }
```

設定は以上

あとはコントローラなりサービスなりでSessionRegistryを利用して同一ユーザのセッション一覧が取れる。

下記は現在ログイン中セッションを除いた同一ユーザセッションをログアウトさせる処理の例

```java
  @Autowired
  private SessionRegistry sessionRegistry;

  @RequestMapping("/logoutAnother")
  public String logoutAnother(HttpSession currentSession) {
    String sessionId = currentSession.getId();
    Optional<Object> principal = Optional.ofNullable(SecurityContextHolder.getContext().getAuthentication())
        .map(authentication -> authentication.getPrincipal());
    if (principal.isPresent()) {
      // 現在ログインしているユーザと同一ユーザのセッション一覧を取得
      List<SessionInformation> sessions = sessionRegistry.getAllSessions(principal.get(), false);
      for (SessionInformation session : sessions) {
        if (sessionId.equals(session.getSessionId())) {
          // 現在のセッションだけはログアウトしない
          continue;
        }
        // セッション期限切れにしてログアウト
        session.expireNow();
      }
    }
    return "redirect:/";
  }
```

`sessionRegistry.getAllSessions` で第1引数に渡したユーザ情報と同じユーザのセッション一覧が取れる。

ログイン中のユーザではなく任意のユーザのセッション一覧を取りたい場合は第1引数に任意のユーザのIDを入れれば取れる。(管理者などが任意のユーザを強制ログアウトするなどを想定)

```java
    // 文字列
    List<SessionInformation> sessions = sessionRegistry.getAllSessions("user", false);

    // UserDetails: userDeails.getUsername() => "user"
    List<SessionInformation> sessions = sessionRegistry.getAllSessions(userDeails, false);

    // Principal: principal.getName() => "user"
    List<SessionInformation> sessions = sessionRegistry.getAllSessions(principal, false);
```

- 例
  - https://github.com/boushi-bird/multiple-logout-example
カラムの追加

例：ユーザーテーブルにカラムを追加する 
    カラムを追加するマイグレーションファイルの作成

$ rails g migration Addカラム名To追加先テーブル名 追加するカラム名:型

例) userの自己紹介を保存するためのカラム、introductionカラムをusersテーブルにtext型で追加

ターミナル
rails g migration AddIntroductionToUsers introduction:text
  # usersテーブルにintroductionカラムをtext型で追加するマイグレーションファイルの作成

この時、「Add」「Introduction」「To」「Users」と、単語の頭文字が大文字

　型　　　　 説明 　　　　用例
　integer   数字 　　　　ユーザーのidなど
　string    文字(少なめ) ユーザー名、パスワードなど
　text　    文字(多め) 投稿文など
　boolean   真か偽か 真偽フラグ
　datetime  日付と時刻 作成日時、更新日時など

例)booleanのときは、最初にdefault値を設定
rails g migration AddAuthorizedToEntries authorized:boolean default: false,null: false

↓
マイグレーションファイル
class AddAuthorizedToEntries < ActiveRecord::Migration
  def change
    add_column :entries, :authorized, :boolean,:default => true,:null => false
  end

userデータベースにカラムを追加する際は、
application_controller.rbにpermitの記述をする。
def configure_permitted_parameters
    devise_parameter_sanitizer.permit(:sign_up, keys: [:kind, :company, :name])　#会員登録時
    devise_parameter_sanitizer.permit(:account_update, keys: [:kind, ：name, :company, ])　#会員情報更新時
  end

end

矢印
rake db:migrate

マイグレーションファイルの実行状況の確認
rake db:migrate:status
【AWS】CloudWatchで、EC2のアイドル状態が続いたらインスタンスを停止する

開発サーバがお釈迦になり、一時的にAWSにインスタンスを立てて開発サーバにすることになった。
r4.2xlargeなので立ち上げっぱなしにしておくのももったいない。
しかし、落とすのを忘れて痛い目にあったこともあって、そういうアホらしいことは避けたい。。
というわけで、誰も使っていない状態が続いたら、自動的にインスタンスを停止する

# CloudWatchの設定

![01.png](https://qiita-image-store.s3.amazonaws.com/0/263849/dfd93350-f5f8-bfd1-3d1c-e0f7ec50d243.png)


EC2のインスタンスマネージャーで、画面下の「モニタリング」タブを選択し「アラームの作成」ボタンをクリックする。

![02.png](https://qiita-image-store.s3.amazonaws.com/0/263849/b462cc06-a715-5c6d-4b7a-d68cad5cb518.png)

アラームの作成画面が表示されるので、以下のように設定する。
・連絡先の設定：「通知の名前」とアラームの送付先のメールアドレス
・アクションを実行：　「インスタンスを停止する」にチェック
・条件：
　- 上記（CPU平均使用率が2%に満たない状態が1時間に1回発生した時）
　- アラーム名は任意に設定
以上で「アラームの作成」を押す。

![03.png](https://qiita-image-store.s3.amazonaws.com/0/263849/1fea524f-fa72-29f2-4583-d1078bcbb6e4.png)

アラームが作成されると上のようなダイアログが表示される。
送付先に設定したアドレス宛にメールが飛ぶようになっている。

![04.png](https://qiita-image-store.s3.amazonaws.com/0/263849/a48ca3b8-3827-6bf1-24fe-ddc7452000b1.png)

メールの内容はこんな感じ。「Confirm Subscription」のリンクをクリックすると以下の画面が表示される。

![05.png](https://qiita-image-store.s3.amazonaws.com/0/263849/918059cc-edde-03eb-65ba-cac5985a8f5b.png)

この画面が表示されたらConfirmしたことになり、これで設定は全て完了。

# 結果

![06.png](https://qiita-image-store.s3.amazonaws.com/0/263849/d4eafb43-d8a4-0d02-ee96-4b40906c8a74.png)

何も触らず放置したら、自動的にインスタンスは停止された。
アラームのメールも飛んできた。
とりあえずはこれで一安心。

EC2のアラームの条件は環境に応じて設定してみてね。
【図解】記事メディアをデータドリブンで改善する時の考え方をまとめてみた

# この記事について
WEBメディア(キュレーションメディア/オウンドメディアなど)をグロースする際は、データを活用した改善を行う事が有効に機能するケースが多くあります。

但し、正しい方法を知らないと、逆に誤った指標を良くする所に時間を使い過ぎてしまったり、部分最適に陥ってサービス全体をグロースできないという事態に陥ります。

本記事では、【記事メディア改善にデータを活用する方法】についてある程度、汎用性を持たせた形で解説します!小難しい話は含めていないので、ざっくりと分かるはず。

# 対象読者
- GoogleAnalyticsは取り敢えず埋まっているけど、改善への活用方法で悩んでいる方
- KGI・KPIなどメディアの目標設定でつまづいている方

# 概念編〜データ・分析の役割・限界を理解する〜
## そもそも ”データ分析”って何するもの？
<img width="919" alt="スクリーンショット 2018-07-29 16.05.30.png" src="https://qiita-image-store.s3.amazonaws.com/0/56466/c6c694d9-1acb-00ed-e568-6baa4f9322f8.png">


- 記事メディアの改善という文脈では、行った施策の評価を行う1つのツールである。位の割り切り具合で考えます。重要なのは、Actionのみで、得た知見を元にどれだけ実際の改善施策を実施できたかが重要!

- 現状把握用途で、行う日次や週次のレポートも、あくまで目標と現実のギャップを明らかにし、何らかの対応策をActionするために作成している意識が肝心なのでは!


## メディアのデータ活用ステップ
<img width="921" alt="スクリーンショット 2018-07-29 16.46.04.png" src="https://qiita-image-store.s3.amazonaws.com/0/56466/844290f2-a014-fbfd-1b55-6b4d3d000b90.png">

- 1.安定して記事をデリバリーできる体力がある
- 2.記事供給の体制がある上で、目指すべき目標が決まっている
- 3.データを有効に活用できるステップ

## メディアのカイゼンは２つに分けて考える
<img width="1038" alt="スクリーンショット 2018-07-29 16.05.36.png" src="https://qiita-image-store.s3.amazonaws.com/0/56466/39796705-2018-9d09-acb2-e87486e95ead.png">

- 大きく分けると①記事コンテンツ自体の改善 と ②メディア全体での改善 の2つに分かれるので、どちらかに偏っていないか、バランスを取りながら、改善を行う。
    - ①記事コンテンツ自体の改善
        - 例)
            - 適切なSEOキーワードの使い方
            - 読了率の高くなる文字量構成
            - SNSシェア率の高いアイキャッチ画像の探求
            - ページングの有無 ...etc
    - ②メディア全体での改善
        - 例)
        - 記事本数
        - CVボタンのデザイン調整
        - 回遊性向上のためのサイトデザイン
        - シェアボタンのスタイル ...etc

## KGIとKPIの関係性
<img width="807" alt="スクリーンショット 2018-07-29 16.43.04.png" src="https://qiita-image-store.s3.amazonaws.com/0/56466/20d86a81-fa6c-c52c-6047-48a936310a6e.png">


- そもそもの実現したい事があり、それが数値(KGI)に落ちる。KGIは実際の現場ではあまり意識することはなく、KPIを目標にゴリゴリ改善をすることで、結果的に達成される関係性。


- KGIが決まれば、ウォッチすべきKPIはほぼ自動的に決まるので、まずはKGIを定める事が重要。
    - (例)ページビューをKGIとした場合のKPI候補
        - 各種SNSからの流入数 
        - SEO流入数
        - 他記事からの回遊流入量

- 各指標毎にPDCAが紐づいていて、それぞれを改善していくようなイメージ


# 実践編〜カイゼンサイクルはどうやって回す?〜
## 仮にFBページのいいねをカイゼンしようとしてみる
<img width="907" alt="スクリーンショット 2018-07-29 16.07.48.png" src="https://qiita-image-store.s3.amazonaws.com/0/56466/b208fd86-3804-c845-22c2-9793f7637d17.png">

## カイゼン量＝サイクル数＊カイゼン率
<img width="1025" alt="スクリーンショット 2018-07-29 16.07.57.png" src="https://qiita-image-store.s3.amazonaws.com/0/56466/0726f9d1-8106-2c2f-35f2-231181d121dc.png">

- 改善を最速で回していくためには。とにかく数をこなして、打席に立つ事が重要。打率5割で1回施策を打つ<打率1割で5回施策を打つ。スピード感を保ちつつ、施策の数でリテラシーを上げながら、クオリティを高めていく

- KPIの絶対値だけでは、良いかどうか分からない。前提条件が揃っている、どうメディア内の別記事を参考に、アップダウンを決めるのがおすすめ。もしくは、[Google Optimize](https://marketingplatform.google.com/about/optimize/)などのABテストツールを併用する事で、スピードを高める事ができる。
migration時のreferencesで作成されるindex nameを変更したい [Rails]

## 経緯

Railsで外部キー制約をつけるために以下のようなmigrationコードを組んだが

```ruby

create_table :all_you_can_drink_course_shops do |t|
  t.references :all_you_can_drink_course, null: false, foreign_key: true
  t.references :shop,                     null: false, foreign_key: true
  t.timestamps
end

```

自動生成されるindexの名前が長すぎて弾かれる

```
Index name 'index_all_you_can_drink_course_shops_on_all_you_can_drink_course_id' on table 'all_you_can_drink_course_shops' is too long; the limit is 63 characters
```

## 解決作

indexのパラメータにネストする形で、index の名前を帰れるようです

```ruby
create_table :all_you_can_drink_course_shops do |t|
  t.references :all_you_can_drink_course, index: { name: 'idx_a_y_c_d_course_shops_on_all_you_can_drink_course_id' }, null: false, foreign_key: true
  t.references :shop,                     null: false, foreign_key: true
  t.timestamps
end

```


参考
[migrations: t.references doesn't allow index name to be specified](https://stackoverflow.com/questions/28727240/migrations-t-references-doesnt-allow-index-name-to-be-specified)
AWS Batch で使う EC2 インスタンスのストレージ容量を増やす

# 何が起こったか
AWS Batchでやってた、数GBの動画ファイルのフォーマット変換処理が、EC2 インスタンスのディスク容量不足が原因で、失敗する事態に。

# 調べてみた
標準のAMIだと、Dockerコンテナに割り当てられるディスクは、10GBが既定らしい。

参考：[How do I increase the default 10 GiB storage limit with Docker container volumes for ECS?](https://aws.amazon.com/jp/premiumsupport/knowledge-center/increase-default-ecs-docker-limit/)

答えもここに書いてある。例えば、20GBにしたかったら、

```
#cloud-boothook
#!/bin/bash

cloud-init-per once docker_options echo 'OPTIONS="${OPTIONS} --storage-opt dm.basesize=20G"' >> /etc/sysconfig/docker
```

と書け、と。

・・・、どこに？ 

# やったこと
## ディスクを拡張したECインスタンスをつくる
どうやら、AWS Batch(or ECS)標準で使われるAMIを拡張する必要があるらしい。
標準のAMIは、"Amazon ECS-Optimized Amazon Linux"というらしい。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/90361/62e9580d-9db6-183a-b0ef-033a72e236d5.png)

なので、一度このAMIを使って、EC2インスタンスを作る。
この時、ユーザーデータにさっきのbashスクリプトを書いておいて、実際のディスク容量も増やしておく。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/90361/4c4ef188-7fac-d54c-8af9-e2b158ff739d.png)
すると、Dockerコンテナが使えるディスク容量が増えた状態で、EC2インスタンスが立ち上がる。

## AMIを作る
このEC2インスタンスでやる作業はないので、シャットダウンして、これをベースにAMIを作る。
AMIの作成は、コンソールのメニューから、選択するだけ。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/90361/b6e55934-4b16-6022-882d-7b4e4bb0907e.png)
AMIのIDは後から使うので覚えておく。

## Batch用コンピューティング環境を作る
最後に、AWS Batchで使うコンピューティング環境作成時に、作成したAMIのIDを指定する。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/90361/07808def-252b-84a6-d93a-0259b34fc0c5.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/90361/a5881fdc-66ca-776a-78a6-9e79c67c7a6d.png)

これで、Batch実行時にディスク容量を増加したAMIをベースに、ECSの仮想マシンが起動するので、数GBクラスのデータの一次利用にも耐えられる。
Github Gistの良いところ、悪いところ

# [Gist](https://gist.github.com/) 使ってますか？
Gistとはコード断片の共有サービス。

Qiitaでも記事投稿時の共有先に組み込まれているけど、あまり活用している人を見かけたことはない。というか全然ない。

特にインターフェイスが優れているわけではないし、ソーシャルサービスでもないし、レポジトリ管理の方法はドキュメントにさえ書かれていないし、なんだかんだと微妙な感じはある。

だが工夫次第では活用方法はあるはず。僕は好きです。嫌いじゃないです。

# 良いところ

- とにかく手軽にコード公開、ファイル公開が出来る
- 1個のGistがレポジトリとして管理されている (つまりcloneやpushが出来る)
- (本来はファイル共有サービスではあるが) markdownファイルを使って、何かコンテンツを書くことも出来る 
- GistのURLをそのまま貼り付けることで、[Mediumなどのサービスでの埋め込み](https://medium.com/supersonic-generation/github-gist-manage-in-one-repository-many-gists-by-using-git-submodule-a052b532e6a6)が可能
  - 「記事としてはMediumのような外部サービスに書くけれど、その実体はGistに存在する」というような運用が可能
- Githubのサービスなのでコードとの親和性が高い
- Githubのサービスなので、サービス継続性に、他のサービスよりも安心感がある (無くなりませんように…)

## MediumにGistを埋め込んだ例
 
![image.png](https://qiita-image-store.s3.amazonaws.com/0/89618/c1cb9167-50ff-d02e-4467-d3b5eb22ede8.png)

# 悪いところ

- Githubにあるようなプレビュー機能、画像アップロード機能などは使えない (コメント欄では可能)
- ソーシャル性がほとんどない
  - 「いいね」がつかない
  - コメント欄があるぐらい
- 1個のGistに1個のレポジトリが割り振られるので、複数のGistを作ると、レポジトリが分散されてしまう
- URLに好きな名前が付けられない、自動的に専用のハッシュが割り振られる
- 1個のGistに複数のファイルを置いた場合、表示の順序は決められない
  - Gistの正体は実はレポジトリなので当然だとも言える
  - 現状はファイル名でソートされていそうなので、見てほしい順にファイル名を付けるという裏技もある ( `00_README.md` `01_example.go` など )
- Gist1個あたりのURLは割り振られるが、ファイル1個あたりのURLは割り振られない様子
  - もしこれが出来たら、外部サービスでの共有がよりやりやすくなるんだけど

# あわせて読みたい

- [Gist を1個のレポジトリでまとめて管理する ( git submodule を利用 ) - Qiita](https://qiita.com/YumaInaura/items/8088aae8df7ffac482b9)
- [Github Gist に手元から push する - Qiita](https://qiita.com/YumaInaura/items/b1377bb69947a5707fb0)








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
Vue.jsのコンポーネントに型指定をして値をbindする

# はじめに

[前回の記事](https://qiita.com/FrozenVoice/items/f8df3e4ec0c633b4221e)では結果内容をまるごとそのままコンポーネントに渡していました。
中身が保証出来ていないのはよろしくないので、個別かつ型の指定をしてみます。

## コンポーネント

```javascript:item.js
var ItemComponent = Vue.extend({
    template:
        '<div class="item">' +
            '<div>ID: {{id}}</div>' +
            '<div>名前: {{name}}</div>' +
            '<div>値: {{value}}</div>' +
        '</div>',
    props: {
       id: Number,
       name: String,
       value: Number
    }
})
```

## HTML

```html
<div class="itemContainer">
    <item-component
        v-for="(result, index) in results" :key="index"
        v-bind:id="result.id"
        v-bind:name="result.name"
        v-bind:value="result.value"
    >
    </item-component>
</div>
```

## 型が異なるデータを表示

ブラウザ上は表示出来ていますが、

|![06.png](https://qiita-image-store.s3.amazonaws.com/0/165884/b51edfd4-80b0-b5ab-cca5-18ea0d75d0b3.png)|
|:-:|


開発者ツールのコンソールにはWarningとしてメッセージが出ています。

|![07.png](https://qiita-image-store.s3.amazonaws.com/0/165884/b22b4d0c-bf4a-b4d5-843a-91691be6a40c.png)|
|:-:|
指定の時間まで待機するpythonプログラム

## 目的・動機
pythonでプログラムを書いていて、
*ある時間より後だったら何もしない、前だったらその時間まで "待機する"*
みたいなプログラムが書きたかった。
ググってみたが意外と情報がなかったため、メモとして投稿。

## プログラム
全体を以下に示す。
細かい部分の説明は後述。
モジュールの説明は省略。

```python:xxx.py
from datetime import datetime, timedelta
import sched
import time


def def1(name):
    print name


now = datetime.now()
now = datetime(now.year, now.month, now.day, now.hour, now.minute, 0)
comp = datetime(now.year, now.month, now.day, now.hour, 30)
diff = comp - now

if int(diff.days) >= 0:
    scheduler = sched.scheduler(time.time, time.sleep)
    scheduler.enter(diff.seconds, 1, def1, ("hoge", ))
    scheduler.run()
else:
    print "do nothing"
```

## プログラム実行例
例1
プログラム実行日時 : 2018/07/29 16:25:00
指定時刻 : 2018/07/29 16:30:00
実行結果 : 16:30:00まで待機して、”hoge” 出力

例2
プログラム実行日時 : 2018/07/29 16:25:00
指定時刻 : 2018/07/29 16:20:00
実行結果 : 何もせずプログラム終了

### ある時間と現在の時刻の差分取得
1行目で現在の日時の取得。
変数`now` の小数点がそのままだとあとあと処理がやりづらくなるため、2行目で秒を0に変更。
3行目で同日同時間30分の日時情報を取得。
4行目で差分を計算。

```py
now = datetime.now()
now = datetime(now.year, now.month, now.day, now.hour, now.minute, 0)
comp = datetime(now.year, now.month, now.day, now.hour, 30)
diff = comp - now
```

### 現在時刻がある時間より前か後かで条件分岐
`if` が前だった場合
指定時刻まで待機して関数`def1` を実行。待機する時間は`diff.seconds` が指定してくれる。
`else` が後だった場合
サンプルプログラムでは特に何も実行しない。

```py
if int(diff.days) >= 0:
    scheduler = sched.scheduler(time.time, time.sleep)
    scheduler.enter(diff.seconds, 1, def1, ("hoge", ))
    scheduler.run()
else:
    print "do nothing"
```

## あとがき
他にこんな書き方できるよとか、ここの処理がまずいなどの意見がありましたら、遠慮せず言ってください。
CentOSの初期構築時に使用するコマンドや作業のメモ

# 前置き
自分がCentOSの初期構築時に使用する、便利なコマンドや作業のメモです。
環境はCentOS7.4を前提としています。

# 初期構築時に使用するコマンドや作業
## grub2関連
起動時のパラメータを確認する時は`/proc/cmdline`を参照。
GUI画面が見切れる場合は以下を追加する。
`vga=773`
※1024*768 8bitカラーで表示する設定

## SElinux
`getenforce`
状態確認
`setenforce 0`
一時無効化
永続的に無効化する場合は`/etc/selinux/config`で`SELINUX=disabled`と修正する。起動時に無効化したい場合は、grub2画面でkernel起動オプションに`selinux=0`を追加する

## firewalld
`firewall-cmd --list-all`
リストを表示

`firewall-cmd --add-service=http`
`firewall-cmd --add-port=xxx/tcp`
即ルールに追加(メモリ上にのみ反映。再起動すると消える。)

`firewall-cmd --remove-service=http`
削除(メモリ上のみ)

`firewall-cmd --runtime-to-permanent`
メモリ上のルールを設定ファイルに反映する。

`firewall-cmd --reload`
再起動

## yumコマンド
`yum info [パッケージ名]`
パッケージの表示

`yum install [パッケージ名]`
パッケージのインストール

`yum grouplist`
グループリストの表示。
現在導入しているグループリストの確認も可能。

`yum provides [ファイル名]`
[ファイル名]が含まれるパッケージを表示。
コマンドがインストールされていない時にどのパッケージに含まれているか確認する時に便利。
キーワード検索をしたい場合は、`yum search [キーワード]`を使う。

## 良く使うパッケージ
`bind-utils`
digやnslookupコマンドを含む。BINDをインストールする時は必須。

`nfs-utils`
NFSを利用する時に必要。

## ジャーナルログを永続化する
ジャーナルログはデフォルトだと/run/log/journalに保管され、再起動時に削除されてしまう。永続化する場合は、以下のコマンドで保管ディレクトリを作成して、journaldを再起動する。
`mkdir /var/log/journal`
`systemctl restart systemd-journald`
または、/etc/systemd/journald.confの設定に以下の修正を行ってからjournaldを再起動する。
`Storage=persistent`

# あとがき
他にも思いついたら、随時更新する予定です。
CSSでテキストを1文字ずつ回転させる

# はじめに
CSSでは `transform: rotate()` を使用することで特定の領域を回転させることが可能です。この記事では、 `rotate` を使用して次のように定義された文字を1文字ずつ回転させる方法について紹介します。

```html:html
<div class="rotate">
  <span>ま</span>
  <span>わ</span>
  <span>る</span>
  <span>よ</span>
</div>
```

# 1文字ずつ同じ方向に回転させる
ブロック内の文字を1文字ずつ回転させる場合、次のようにCSSを定義します。



```css:css
.rotate span {
  display: inline-block;
  transform: rotate(50deg)
}
```

### 実行例

<p data-height="265" data-theme-id="0" data-slug-hash="BPmrBW" data-default-tab="html,result" data-user="Tsuyoshi84" data-pen-title="rotate-char-one-by-one-1" class="codepen">See the Pen <a href="https://codepen.io/Tsuyoshi84/pen/BPmrBW/">rotate-char-one-by-one-1</a> by Tsuyoshi Yamaguchi (<a href="https://codepen.io/Tsuyoshi84">@Tsuyoshi84</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

# 交互に左右別方向へと回転させる
テキストの各文字を交互に別方向へと回転させる場合、次のように `nth-child(even)` 、 `nth-child(odd)` を使用します。

```css:css
.rotate span {
  display: inline-block;
}

.rotate span:nth-child(even) {
  transform: rotate(50deg);
}

.rotate span:nth-child(odd) {
  transform: rotate(-50deg);
}
```

### 実行例

<p data-height="265" data-theme-id="0" data-slug-hash="LBOdEP" data-default-tab="css,result" data-user="Tsuyoshi84" data-pen-title="rotate-char-one-by-one-2" class="codepen">See the Pen <a href="https://codepen.io/Tsuyoshi84/pen/LBOdEP/">rotate-char-one-by-one-2</a> by Tsuyoshi Yamaguchi (<a href="https://codepen.io/Tsuyoshi84">@Tsuyoshi84</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

# アニメーションで回転させる
アニメーションを使用して文字を回転させる場合、次のように `animation` と `keyframes` を利用します。

```css:css
.rotate span {
  display: inline-block;
  animation: rotate-anime 2s ease-in-out infinite;
}

@keyframes rotate-anime {
 100%{ transform: rotate(360deg) }
}

```

### 実行例

<p data-height="265" data-theme-id="0" data-slug-hash="KByozR" data-default-tab="css,result" data-user="Tsuyoshi84" data-pen-title="rotate-char-one-by-one-3" class="codepen">See the Pen <a href="https://codepen.io/Tsuyoshi84/pen/KByozR/">rotate-char-one-by-one-3</a> by Tsuyoshi Yamaguchi (<a href="https://codepen.io/Tsuyoshi84">@Tsuyoshi84</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>
# 参考
https://webparts.cman.jp/string/roll/
Azure Machine Learning StudioのPython Scriptで外部パッケージを使う方法

Azure Machine Learning StudioのPython Scriptは、通常ではAnacondaに標準で入っているパッケージしか使うことができませんが、Anacondaにない外部のパッケージを用いる方法があります。

こちらの記事を参考にしました。
https://blogs.technet.microsoft.com/machinelearning/2016/10/12/deep-neural-network-in-azure/

## ローカル環境での作業

MacまたはLinux環境を想定しています。

適当な場所で、適当なディレクトリを作成。今回は`bundle`とします。
作成したディレクトリの`lib`に、使いたいパッケージをインストール。

```
mkdir bundle
pip install --no-deps --target=bundle/lib [package_name]
```

`bundle`のzipを作成します。

```
zip bundle.zip -r bundle
```

## Azure Machine Leaning Studioでの作業

ローカルで作成したzipをdatasetsにアップロード。
フッターバーの+NEW -> DATASET -> FROM LOCAL FILE からアップロードできます。

アップロードされたら適当なexperimentを開いて、Execute Python Scriptモジュールを配置。
そして、アップロードしたzipのdatasetモジュールを配置して、2つのモジュールを結合。

<img width="500" alt="Experiments_-_Microsoft_Azure_Machine_Learning_Studio.png" src="https://qiita-image-store.s3.amazonaws.com/0/254436/c8da1cf1-1570-aea1-3fe1-25cc9aa6277f.png">

Execute Python Scriptを選択して、モジュールのスクリプトに以下のコードを追加。
今回はモジュールのPython Versionは`Anaconda 4.0/Python 3.5`を想定しています。

```
import os, pkg_resources

BUNDLE_DIR = os.path.join(os.getcwd(), "Script Bundle", "bundle")
LIB_DIR = os.path.join(BUNDLE_DIR, "lib")
env = pkg_resources.Environment([LIB_DIR])
packageList, errorList = pkg_resources.working_set.find_plugins(env)
for package in packageList:
    print("Adding", package)
    pkg_resources.working_set.add(package)
for error in errorList:
    print("Error", error)
```

このコード以下より、パッケージをimportして使うことができます。
【第２回】超初心者が書くSAPについてのメモ　〜モジュール〜

# **モジュール**

SAP ERPパッケージにはモジュールという機能の塊があります。
例えば、企業の活動として、
1. 買う
2. 作る
3. 売る
4. 1~3で発生したお金の管理
があると思います。(かなり大雑把ですが)
SAP ERPパッケージにはモジュールという機能の塊を作り、分離、連携させ
これらの管理を実現しています。

# **主要なモジュール**

SAP ERPで主要なモジュールをいくつか挙げたいと思います。

| モジュール名       |    Center align    |
|:-----------------|:------------------:|
| MM               |     在庫管理         |
| PP               |     生産管理         |
| FI               |     財務管理         |
| CO               |     管理会計         |
| PS               |     プロジェクト管理  |
| HR               |     人事管理         |
| PM               |     プラント保全     |


主要なものはこれくらいですかね・・・。
まだまだたくさんあります。


# **リンク集**

[SAP モジュール一覧](http://seesaawiki.jp/w/chocolate_mousse/d/SAP%A5%E2%A5%B8%A5%E5%A1%BC%A5%EB%B0%EC%CD%F7)

[SAP ERP -経営改革基盤-](http://www.softes.co.jp/product/erp/) //すごく分かりやすくまとまっています。
ns-3構築を爆速で終わらせるためのシェルスクリプト

ns-3.28をUbuntuに一気に入れてしまいたいのでシェルスクリプトを書いてみた。
動作環境 Ubuntu 16.04 or Ubuntu 17.10

```sh:ns3.sh
#!/bin/sh

sudo apt install gcc g++
sudo apt install python python-dev
sudo apt install mercurial python-setuptools git
sudo apt install qt4-dev-tools libqt4-dev
sudo apt install cmake libc6-dev libc6-dev-i386 g++-multilib
sudo apt install gdb valgrind
sudo apt install gsl-bin libgsl2 libgsl-dev
sudo apt install flex bison libfl-dev
sudo apt install tcpdump
sudo apt install sqlite sqlite3 libsqlite3-dev
sudo apt install libxml2 libxml2-dev
sudo apt install libgtk2.0-0 libgtk2.0-dev
sudo apt install vtun lxc
sudo apt install uncrustify
sudo apt install doxygen graphviz imagemagick
sudo apt install texlive texlive-extra-utils texlive-latex-extra texlive-font-utils texlive-lang-portuguese dvipng
sudo apt install python-sphinx dia
sudo apt install python-pygraphviz python-kiwi python-pygoocanvas libgoocanvas-dev ipython
sudo apt install libboost-signals-dev libboost-filesystem-dev
sudo apt install openmpi-bin openmpi-common openmpi-doc libopenmpi-dev
cd ~
wget http://www.nsnam.org/release/ns-allinone-3.28.tar.bz2
tar xjf ns-allinone-3.28.tar.bz2
cd ns-allinone-3.28/ns-3.28
./waf distclean
./waf configure --enable-sudo -d optimized
#enable-sudoはビルドしたものに管理者権限を与えるようにするオプション
#-d optimizedはそのマシン用に最適化するオプション
#サンプルコードもビルドしたければ--enable-exmamples
#テストコードもビルドしたければ--enable-tests
./waf
```

適宜編集して使ってください。
ちなみにUbuntu18.04ではpython-pygoocanvasを入れることが出来ないので、--vizオプションでPyVizが使えません。トポロジを可視化出来なくても良いならUbuntu18.04でも動かせると思います。
JavaScriptのディスクリプタを使い、堅牢なオブジェクトやObservableなオブジェクトを作る

## ディスクリプタって？

たとえば、

```javascript
let obj = { name: 'taro' }
Object.defineProperty(obj, 'age', {
  value: 100,
  writable: false
})
```

この第三引数をdescriptorという。

プロパティを細かく制御することができ、その制御モードを指示するオブジェクトのことをさす。

discriptorには2つタイプがある。

#### 1. データディスクリプタ
value(, writable)をもつdiscriptor

```javascript
{
    value: 123,         
    writable: false
    enumerable: false,
    configurable: false 
}
```

#### 2. アクセサディスクリプタ
get, setをともにもつdiscriptor

```javascript
{
    get: () => { return hoge },
    set: (val) => { hoge = val },
    enumerable: false,
    configurable: false
}
```

enumerableとconfigurableはともに持つことができる。
一方例えばvalueをもつときにget or setをもつとエラー。逆もしかり。


## 普通のattributes代入とどう違うか
`obj.hoge = 120` はこれのショートハンド。
この場合は `{value: 120, writable: true, configurable: true, enumerable: true}` でセットされたことになる


## 何が嬉しいか
- imutableな属性を作るなど堅牢性を増すことができる。
- setterを使ってobservableなオブジェクトを作れる

では作ってみる

## 堅牢性をましたオブジェクトを作る
シンプルにwritableをfalseにする。

```javascript
let obj = {}
Object.defineProperty(obj, 'age', {
  value: 100,
  writable: false,
  enumerable: false,   // false: for (let prop in obj) で age を列挙対象にしない
  configurable: false  // false: ディスクリプタを変更可能としない
})

console.log(obj.age) // 100
obj.age = 1000
console.log(obj.age) // 100 ... 変わらない
```

setterいじってもいいかもしれないが、 `writable: false` が楽

## observableなオブジェクトを作る
(通知しすぎない(changedの検知), バリデーションなどは省略しました)

```javascript
let obj = {}
let _age = 0
Object.defineProperty(obj, 'age', {
  get () { return _age },
  set (newValue) { 
    _age = newValue
    this.noticeObservers() // setしたらリスナーに通知
  },
  enumerable: false, 
  configurable: false
})

// observerの登録と通知
let listenerA = {}
listenerA.update = (observable) => {
  // 通知を受けたらなにかする
  console.log(`listerA received notification $(observable.age) from!`)
}
obj.observers = [listernA]

obj.noticeObservers = () => {
  this.observers.forEach((listener, _idx) => {
    listener.update(obj)
  })
}
```

## 関連
- Object.defineProperty / Object.defineProperties
- Object.create
- Proxy
    - https://issus.me/projects/100/issues/83

このProxyを使うとより柔軟にオブジェクトに対する処理に、任意の処理を挟み込める。

## ref
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty

なぜか definePropertyのページにdiscriptorの説明が載っている。

このあたりをより発展させたProxyについては https://aloerina01.github.io/blog/2017-03-14-1 こちらが詳しくて助かった。
Github Gist を1個のレポジトリでまとめて管理する ( git submodule を利用 )

Gistはお手軽にコードが書けて、なおかつレポジトリ管理も出来てなかなか便利だ。

だが欠点もある。

- レポジトリがバラバラになってしまう
- URLに自動的にハッシュが割り振られるので、名前を思い出しにくい

そこで通常のGithubレポジトリでまとめてGistを管理してみる。

# Githubに集約用レポジトリを作成

例:

https://github.com/YumaInaura/gist

# Gistを作成する

Webから作成。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/89618/85ad3745-def0-4a1c-ea8d-cee787b91702.png)

割り振られたURLの例:

https://gist.github.com/YumaInaura/8d52e73dac7dc361745bf568c3c4ba37

# 集約用レポジトリに submoduleとして追加する

コマンド:

```
git submodule add [GistのURL] [好きなディレクトリ名]
```

例:

```
git submodule add https://gist.github.com/YumaInaura/8d52e73dac7dc361745bf568c3c4ba37 understandhing_channel_buffer
```

ここでディレクトリに好きな名前を付けておくと、思い出しやすいと思う。

( 手元からpushも出来るようにする場合はこちらを参照 — [Github Gist に手元から push する - Qiita](https://qiita.com/YumaInaura/items/b1377bb69947a5707fb0) )

# 集約用レポジトリにpushする

これでsubmoduleで管理された状態が、本体のレポジトリに反映される。

# Githubでの見え方

集約用レポジトリからGistへのリンクが貼られているのが分かる

![image.png](https://qiita-image-store.s3.amazonaws.com/0/89618/dc180050-3252-e17e-261d-2f50d419dea4.png)

リンク先はGistだ

![image.png](https://qiita-image-store.s3.amazonaws.com/0/89618/a87df0a8-d8fe-bf75-6553-c6be6d77b46f.png)

ページ例: 

https://github.com/YumaInaura/gist/tree/master/go

# 集約用のレポジトリをcloneする

`--recurse-submodules` オプションを付けると、submodule分まで全て手元に持ってきてくれる。

例:

```
git clone --recurse-submodules https://github.com/YumaInaura/gist
```

submoduleの数が多くなるとすごいclone数が発生しそうだが、それはそれでまた困った時に考える。








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
モンテカルロ木探索の結果の利用方法

# はじめに
モンテカルロ木探索で、UCTアルゴリズムなどを実行した結果の利用方法について記述します。

# 利用方法
モンテカルロ木探索を実行すると、その結果として、ある状態$s$に対して、それぞれの行動$a$に対応した試行回数が得られます。[AlphaGo Zero](https://deepmind.com/blog/alphago-zero-learning-scratch/)の強化学習では、シミュレーションで訪問した回数を$N(s,a)$と表記しているため、それに合わせて試行回数$N(s,a)$と表記します。

UCTアルゴリズムなどを使用すると、有望な手ほど多く試行する(期待値の高い行動を、より多く選ぶ)ため、試行回数$N(s,a)$の大きさが、そのまま行動$a$の有望さの度合いとなります。

これを確率分布として利用する方法は「最強囲碁AI アルファ碁 解体新書」[増補改訂版](https://www.amazon.co.jp/dp/4798157775/)の268ページと269ページに、以下の数式とともに、わかりやすく例示がなされています。

$$ \pi_a = \frac{{N(s,a)}^{1/\gamma}}{\sum_a {N(s,a)}^{1/\gamma}}$$

この$\gamma$は温度パラメータで、$\gamma = 1$とすると、試行回数$N(s,a)$に比例した方策$\pi_a$となります。また$\gamma \rightarrow 0$とすれば、試行回数$N(s,a)$が最大となった行動$a$が常に選ばれる方策$\pi_a$となります。

教師あり学習のデータとして利用する場合、まずは$\gamma = 1$で計算した確率分布を訓練データとして使用してみるのが、一番よさそうに思えます。
Clova Friends mini ドラえもんver.開封の儀

LINEが提供する音声AIアシスタントClovaが搭載されているスマートスピーカーのうち、Clova Friends mini からドラえもんバージョンが数量限定で発売されました！
開封してアプリで認識するところまで実施しましたのでまとめます。

[LINE Clova 公式サイト](https://clova.line.me/)

[Clova Developer Center β](https://clova-developers.line.me/)

「Clova Extensions Kit」についてのプレスリリース
[【LINE Clova】プラットフォームのオープン化を発表 「Clova」のスキルを開発・拡張できる 「Clova Extensions Kit」を7月中に一般公開](https://linecorp.com/ja/pr/news/ja/2018/2247)


さて開封します！

**外箱**
白い箱に入っています。
![draemon_box.jpg](https://qiita-image-store.s3.amazonaws.com/0/79466/fc3495a0-278e-4488-615e-0c4194b8ee27.jpeg)

**開封**
実物がこちら。四次元ポケットについてランプが光ります
（小さいドラえもんはスタッフ私物です）
![38020917_10155752898643325_5427818238044012544_n.jpg](https://qiita-image-store.s3.amazonaws.com/0/79466/b7a9e269-9dc8-7d84-2d18-983f2c73417a.jpeg)

**Clovaアプリと接続**
Clovaアプリをダウンロードして開くと、デバイスが検出されました。
デバイス名が「DORAEMON」！
<img width="320" alt="draemon_app_02.png" src="https://qiita-image-store.s3.amazonaws.com/0/79466/16c6e384-975e-4b0d-ca8e-128a527f2574.png">

接続します。
<img width="320" alt="draemon_app_01.png" src="https://qiita-image-store.s3.amazonaws.com/0/79466/7dc47a6c-4f52-b921-bfb0-4ddb3e0d0ce4.png">

**話しかける方法**
「ねえ Clova ドラえもんにかわって」と話しかけると、会話することができます。


**サイズの違い**
ドラえもんver.はClova Frineds miniなので、
Clova Frineds（miniではない方）より少し小さいです。
![clovafriendsmini_size.jpg](https://qiita-image-store.s3.amazonaws.com/0/79466/2aa2b67d-40ea-9788-8ce7-1f109298dbc0.jpeg)

**価格の違い**
Clova Friends + カバーセット 8,640円(税込)
Clova Friends mini  5,400円(税込)
void(0)とundefinedの使い分け

Vueのソースコードを読んでいるとこんな箇所があった。

```javascript
var createEmptyVNode = function (text) {
  if ( text === void 0 ) text = '';

  var node = new VNode();
  node.text = text;
  node.isComment = true;
  return node
};
```


この2行目の条件文のところで登場する `void 0`。
これまでふわっとした理解だったのでおさらいした。


## void expression / void(expression)
voidはjavascript組み込みの**演算子**(関数ではない)で、
与えられた式が何であろうとundefinedを返す。

> この演算子は、「戻り値が undefined であってほしい場所に、それ以外の戻り値を持つ式を挿入したい場合」に有用です。
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/void

とのことだけど、実際はundefinedの代わりとして使われることが多数である。

## なぜundefinedの代わりに使うのか？
jsではundefinedは値であり、すなわち上書きができる。そのため代わりとして、voidが使われる。

```javascript:example
console.log(a === undefined) // true
console.log(a === void 0)    // true

// undefinedをうわがく
var undefined = 100

console.log(a === undefined) // false
console.log(a === void 0)    // true
```

なるほど。

## NOTICE
が、今どきのブラウザではもう書き込み不可なので安心。undefined使ったほうがわかりやすいのでそっちを使おう。

> モダンブラウザ (JavaScript 1.8.5 / Firefox 4 以降) での undefined は、ECMAScript 5 仕様により、設定不可、書込不可のプロパティとなります。
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/undefined

## ref
https://issus.me/projects/100/issues/86
スクラムマスターの役割

- スクラム開発の活動を守る人。内部からの崩壊だけでなく、外部からの障害からも守る。
- チームメンバーがスクラム活動を理解しているか、守っているかチェックする人
- メンバーが、自律的な活動を通して、成果を出せるように、アシストする人

https://www.youtube.com/watch?v=NcWDx-XXISY
Numpy基本操作メモ

#Numpy基本操作メモ
基本的な操作メモ．

```py

import numpy as np
data = [[1,2,4],[2,1,2]]
d1 = np.array(data)
ndim = d1.ndim              #次元数チェック
nsiz = d1.shape             #サイズ(matlabでのsize())
d2 = np.zeros([2,3])        #２行3列ゼロ行列    
d3 = np.eye(3,3)            #3行単位行列
d4 = np.arange(6)           #0-7までの連続数字
d5 = d4.reshape((2,3))      #2行3列の行列に直す
d1 = d1.T                   #d1を転置し，3行2列に
d6 = np.dot(d1,d5)          #d1とd5の行列積
```

#線形代数
Numpyで逆行列を求めてみる．

```py

import numpy as np
from numpy.linalg import inv
data = [[1,2],[2,3]]
d1 = np.array(data)
d8 = inv(d1)                #逆行列算出
d9 = np.dot(d1,d8)          #行列積
```
d9の結果は以下の様になる．
![image.png](https://qiita-image-store.s3.amazonaws.com/0/267311/1757c2cb-227d-0ea0-32bc-9ec1c5644251.png)
[AutoHotKey]Chrome-urlsを入力する


`Chrome://quit`とかのChrome-urlsを簡単に入力したかった。
ホットストリングでブックマーク呼び出し的なこと。

アクティブウィンドウがChrome（系ブラウザ）なら、Ctrl+Lでアドレスバーに移動してから文字列をペーストする。
Chromeかどうかはウィンドウクラスと実行ファイル名の両方で判断する。Visual Studio Codeとかもウィンドウクラスが`Chrome_WidgetWin_1`なので。

```Chrome-urls.ahk
::cu:: ; Chrome-urls
    IfChrome()
    PasteString("Chrome://")
    Return

::cuq:: ; quit
    IfChrome()
    PasteString("Chrome://quit")
    Return

::cur:: ; restart
    IfChrome()
    PasteString("Chrome://restart")
    Return

::cuc:: ; 閲覧履歴データを消去する
    IfChrome()
    PasteString("chrome://settings/clearBrowserData")
    Return

IfChrome() {
    if ("Chrome_WidgetWin_1" = WinGetClass() and (("Chrome.exe" = WinGet_ProcessName()) or ("Kinza.exe" = WinGet_ProcessName())))
    {
        Send, ^l
    }
}
WinGetClass(WinTitle="A") {
    WinGetClass, OutputVar, %WinTitle%
    Return, OutputVar
}
WinGet_ProcessName(WinTitle="A") {
    WinGet, OutputVar, ProcessName, %WinTitle%
    Return, OutputVar
}
PasteString(String)
{
    OnClipboardChange("ClipChanged",0)
    Backup := ClipboardAll
    Clipboard := String
    Sleep, 100 ; 削除が間に合わないので
    SendPlay, ^v
    Clipboard := Backup
    OnClipboardChange("ClipChanged",1)
}
```
エディタ・ショートカット

#ショートカット一覧
###command + F 検索
###command + S 保存
###ターミナル code .　　VSCODEで該当フォルダを開く
###command + ]  行にインデントを追加(いちいち行頭をクリックしなくていいから便利)
###command + [  行にインデントを削除(同上)
###command + ↑  ファイルの最初へ
###command + ↓  ファイルの最後へ
###command + ↑ + ENTER 上に行追加
###command + U  カーソル操作のUNDO
###command + 1  分割した左のエディターへ移動
###command + 2  分割した右のエディターへ移動
【AWS_CLI】ALBのリダイレクト設定

2018/7/25に対応されたALBのリダイレクト設定です。
[参考ページ](https://aws.amazon.com/jp/about-aws/whats-new/2018/07/elastic-load-balancing-announces-support-for-redirects-and-fixed-responses-for-application-load-balancer/)



## CLI version
```bash:awscli
aws --version
aws-cli/1.15.66 Python/3.6.4 Darwin/17.7.0 botocore/1.10.65
```
そもそも`aws-cli/1.15.66`より古いバージョンだと、RedirectConfigがないのでエラー吐きます。
なのでアップデート必須

## JSON
ワンライナーで試してたのですが、RedirectConfigを2つ以上設定すると[謎のエラー吐く](#おまけ)のでJSONで逃げました。

```json:alb_RedirectConfig.json
{
    "LoadBalancerArn": "[ALBのARN]",
    "Protocol": "HTTP",
    "Port": 80,
    "DefaultActions": [
        {
            "Type": "redirect",
            "RedirectConfig": {
                "Protocol": "HTTPS",
                "Port": "443",
                "Host": "#{host}",
                "Path": "/#{path}",
                "Query": "#{query}",
                "StatusCode": "HTTP_301"
            }
        }
    ]
```

## CLI

```bash:awscli
aws elbv2 create-listener  --cli-input-json file://alb_RedirectConfig.json  --profile [aws conflimのprofile]
```
`--profile`はプロファイル分けてる人用なので、要らなければ外してください。

```bash:結果
$ aws elbv2 create-listener  --profile jupiter_develop --cli-input-json file://alb_RedirectConfig.json
{
    "Listeners": [
        {
            "ListenerArn": "[ListenerのARN]",
            "LoadBalancerArn": "[ALBのARN]",
            "Port": 80,
            "Protocol": "HTTP",
            "DefaultActions": [
                {
                    "Type": "redirect",
                    "RedirectConfig": {
                        "Protocol": "HTTPS",
                        "Port": "443",
                        "Host": "#{host}",
                        "Path": "/#{path}",
                        "Query": "#{query}",
                        "StatusCode": "HTTP_301"
                    }
                }
            ]
        }
    ]
}

```

## 感想
ちなみにコンソールからやると5分で終わります／(^o^)＼
CLIでやりたかったので、あれこれ調べたりCLIバージョンではまったり、エラーでハマったりとかしてたら2時間くらいかかりました・・・

ただやっぱり画面はコロコロ変わるのがAWSなので、コマンドで残すのは再現性高くていいなと思ってます。


## おまけ
ワンライナーのときの謎のエラーです。
`StatusCode=HTTP_301`だと出ないですが、2つ以上の要素足していくとでます／(^o^)＼

```bash:error
aws elbv2 create-listener  --load-balancer-arn [albのarn] --protocol HTTP --port 80 --default-actions Type=redirect,RedirectConfig={StatusCode=HTTP_301,Port=80} 
Invalid type for parameter DefaultActions[0].RedirectConfig, value: StatusCode=HTTP_301, type: <class 'str'>, valid types: <class 'dict'>
Invalid type for parameter DefaultActions[1].RedirectConfig, value: Port=80, type: <class 'str'>, valid types: <class 'dict'>
```


## 参考資料
[create-rule — AWS CLI 1.15.66 Command Reference](https://docs.aws.amazon.com/cli/latest/reference/elbv2/create-rule.html)
Linux (タイル型 wm)でもスクショがとりたい！⁽⁽٩( ˘ω˘)۶⁾⁾

# はじめに
そんなのしってるよ〜(っ･ω･)っ という方には参考にならないかもしれないです.

あと, タイル型ウィンドウマネージャを使ってる方向けです.
Gnome には gnome-screenshot があるので, そちらを使うと良いと思います.

# 動機
mac と linux を兼用していて気づいたんですが,
「mac の ⌘+⇧+4 みたいなスクショを Linux でしたい！(いい感じに範囲選択できるやつ)」
っと思ったわけです. 思いませんか? そうですか.

# どうしましょ
[slop](https://github.com/naelstrof/slop)っていう範囲選択用のアプリがありました.

しかもスクショのとり方まで書いてあるので, もうこれは解決ですね.

```bash:screenshot.sh
#!/bin/bash
slop=$(slop -f "%g") || exit 1
read -r G < <(echo $slop)
import -window root -crop $G ~/myimage.png
```
これは slop の readme に書いてあることなんですが, **imagemagick が別途必要**です.

ArchLinux: `sudo pacman -S imagemagick`
GentooLinux: `sudo emerge --ask media-gfx/imagemagick`
Ubuntu: `sudo apt install imagemagick`
(CentOS の場合は少々面倒らしいので, ご自分で調べていただきたいです:;(∩´﹏`∩);:)

あと, テンプレには `~/myimage.png` として保存するように書かれているので, 例えば 
`` $HOME/Pictures/screenshot/`date \"+%Y_%m_%d_%H_%M_%S"`.png `` 
とかに置き換えると, 撮影日時がわかりやすいし保存したファイルが重複しないのでいいと思います.

# キー割り当て
タイル型ウィンドウマネージャの例として i3wm, xmonad での割り当てを紹介しておきます.
st 等他のウィンドウマネージャを使っている方はすみません.( ◞´•௰•`)◞

## xmonad の場合
以下は, スクショを Mod+S に割り当てる一例です.

```haskell:~/.xmonad/xmonad.hs
{-
   ここでの myKeys は XConfig (desktopConfig とか defaultConfig とか) に対して,
     xmonad $ config `additionalKeysP` myKeys
   というように使用される値です.
-}

myKeys :: [(String, X())]
myKeys = [ 
  -- some other key settings
  , ("M-s", spawn "/path/to/screenshot.sh")
]
```
## i3 の場合
以下は, スクショを Mod+Shift+s に割り当てる一例です.

```config
# other configs
bindsym $mod+Shift+s exec /path/to/screenshot.sh
```

# さいごに
slop の readme には動画を撮影する方法も書かれているので, 動画の撮影とかにも使えると思います.
ハンズラボの掲載記事一覧(2018年4〜7月)

ハンズラボ株式会社の、掲載記事一覧をまとめました。
2018年の4〜7月という中途半端な区切りですがご容赦ください。

・web記事のみです（書籍への掲載分は含みません）
・登壇資料URLは含みません
・東急ハンズとして掲載しているものも、弊社が開発したものなど携わったものについては掲載しております

---

**ペイメントナビ**
[「ペイメントカード・セキュリティフォーラム2018」を開催　9つの講演を行い、申し込みは定員超過](https://www.paymentnavi.com/paymentnews/72257.html)

[東急ハンズ、カード情報非保持化とICクレジットカード決済に対応可能なPOSシステムの構築について](https://www.paymentnavi.com/paymentnews/74873.html)

**MD NEXT**
[ハンズラボ、AOKI、カインズ、グッデイ、チームラボ、それぞれのデジタルシフト](https://md-next.jp/5435)

[「データもシステムもAWS上に置いているからITの力をフル活用できる」](https://md-next.jp/4701)

**日経クロステック**
[反対派を黙らせる一言、デジタル変革の抵抗勢力を味方にするワザ](http://tech.nikkeibp.co.jp/atcl/nxt/column/18/00335/062000001/)

**日本経済新聞**
[小売り、会計に「時短」の工夫](https://r.nikkei.com/article/DGXMZO32210570V20C18A6TJ3000?s=1)

**ECzine premium**
[Amazon Goの衝撃 日本にも「スキャン＆Go」の時代が来る](https://eczine.jp/premium/detail/5763)

**日経クロストレンド**
[ハンズ、パルコ、JapanTaxiの音声UI活用 AIの提案精度へ期待](http://trend.nikkeibp.co.jp/atcl/contents/watch/00013/00045/)

[AIは「簡単単純だけど、明確に良くなるよね」というところから](https://trend.nikkeibp.co.jp/forum/00008/00022/)

**METI/経済産業省**
[電子レシートの標準仕様を検証する実験を行いました](http://www.meti.go.jp/press/2018/06/20180629001/20180629001.html)

**LINE株式会社**
[【LINE Clova】プラットフォームのオープン化を発表 「Clova」のスキルを開発・拡張できる 「Clova Extensions Kit」を7月中に一般公開](https://linecorp.com/ja/pr/news/ja/2018/2247)

**ITmediaエグゼクティブ**
[消えゆく情シスと輝き始める情シス――ビジネス革新をけん引できるかどうかが分かれ目に](http://mag.executive.itmedia.co.jp/executive/articles/1807/23/news011.html)