OmniAICreator/Qiita-1.07M huggingface dataset:
大量のコンテンツをラインアップする際の有効カタログサイズ


Netflixの研究者らが発表した推薦システムの運用と改善に関する論文[^1]で、<b>有効カタログサイズ (Effective Catalog Size: ECS)</b>というおもしろい概念が提案されていたので、備忘録的にまとめます。
（この記事はZOZOテクノロジーズAdvent Calendar 2018その3の3日目の記事です）

#推薦システムの重要性
Netflixは膨大な数のビデオをラインアップしているため、ユーザーがカタログを一つ一つチェックしながら好みのビデオを見つけるのは困難です。せっかく良質なビデオをたくさんそろえても、ユーザーがそれを発見できなくては意味がありません。したがって、Netflixにとって推薦システムは"core to our business"であり、極めて大きな役割を果たしています[^2]。
これは他の多くのIT企業も共通して抱えている問題で、音楽、本、レストラン、求人、旅行先など、現代社会において推薦システムの応用先は枚挙にいとまがありません。

###多様なコンテンツを届ける
テレビのビジネスモデルが、誰もが好むような少数のコンテンツを大多数のユーザーに届けるというものであるのに対し、Netflixは、ニッチなコンテンツを大量にそろえ、それらを好むユーザーに対して的確に届けることで大きな利益を生み出します。よって、Netflixの推薦システムは単純に人気の高いコンテンツを勧めるのでなく、<b>多様なコンテンツを多様なユーザーに届ける</b>ことが重要です。

#有効カタログサイズとは何か
では、ユーザーが消費しているコンテンツの多様性をどのように定量化すればよいでしょうか。そこで上記論文で提案されていたのが有効カタログサイズ（ECS）です。
以後、映画タイトルや楽曲などユーザに推薦する単位をアイテム、アイテムすべての集合をカタログと呼ぶことにします。
カタログに$N$個のアイテムがあり、それぞれが一定期間内に消費された割合[^3]をベクトル$\mathbf p = [p_1, \ldots, p_N]$で表すことにします。ただし、$\mathbf p$の要素は大きい順にソートされているとします（$p_i \geq p_{i+1}$）、また割合であるため総和は1となります($\sum_{i}^Np_i=1$)。ここで、$\mathbf p$はどのアイテムが消費されやすいかを表す確率質量関数（probability mass function）として解釈できます。
この時、ECSは以下の式で定義されます。
$$
ESC(\mathbf p)=2\left(\sum_{i=1}^Np_ii\right)-1
$$
Python3での実装

```python

def ECS(pmf):
    ecs = 0
    for idx, prob in enumerate(sorted(pmf, reverse=True), 1):
        ecs += prob*idx
    return 2*ecs -1   
```

アイテムが3つあるシナリオ($N=3$)で値を確認してみます。

```
# 1つのアイテムが圧倒的人気
p = [1, 0, 0]
ECS(p)
Output: 1

# 3つのアイテムが平等に消費される
p = [1/3, 1/3, 1/3]
ECS(p)
Output: 3
```
ECSは、消費されるアイテムに偏りが大きいほど最小値の1に近づき、逆にアイテムが平等に消費されるほど最大値の$N$に近づきます。つまり、<b>ECSはユーザーが消費したコンテンツにどれくらい多様性があるか</b>の指標となります。
上記論文の著者らは、以下の図で彼らの推薦システムの有効性を主張します（図は同論文から引用）。
<img width="611" alt="62589bb3b62b6c3e93469f0f2809e765.png" src="https://qiita-image-store.s3.amazonaws.com/0/309437/7c97d672-0122-e9a4-675e-f3ff54469b4d.png">
横軸にカタログサイズ、縦軸に有効カタログサイズがプロットされています。単に人気のビデオを推薦した場合が黒、推薦をパーソナライズした場合が赤でプロットされており、推薦のパーソナライズによりECSが最大で4倍になったという主張です。つまり、単に人気のコンテンツを推薦しているとユーザーはより同一のコンテンツを視聴するようになり、推薦をパーソナライズするとより多様なコンテンツを視聴するようになったことを意味します。これは、上述の通りNetflixのビジネスにとって重要なことです[^4]。

# おわりに
有効カタログサイズ (ECS)という概念を紹介しました。大量のコンテンツをラインアップしている状況において、どれくらい多様な選択肢をユーザーに届けることができているかの指標として使えそうです。弊社の事業領域であるファッションも多様性が非常に重要であると考えているので、今後ZOZOTOWNやWEARの有効カタログサイズを計算してみたいと思います。今回参考にした論文には、有効カタログサイズ以外にもおもしろい話が紹介されているので、興味のある方には一読を勧めます。


[^1]: Gomez-Uribe, Carlos A., and Neil Hunt. "The Netflix Recommender System: Algorithms, Business Value, and Innovation." ACM Transactions on Management Information Systems, 2016. https://dl.acm.org/citation.cfm?id=2843948

[^2]: 上記論文によると、ネットフリックスにおいては視聴時間の3分の2が推薦システム経由であり、年間10億ドル以上の効果をもたらしているそうです。

[^3]: たとえば、視聴時間やクリック数の割合などが考えられます。

[^4]: 統計的思考に慣れている人なら「有効カタログサイズなど持ち出さなくても単にアイテム消費の分散を計算すれば良いのでは？」と思うかもしれません。たしかにそれも1つの手段ですが、分散は異なるカタログサイズの間で比較が難しいという欠点があります。つまり、カタログサイズ=10の時の分散とカタログサイズ=1000の時の分散では、値が同じでも状況は大きく違います。ECSは、元のカタログサイズを基準にした上でどれくらいの多様性があるかを直感的に表現する値と言えます。
JavaScript Style Sheetをご存知ですか

まずはじめにお断りしておきますが、タイトルだけを見て、「Reactなどで、JavaScriptとCSSを融合させる」ような技術を連想した方は…大外れです。

[カレンダー](https://qiita.com/advent-calendar/2018/lost-technology)のとおり、これは現代には伝わっていないロストテクノロジーです。

## JavaScript Style Sheet（JSSS）とは

HTML5では`<style>`の`type="text/css"`を省略できるようになりましたが、現実問題としてブラウザで直接使う、他のスタイルシート言語は存在しないように思えます。

…と思いきや、かつて`type="text/javascript"`で書くスタイルシート言語が存在しました。これが、JavaScript Style Sheet、略してJSSSです。

## 文法概要

現代でもJavaScriptで要素ごとにCSSを指定する際に`element.style.marginLeft = '20px';`のように書けますが、そういうことをグローバルにできるオブジェクトが存在している、というのがJSSSの環境です。なお、用語は現代の読者の理解を優先するためにCSSのものを借用する場面もあります。

* `tags.TAGNAME`…タグセレクタ
* `classes.class_name.all`…クラスセレクタ
* `ids.id_value`…IDセレクタ

なお、同じセレクタに複数のプロパティを指定する場合、これまた現代JavaScriptから消滅した`with`構文を使っています。

### 子孫セレクタ

CSSでいう「複合セレクタ」として使えるのは子孫セレクタだけで、`contextual(親オブジェクト, 子オブジェクト…)`のような形で指定します。また、`first-letter`や`first-line`はプロパティとして取れたようです。

### 動的スタイルシート

JavaScriptということで、当然プロパティに代入する値は計算して出すことが可能です。また、`apply`というプロパティがあって、ここに関数を入れておくと、スタイルシートの評価のたびに関数が呼び出されて評価されるという、意外と高度な仕組みがあります。

## 普及状況

JSSSはNetscapeの4系列で採用されましたが、IEで採用されることはなく、Netscapeも6系列では対応を打ち切っています。

## 外部リンク

* [英語版Wikipedia](https://en.wikipedia.org/wiki/JavaScript_Style_Sheets)
* [W3Cへの提案](https://www.w3.org/Submission/1996/1/WD-jsss-960822)
document.hidden時のrequestAnimationFrameの挙動

requestAnimationFrameはページが隠れてるときは、実行されないと思っていましたが、Firefoxでは実行されてるっぽかったので、各ブラウザがどういう挙動になるか調査してみました。
ついでにsetTimeout / setIntervalもページが隠れてるときどのくらい変化するか調べました。

## 結果

| Browser | request<br>Animation<br>Frame | setTimeout<br>setInterval* |
|:-:|:-:|:-:|
| Chrome 70 | 0 | 約1回/秒 |
| Firefox 63 | 0.5 ~ 1回/秒 | 約1回/秒 |
| Safari 11 | 0 | 約1回/秒 |
| IE11 | 0 | 変化無し |
| Edge 12 | 0 | 変化無し |
| iOS<br>Safari 12 | 0 | 0.01 ~ 1回/秒 |
| Android<br>Chrome 70 | 0 | 約1回/秒 |
*setTimeout / setInterval のdelayは1000/60秒

Firefoxのみページが隠れてるときも多少実行されました。
setTimeout / setIntervalもページが隠れてるときは約1回/秒ほどのに抑えられますが、IE11とEdgeは変化なしでした。

[調査ページ](http://ksk1015.github.io/raf-on-document-hidden/)
CryptZombiesレッスン2(チャプター1~5)の自分なりのまとめ

# 最初に
この記事は私がCryptZombiesを進めていく上で自分なりにまとめたものです。
前回の記事
https://qiita.com/daichi77/items/c494fc23652a476b63ba
参考にしたサイト
サイト名: イーサリアム上のDApp開発をゲームを作って学びましょう
URL: https://cryptozombies.io/jp/　
前の記事までは問題文と答えを書いておきましたがよく考えたらcryptzombiesの方に問題も答えも書いてあるので割愛します。
# チャプター１
特に何もないので割愛。
# チャプター２　マッピング(Mapping)とアドレス（Addresses）
## 用語
**アドレス**
イーサリアムのブロックチェーン場にある口座。
仮想通貨の取引をしているとよく目にする。通貨(ethreumとか)を送金したり、受け取ったりする。
銀行口座のデジタル版みたいな認識。
**マッピング**
配列や構造体のようにデータを格納するときに使える便利なやつ。

```
mapping (key => value) public mapping名;
```
実際に使うときはkeyとvalueのところにはuintやstringなどの型を書いておく。
## 今回したこと(テスト)
1. zombieToOwnerというマッピングの作成
これによりゾンビのIDを元にゾンビを参照できるようになった。
keyはID,valueはaddress
2. ownerZombieCountというマッピングの作成。
これはownerのaddressをkey、uintをvalueにすることでそのアドレスのゾンビの数を数えれるようにするためのやつ。(多分)

# チャプター３ Msg.sender
## 用語
**msg.sender**
この関数を呼び出したユーザー（またはスマートコントラクト）の**address**を参照できる。
関数を呼び出すまでは、コントラクトはブロックチェーン上で何もせずに、ただそこにあるだけなのでこれを呼び出すためにmsg.senderが使われる。
## 今回したこと(テスト)
1. keyをゾンビのid、valueをmsg.sender(アドレス)にしzombieToOwnerマッピングを更新した。
2. OwnerZombieCountのkeyがmsg.sender(自分のアドレス)のvalueを＋１した。
 
## まとめ
今回新たにできるようにしたことは、ゾンビが作られた時点で
1.そのゾンビがownerのアドレスに紐付けられる。
2.ownerの持っているゾンビのカウントが+１される。
ということである。
これでいつでもゾンビのownerのアドレスを参照できるようになり、オーナーに紐づけられているゾンビの数が参照できるようになった。

# チャプター４ Require
## 用語
**Require**
if文のようなもので関数内で

```
require(条件);
```
と書くことで条件を満たしていなかった時にエラーを吐くようにすることができる。
## 今回したこと(テスト)
今回はcreateRandomZombie関数の中にrequire文を書くことで、自分のアドレスにすでにゾンビが登録されていた場合ゾンビが作られないようにした。

# チャプター５　継承
## 継承
これは他の言語と同様、コントラクトを継承することでコードをリファクタリングできるというやつ。

```
contract 子contract is 親contract {}
```
と書くと子コントラクトにアクセスした時に親コントラクトの関数も使えるようになる。
まあこの辺は他の言語のクラスの継承とほぼ同じ認識。
## 今回したこと(テスト)
ZombieFeedingにZombieFactoryを継承した。以上！

# 次の記事
https://qiita.com/daichi77/items/a3d758853da726f25874
グラフラプラシアン（関係データ学習　機械学習シリーズ）

```{r}
#グラフラプラシアン

#関係データ学習　機械学習シリーズ

data=data.frame(num=1:20,y=c(167,167.5,168.4,172,155.3,151.4,163,174,168,160.4,164.7,171,162.6,164.8,163.3,167.6,169.2,168,167.4,172),x1=c(84,87,86,85,82,87,92,94,88,84.9,78,90,88,87,82,84,86,83,85.2,82),x2=c(61,55.5,57,57,50,50,66.5,65,60.5,49.5,49.5,61,59.5,58.4,53.5,54,60,58.8,54,56))

n=nrow(data)

mat_data=as.matrix(data[,colnames(data) %in% c("y","x1","x2")])

cor=cor(mat_data)

alpha=0.01

t_value=qt(1-alpha/2,df=n-2)

t=cor*sqrt(n-2)/sqrt(1-cor^2)

diag(t)=0

t[t>qt(1-alpha/2,df=n-2)]=1

t[t!=1]=0

t=t+diag(-apply(t,1,sum),ncol=(ncol(t)))

eigen_values=eigen(t)$values

vec=eigen_values

vec[abs(vec)<10^(-4)]=1;vec[vec!=1]=0

vec_data=data.frame(num=1:length(vec),vec=vec)

num=vec_data$num[vec_data$vec==1]

vectors=eigen(t)$vectors[,num]

vectors=vectors/mean(vectors)




```
C++ Builder XE4 > TOpenDialog (TSaveDialog) のOptions > ソースでの指定の仕方

```txt:動作環境
C++ Builder XE4
```

### 関連

- [TOpenDialog の Option](https://qiita.com/plum_shiga/items/ce2927b151ae7b772882) by @plum_shiga さん
    - 情報感謝です。

### 不明だった点

- ofOverwritePromptをソースで指定する書き方

参考

- [C++BuilderでTSaveDialogの使用例](https://www.gesource.jp/weblog/?p=6054) by 山本隆 さん
    - 情報感謝です。

```cpp
SaveDialog1->Options << ofOverwritePrompt << ofCreatePrompt;
```

`<<`を使うようです。

### 実装

```Unit1.cpp
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
	SaveDialog1->Options << ofOverwritePrompt;

	if (SaveDialog1->Execute() == false) {
		return;
	}

	// ここにファイル指定時の処理を書く
}
//---------------------------------------------------------------------------
```

### 不明点

`<<`の意味

A. 既存のものを消して設定
B. 既存のものに加えて設定

既存のもの
- ofHideReadOnly
- ofEnableSizing

動作結果からかんがみると、「B. 既存のものに加えて設定」である気はします。
(サイズ変更ができた、という理由から)

### その他関連

- [Vcl.Dialogs](http://docwiki.embarcadero.com/Libraries/XE4/ja/Vcl.Dialogs)
AtomのCSVビューワ tablr が動かない問題の回避策

# 背景
いつものように [tablr](https://atom.io/packages/tablr) でCSVを開こうとすると以下のようなエラーが出たので調べた

```
Cannot read property 'includeInfo' of undefined 
```

# TL; DR
作者のリポジトリが全く更新されないのでコマンドラインで以下の処理を実行する。

```shell
apm uninstall tablr
apm install https://github.com/mfripp/atom-tablr.git
```

[こちらのIssueのコメントから引用しています](https://github.com/abe33/atom-tablr/issues/100#issuecomment-406904774)

# 解説

 問題は以下の2つでした。

1. ATOMパッケージが最新のATOMに追随できていない
2. 元のGitHubリポジトリが更新されていない

解決策としてGitHubで議論されて出た答えが「他のひとがフォークしてくれたリポジトリからインストールする」でした。

(再掲)

```bash
apm uninstall tablr # 一旦アンインストールする
apm install https://github.com/mfripp/atom-tablr.git #mfrippさんのrepoからインストールする
```

# 最後に
ATOMの拡張は基本的にはOSSなので困ったらGitHubのIssueを眺めると答えが見つかるかもしれません。
Pythonでexception、logging.configによるエラーメッセージに変数を表示したい

#概要
Pythonスクリプトを実行している際に、想定しているエラーのLogを取得する手法を記述します。
Pythonではログの出力に logging.configを使います。

参考
logging.config使ったpythonのロギングについてメモ
http://takemikami.com/2016/06/11/loggingconfigpython.html

#前提
logging.conf ファイルを準備している環境で、 try-exception による exception発生時におけるエラーメッセージに変数を入れ込みたい場合を想定します。
Pythonのドキュメントを参照すると以下のように記載があります。


>logging.exception(msg, *args, **kwargs)
レベル ERROR のメッセージをルートロガーで記録します。引数は debug() と同じように解釈されます。例外情報がログメッセージに追加されます。このメソッドは例外ハンドラからのみ呼び出されます。

debug()はどのように解釈されるかは下記のとおりです。

>logging.debug(msg, *args, **kwargs)
レベル DEBUG のメッセージをルートロガーで記録します。 msg はメッセージの書式文字列で、 args は msg に文字列書式化演算子を使って取り込むための引数です。 (これは、書式文字列の中でキーワードを使い、引数として単一の辞書を渡すことができる、ということを意味します。)

16.6. logging --- Python 用ロギング機能
https://docs.python.org/ja/3.6/library/logging.html#logging.debug

すなわち、文字列置換を利用して変数を入力することが可能であるということを意味しています。

#コード
1を0で割る簡単なプログラムで想定してみましょう。
1(a)を0(b)で割ろうとし(try)、例外が発生する際には(exception)、ログ上に割る数を変更してくださいという趣旨のログを記載します。


```
test.py

#logging.configおよび設定ファイルであるlogging.confをインポート
import logging.config
logging.config.fileConfig("logging.conf")
logger = logging.getLogger()
logger.info("info level log")

#0で除算
a = 1
b = 0

try:
    c = a/b
except ZeroDivisionError:
    print("ゼロで割るとエラーになります")
    #logger.exception内のmsgに文字列書式化演算子を入れ込む(%d)
    logger.exception("You can not diving by zero. Please change b ---> %d",b, exc_info=True)

print("終わりました")
```

ログ上はこのように出力されます。


```
test.log

[2018/12/03 19:05:53][INFO](htmltest.py:4) info level log
[2018/12/03 19:05:53][ERROR](htmltest.py:13) You can not diving by zero. Please change b ---> 0
Traceback (most recent call last):
  File "C:/Users/khagiwara/PycharmProjects/untitled1/htmltest.py", line 10, in <module>
    c = a/b
ZeroDivisionError: division by zero

```

"You can not diving by zero. Please change b ---> %d" の %d 部分に変数bを代入することができました。
【Rails】Rinkuを使い、URLを検出して<a>タグを自動的に適応させる方法


URLを検出してaタグを自動的に適応させたくて色々探していたところ、LinkuというGemを見つけました。
これを使えば、安全なURL、emailなどにlinkを埋め込んでくれます。

C言語で書かれているらしく、どうやら高速らしい。


早速使って見ましょう。

github→　https://github.com/vmg/rinku

##Rinkuのinstall

Gemfileに`rinku`を追加。

```ruby

gem 'rinku'
```

```ruby

bundle install
```

##使い方

```ruby

<%= raw Rinku.auto_link(h(変数)) %>
```

これでURLを検知して自動的にaタグで囲んでくれます。

しかし、これでは外部リンクにできません。
もし外部リンクにしたいのであれば、以下のようにすると良いでしょう。

```ruby

Rinku.auto_link(text, :all, 'target="_blank"')
```

text・・・　文字列かhtmlが入り、自動的にhtmlに変換されます。すでにaタグが適応されてあれば、そのままaタグになります。

mode　・・・　どのformatをlinkにするか指定します。　:all, :urls、　:email_dressのどれかをlinkに変えます。

targetを指定すれば外部リンクにすることができます。文字列でしか渡せない仕様になっていたため、くれぐれも`target: "_blank"`とハッシュを渡さないようにしましょう。

##実際の例

```slim
= Rink.auto_link("http://www.hoge.com", :all, 'target="_blank"')
```
とした場合、以下のように出力されます。

```ruby
# <a href="http://www.hoge.com" target="_blank">http://www.hoge.com</a>
```

しかし、railsで使うと画面上では文字列として表示されてしまうことがあるため、もしその場合はエスケープしないようにしてあげる必要があります。

```slim
/このうちのどれか
= Rink.auto_link("http://www.hoge.com", :all, 'target="_blank"').html_safe
= raw Rink.auto_link("http://www.hoge.com", :all,'target="_blank"')
== Rink.auto_link("http://www.hoge.com", :all, 'target="_blank"')
```


こちらの記事を参考にさせていただきました。
 https://freesworder.net/rails-link-a/
Kubernetes, Docker周りのVSCode便利拡張機能

# 概要
Kubernetesそのものの運用などとはちょっと違い、KubernetesやDockerを使っていく上でちょこっと便利なVSCodeの機能の紹介です。
これらを使うことでKubernetesのちょっとしたIDEがVSCodeできてしまいます。コマンドをいちいち打つのがそろそろめんどくさいと思った方、一からyamlを作るのはちょっと・・・（実務的にはあまりないでしょうけど）、あの書き方どうだっけ？ってなるって方には作業支援になるのではと思います。

# Docker
https://marketplace.visualstudio.com/items?itemName=PeterJausovec.vscode-docker
<img src=https://qiita-image-store.s3.amazonaws.com/0/257806/92128e9d-11e8-ea1f-6dd9-568641facb7d.png width=30%>

まずはKubernetesのベースになるdockerのための拡張機能。

- リソースのリスト化と簡易的にコンテナへの操作がコンテキストメニューからできる
- dockerfileやdocker-compose.ymlのIntelliSenseが使えるようになる
- `docker rm`や`docker logs`など基本的なdockerコマンドがコンテキストメニューから選択できる
- `docker attach`や`docker exec`も右クリックからの操作でVSCodeのターミナルにアタッチできる

![image.png](https://qiita-image-store.s3.amazonaws.com/0/257806/03423e51-e266-98e6-d649-809829d22a5d.png)
![スクリーンショット 2018-12-03 13.10.07.png](https://qiita-image-store.s3.amazonaws.com/0/257806/d1b88be2-84fa-5fd1-bc0a-c699c91e7578.png)

# Kubernetes
https://marketplace.visualstudio.com/items?itemName=ms-kubernetes-tools.vscode-kubernetes-tools
![image.png](https://qiita-image-store.s3.amazonaws.com/0/257806/67acbb56-65d7-65e8-2933-c3acfe6548f5.png)

Kubernetesの簡易ダッシュボードがわりになってくれる拡張機能。

- リソースの一覧やコマンド操作などをコンテキストメニューから行うことができる
- Dockerと同じ感覚でPodへのターミナルのアタッチもできます
- リソースをクリックすると、上の画像のように、そのyamlが見れる
- ymlファイル上でリソースの名前を打つと簡単なテンプレートをサジェストしてくれる（下記gif）
![k8s_support.gif](https://qiita-image-store.s3.amazonaws.com/0/257806/82eb1f7b-4d93-6007-c07b-4f54c9bfb333.gif)

kubeconfigのコンテキスト切り替えなんかもできます
<img src=https://qiita-image-store.s3.amazonaws.com/0/257806/6d2e4acc-2518-3435-9572-616a308b3232.png width=40%>

# Kubernetes Support
https://marketplace.visualstudio.com/items?itemName=ipedrazas.kubernetes-snippets

なぜかあんまり記事が出てこなかったKubernetesのyaml作成支援機能。
個人的にはKubernetesの「yamlの壁」を下げてくれる可能性を感じる拡張機能だと思っています。
基本的には前述の「Kubernetes」のサジェスト機能をより強化したものです。
「Kubernetes」よりも対応しているリソーステンプレートの種類が豊富。
雛形を調べて引っ張ってこなくてもこの拡張機能である程度作成できてしまいそう。（もちろんそれぞれのリソースへを理解していないと意味ないですが）

例えば、Deploymentだと、フルセットのものとシンプルなものを選べます。

![k8s_support2.gif](https://qiita-image-store.s3.amazonaws.com/0/257806/470653d3-e048-5cdb-21e8-337ccade99d2.gif)

ちなみにシンプルなものだとこんな感じ。
<img src=https://qiita-image-store.s3.amazonaws.com/0/257806/23ce0e18-256f-49b1-ef6b-9dd1a24c1f63.png width=50%>

serviceからserviceAccountまで豊富ですね。typeまで列挙してくれている。親切！
![k8s_support3.gif](https://qiita-image-store.s3.amazonaws.com/0/257806/32bfd49e-f5df-f34b-9d87-41fc9992c745.gif)



以上、ちょこっと便利なKubernetes周りの拡張機能の紹介でした。
よければ使ってみてサクサクyamlを書いてください。
[C#] usingブロックを使ったStringBuilderのインデント処理

# 概要
ツリー構造や集約ルートモデルのデバッグプリントするとき、階層ごとにインデントを入れたいですが、コード上もわかりやすく、簡単にかけるようにならないかと考えて、ユーティリティクラスを作ってみました。

IDisposableにして、 **usingブロックを使って書けたらブロックのインデントが出力のインデントに一致してわかりやすい（当社比）** かなという思い付きです。

# コード（ユーティリティクラス）
**コメント欄に改良版があります**ので、そちらをご覧ください。取り込もうと思ったけど単なるコピペになりそうなので、自分の元ソースはそのままにしておきます。

```csharp
using System;
using System.Text;
using System.Text.RegularExpressions;

public class IndentedStringBuilder : IDisposable
{
    private const string INDENT = "  ";
    private const string REPLACEMENT = "$1" + INDENT;
    private StringBuilder _parent;
    private StringBuilder _internal;

    public IndentedStringBuilder(StringBuilder parent)
    {
        _parent = parent;
        _internal = new StringBuilder();
    }

    public StringBuilder Builder { get { return _internal; } }

    /// <summary>
    /// 親のStringBuilderが改行で終わってなかったら改行を追加する
    /// </summary>
    private void AdjustParentEndLine()
    {
        if (_parent.Length == 0 ) return;

        var lastChar = _parent[_parent.Length - 1];
        if(lastChar == '\r' || lastChar == '\n') return;

        _parent.AppendLine();
    }

    public void Dispose()
    {
        AdjustParentEndLine();

        var lines = Regex.Split(_internal.ToString(), "\r\n|\r|\n");
        var count = lines.Length;
        // 元の文字列の末尾が改行だと、空の行が一個増えるのを防ぐ
        if (count > 0 && lines[count - 1].Length == 0) count--;
        lines.Take(count).Foreach(x =>
        {
            _parent.Append(INDENT);
            _parent.AppendLine(x);
        });
    }
}
```

# 使い方
こんな風にusingブロックで囲んで使います。ネストして多段インデントもできます。
インデントの前後で必要に応じて改行を追加する機能もありますので、下記の例の場合 AppendLine から Append に変えても同じ出力結果になります。
（当然ですが、同じインデント階層に連続で書き出す場合は Append で改行はしません。）

**サンプルコード**

```csharp
    var sb = new StringBuilder();
    sb.AppendLine("AAA");
    using (var child = new IndentedStringBuilder(sb))
    {
        child.Builder.AppendLine("BBB");
        using (var child2 = new IndentedStringBuilder(child.Builder))
        {
            child2.Builder.AppendLine("CCC");
        }
        child.Builder.AppendLine("DDD");
    }
    sb.AppendLine("EEE");
    return sb.ToString();
```

**出力**

```console
AAA
  BBB
    CCC
  DDD
EEE
```

#解説
IDisposableをusingブロックで使うと、ブロックを抜けるときにdisposeされるという仕様を使って、dispose呼ばれたときにインデント付与処理をしています。

IndentedStringBuilder 自体が StringBuilder を継承できればよかったんですが、sealed クラスなのでできません。なのでやむなく Builder プロパティー経由で StringBuilder にアクセスするようにしました。
**お好みで IndentedStringBuilder に Append() など StringBuilder と同じメソッド生やしてもいいかもしれません。**

言うほど使いやすくも見やすくもねーよ、と言われたらごめんなさいと言うしかありません。そこは主観の問題なのでご容赦ください。

#注意点
usingブロックの中で普通に元のStringBuilderを編集できてしまうけれど、(おそらく)書いた人の期待とは違う結果になります。

```csharp
    var sb = new StringBuilder();
    sb.AppendLine("AAA");
    using (var child = new IndentedStringBuilder(sb))
    {
        child.Builder.AppendLine("BBB");

        sb.AppendLine("XXX"); // <--これ

        child.Builder.AppendLine("DDD");
    }
    sb.AppendLine("EEE");
    return sb.ToString();
```

出力

```console
AAA
XXX
  BBB
  DDD
EEE
```
まあ、`XXX`を`BBB`と`DDD`の間に挿入したいなら、普通にusingブロックを分割してください。
[転載] Anaconda > Proxyがある環境においてpipインストールに失敗する > 対処 > Condaのインストールコマンドをコピペしてコマンドプロンプトの画面で打つ

詳細は不明 (自分の環境ではないため)

```txt:動作環境
- Anaconda
- Proxyがあるネットワーク環境
```

### 概要

@MageManager さんが1年以上苦労していたpipインストール問題。

ご自分で解決されたそうです。Qiita記事にすると同じ状況の人に役立つかと提案したところ、こちらが記事にしてもいいと許可をいただいたので、簡単ながら記事にします。


### 問題

2018年11月11日
https://qiitadon.com/@magemanager/101050329685232719

@MageManager さんWrote
> Anacondaで入れたPythonに、例えばPuLPをpipで入れようとすると弾かれて１年間泣いてました。


### とりあえずの対処

2018年11月19日
https://qiitadon.com/@magemanager/101097001736625391

@MageManager さんWrote
> 会社の環境でpipが使えないとムンクの様に叫びましたが、圧縮ファイルをダウンロードして、ローカルで直接ファイル指定するとpipが動くことが分かりました！
※調子に乗ってテンソルフローを入れようとしたら、ローカル環境でも怒って動いてくれませんが。。。

### きちんとした対処

2018年12月3日
https://qiitadon.com/@magemanager/101176450131730794

@MageManager さんWrote

> 社内のProxyサーバーの妨害でPythonのモジュールが入れられなかった件だが、何故かcondaだと自由に通る事が判明。よく分からんが、これでTensorFlowも無事にインストールされた！VPythonもクリアー！


2018年12月3日
https://qiitadon.com/@magemanager/101176441606080994

@MageManager さんWrote
> 普通にAnacondaCloudのページに載ってるCondaのインストールコマンドをコピペしてコマンドプロンプトの画面で打つと通りました。
※pipは赤い文字が出て通りません

### 補足情報

Rのインストールについても

2018年12月3日
https://qiitadon.com/@magemanager/101176450131730794

@MageManager さんWrote
> @7of9 あと、RのインストールはRStudioのメニューからインストールするとこれまた普通に通ります。駄目なのはpipですね。

### 記載内容について

@MageManager さん

記載内容に問題があればご連絡ください。
（記事削除も含めて）対処いたします。

この内容をそのままご自分の記事にして、ブラッシュアップしていただくのも問題ございません。
(その際はこちらの記事を消します）

あるいは、補足情報がありましたら、編集リクエストください。


### 関連
(2019-09-17追記)

プロキシ関連で、別の状況での対応記事をリンクしておきます。

- [プロキシを通さないと外に出れないネットワーク上にあるWindowsに、DOOM Emacsをインストールした](https://qiita.com/manzyun/items/9e55358f4d58f54198eb)
Mac に boostをインストールし ublasとlapackを使えるようにする

タイトルの通り、Macにboostをインストールしてublasを使えるようにする

## boost.ublusをインストール
１． Homebrewでboostをインストール

```
$ brew update
$ brew install boost
```

２．boostがインストールされたディレクトリを確認

```
$ls /usr/local/Cellar/boost/
```

３．ublasのヘッダーファイルの場所を確認

```
$ /usr/local/Cellar/boost/1.68.0/include/boost/numeric/ublas
```

４．XCode のプロジェクトに boostのheaderとlibraryのリンクを設定する

## boost.bindingsをインストール
ublasからlapackを使うためのラッパー。ヘッダーファイルのみ。

１． https://github.com/uBLAS/numeric_bindings　をダウンロード

２．1でダウンロードしたファイルを解凍し、解凍後の'boost'ディレクトリをboostのincludeフォルダへ移動

```
$ cp -r ./numeric_bindings-master/boost/numeric/bindings /usr/local/Cellar/boost/1.68.0/include/boost/numeric/
```

３．Xcodeにliblapack.tbd, libcblas.tbdを読み込む
metaタグのrobotsで自分に都合よく検索避けさせる

※以下を自分用にまとめただけです。
[メタタグとは？SEO効果は？metaタグ一覧と書き方まとめ - サルワカ](https://saruwakakun.com/html-css/basic/meta-tag#metarobots)
サルワカさん、いつもお世話になっております。

# robotsの書き方、効能
```html:htmlのhead内
<meta name="robots" content="noindex,nofollow">
```
headタグ内にこんなものを書くと、検索エンジンに対して「インデックス(掲載)せず、ページ巡回もしないでくれ」ということになる。
なので、クソ以下の臭いがプンプンするページにはこれをはっつけておけば、SEOになるのでは。

`contents=""` 内にはカンマで複数入れたり、片方だけ記入、もできるので用途によって変えるのが良さそう。

## index
`index`は名前通りGoogleの検索結果にインデックス(掲載)するかどうか。(あえて書くものでもない)
`noindex`でインデックスされなくなる。

検索結果に乗せたくないものに使う。
ex) 検索結果、フォームの確認画面、タグや日付の索引ページ

## follow
`follow`でサイトのクロール(巡回)だけはしてくれる。張ったリンクだけ見ててほしい、というところでつかえるらしい。
`nofollow`でクロールされなくなる。
Vue Routerでparamsとqueryの取得方法

Vue Routerでparamsとqueryの取得方法です。
（よく忘れるので、備忘録です。）

```
#　paramsの取得方法
localhost:8080/example/:id
→ this.$route.params['id']

#　queryの取得方法
localhost:8080/example?itemId=1234
→ this.$route.query.itemId
```
AWS SDK for Ruby のインストールを早くする

## はじめに
RubyプロジェクトでAWSにサービスを使うとき、AWSの開発ガイド「[AWS SDK for Ruby のインストール](https://docs.aws.amazon.com/ja_jp/sdk-for-ruby/v3/developer-guide/setup-install.html)」を見て、AWS SDKをインストールしました。

```:Gemfile
gem 'aws-sdk'
```

これを追加して、Gem installすると、インストールにかなり時間がかかってしまいます。

## なぜ時間がかかるのか？

Gemfile.lockの中を見てみました。

```
...
aws-partitions (1.76.0)
aws-sdk (3.0.1)
  aws-sdk-resources (~> 3)
aws-sdk-acm (1.5.0)
  aws-sdk-core (~> 3)
  aws-sigv4 (~> 1.0)
...
```

上記のような、AWSに関する記述が500行くらいあり、100くらいのGemがインストールされていることがわかりました。

## これを減らすことはできないのか？

AWS SDKではAWSサービスすべてが使えるように、多くのGemがインストールされます。
しかし、実際のプロジェクトではその中のS3のサービスしか使わないとなると、その他はインストールするのは無駄です。
AWSの特定サービスのSDKだけをインストールできないか [AWS-SDK-Ruby の GitHub](https://github.com/aws/aws-sdk-ruby)を見てみました。

すると、[Upgrading Guide](https://github.com/aws/aws-sdk-ruby#upgrading-guide)こんな記述がありました。

> Version 3 modularizes the monolithic SDK into service specific gems.

AWS SDK Version3からSDKがモジュール化されており、特定サービスのGemをインストールできそうです。

## 特定サービスのGemだけをインストールしてみた

例として、S3のサービスだけを使えるように修正してみます。
やり方は、 [Upgrading Guide Options](https://github.com/aws/aws-sdk-ruby#options) に書いてあるようにします。

```:Gemfile
# -------- before --------
gem 'aws-sdk'

# -------- after --------
gem 'aws-sdk-s3'
```

```ruby:s3.rb
# -------- before --------
require 'aws-sdk'

# -------- after --------
require 'aws-sdk-s3'
```

この状態で、Gem installを行って、Gemfile.lockを見たところ、その差は歴然でした！

- コード行数
 - 539行 -> 15行
- インストールGem数
 - 138個 -> 6個

## CHANGELOGはどうやって確認すればよいか？
`aws-sdk-ruby/gems/` から特定のサービスのSDKの中に、CHANGELOG.mdがありました。
AWS-SDK-S3を例にすると、以下のURLになります。
https://github.com/aws/aws-sdk-ruby/blob/master/gems/aws-sdk-s3/CHANGELOG.md

## S3以外はどうやって記述できるのか？

[Upgrading Guide Options](https://github.com/aws/aws-sdk-ruby#options) には、S3とEC2の例が書いてありますが、他の場合はどう記述すればいいのでしょうか。
[Supported Services](https://github.com/aws/aws-sdk-ruby#supported-services)に書いてありました。
AWS re:Inventを日本で楽しむ方法

[NJCのアドベントカレンダー](https://qiita.com/advent-calendar/2018/njc-tech)に参加しております。
# はじめに
**AWS re:Invent**とは、AWSが開催する最大の学習型イベントで、毎年11月末から12月頭にかけて、ラスベガスにて実施されております。
2016年、2017年と2年連続現地参加させて頂きましたが、
今回（11/26-11/30）は技術者を優先して、**お留守番**となりました。
そこでお留守番でも楽しむために行った事をまとめます。

# この記事の目的
AWS re:Inventに現地参加できなくても楽しめる方法を共有する

# 現地の情報を収集する主な手段と目的
**公式ライブストリーミング**
　- リアルタイムの情報を得る
　- 現地の雰囲気を得る
**公式ブログ（Jeff Barr氏）**
　- リアルタイムの情報を得る（英語が読めるなら）
**赤い軍団の技術ブログ**
　- ほぼリアルタイムの情報を得る
　- 日本語の情報を得る
　- 詳しい解説を得る
**SNS**
　- 現地の雰囲気を得る
**現地参加メンバー（同僚）からの情報提供**
　- 自社に関わりの高そうな情報を得る
　- 現地に行ってる感を得る

# 工夫したこと
## 事前準備
**事前勉強会への参加**
一番のポイントです。実際に現地に行く方と知り合い、SNSで繋がる事で情報量が増えます。参加者限定コミュニティグループにジョインできればさらに情報量がupするでしょう。

**自社からの参加メンバーとの交流**
まずは、事前勉強会へ誘います。でもってその際にチャットグループを作っておきます。これで彼らの行動は筒抜けです。（ニヤリ）
もちろん、自分のノウハウは事前に、また期間中にも伝えます。
（今回は複数人が参加したので、彼ら同士のやり取りも貴重な情報源でした。）

**スケジュール管理**
ライブストリーミングがあるKeynoteは、日本時間のAM1:00開始です。
仕事に悪影響が出ないように寝る時間を確保する必要があります。
（詳細はのちほど）

## 期間中
**ライブストリーミングの視聴**

具体的にはキーノートの視聴ですね。
今回のスケジュールは下記の通りでした。（日本時間）
- 水曜 AM1:30〜3:30
- 木曜 AM1:00〜4:00
- 金曜 AM1:30〜3:30

幸いにも勤め先がフレックスタイム制なので、期間中は可能な限り下記の生活を行いました。
- AM6:00〜PM3:00出社
- PM6:00〜AM0:00就寝
- AM1:00〜AM4:00視聴
（なかなかに辛いスケジュールなので、どこかで休暇を挟むことを推奨します。）

ここで、現地とストリーミングでの比較

|項　目|　　現　地　　|ストリーミング|
|:------:|:------:|:------:|
|対象|すべてのセッション|Keynoteのみ|
|雰囲気|◎|×|
|同時通訳|○|×|
|メモの取りやすさ|△|◎|
|気楽さ|△|◎|

![IMG_0363.JPG](https://qiita-image-store.s3.amazonaws.com/0/225108/14fd28e1-e1e6-8a9c-409a-22adfe03b704.jpeg)

**情報発信**
"情報を発信する人に、一番情報が入ってくる。"
視聴用とは別にPCを用意して、FacebookとTwitterを立ち上げます。
現地の方のポストをチェックしつつ、自分も気になった情報やテンション上がった事は投稿しましょう。すぐに現地の方からの反応があったり、情報量がupします。
何より**参加してる感**が高まります。

**赤い軍団のブログ**
他社なので具体的には書けませんが、現地に約60名派遣して数百のブログをアップして下さる軍団です。
英語で聞き取れなかった内容や知識不足な内容はここですぐに補完できます。
ヒント："AWS re:Invent 2018 JAPAN PORTAL"

## 期間後
**AWSサイト**
発表された、ほぼすべてのサービスが日本語で紹介されております。
すでに使えるサービスもたくさんあります。

**reCap**
AWSやパートナー企業、JAWS-UG（コミュニティ）にて、多くの振り返りイベントが開催されます。
"reCap"というキーワードのイベントがそれです。
できるだけ多く参加しましょう。

**アウトプット**
この投稿もそうですが、アプトプットすることで自分のものになります。
技術者なら実際に新しいサービスを使ってみたブログでもいいでしょう。
私は参加したメンバーにインタビューして、企業ブログに幾つか投稿しようと考えてます。

# 感想
17時間の時差は結構キツいですね。フレックスタイム制にだいぶ助けられましたが、国内で時差ボケしそうでした。
参加したメンバーやSNSを見ていると、現地のほうが圧倒的に情報量があって、毎日**"羨ましい"**気持ちでいっぱいでした。

ストリーミング環境は、画像は鮮明で音声もクリアで、想像よりもかなり快適でした。

# さいごに
次回以降の**"日本で参戦"**の方々のお役に立てれば幸いです。
SlackのDM比率が高くなる理由

## はじめに

組織のオープンマインドの現れとして、SlackのDM比率の低さをアピールする事例をいくつか見かけるようになりました。とても素晴らしいことだと思います。

例）

- https://mercan.mercari.com/entry/2018/04/10/163322
- https://speakerdeck.com/miyasho88/we-are-hiring?slide=46
- https://speakerdeck.com/hideakiishikura/20180718ren-shi-kaben-yin-takewohua-suhui-deng-tan-zi-liao?slide=15

一方で自社のDM比率を見てみると、かなりの割合でDMが使われていてギャップに落胆する、という人も少なくないのではないでしょうか。なぜDM比率が高くなるのか？ということについて自分なりに整理してみました。

## 理由1:組織の心理的安全性が低い

「心理的安全性」は、 Googleの [re:Work](https://rework.withgoogle.com/jp/guides/understanding-team-effectiveness/steps/introduction/) によると以下のように述べられています。チームの効果性を高めるために最も重要なファクターと言われています。

> 心理的安全性: 心理的安全性とは、対人関係においてリスクある行動を取ったときの結果に対する個人の認知の仕方、つまり、「無知、無能、ネガティブ、邪魔だと思われる可能性のある行動をしても、このチームなら大丈夫だ」と信じられるかどうかを意味します。心理的安全性の高いチームのメンバーは、他のメンバーに対してリスクを取ることに不安を感じていません。自分の過ちを認めたり、質問をしたり、新しいアイデアを披露したりしても、誰も自分を馬鹿にしたり罰したりしないと信じられる余地があります。

例えば、Slack上で誰かが質問をしたとします。
心理的安全性が低い状態では、その質問に回答したいとしても、トンチンカンな回答だと嫌だな、チャンネル全員にそれを見られたくないな、という心理が働き、DMで回答するという行動に繋がる、という話を聞きました。特に `#general` などの参加人数が多いチャンネルだとその傾向が高くなるようです。個人的にはこの理由が一番重要だと思います。

## 理由２：Slackの活用方法の周知不足
Slackはかなりメジャーなコミュニケーションツールになりましたが、チャットによる業務に慣れていない人・職種はあります。
私は、もともとエンジニアだけでSlackを利用していたのを、全社利用に切り替えたタイミングで、DM比率が急激に上がった、ということを経験しました。

エンジニアの場合、コードレビューやOSSを通じてオープンにコミュニケーションすることのメリットを肌で理解していることが多いです。一方で、非エンジニアだとそういったコミュニケーションに不慣れな場合もあります。

例）
- 受注前のクライアントの情報をむやみに公開したくない営業
- 普段から取扱注意な情報を扱いがちな人事

職種ごとの事情や背景について尊重しつつも、オープンにコミュニケーションすることのメリットを啓蒙し続けていくのが良いのかな、と思います。

## 理由3:業務が属人化している
属人化した業務だと、業務の依頼がDMでとんでくる、ということが少なくありません。社内ITなど、なんとなく詳しい人がなんとなく担当している、という場合に属人化傾向が高くなると思います。
その業務用のチャンネルを開設するなどして、依頼のフローを標準化することで解決できました。

## 理由4:ゲストアカウントが多い
Slackのゲストアカウントは[channelを作ることができません。](https://get.slack.help/hc/ja/articles/202518103-%E3%83%9E%E3%83%AB%E3%83%81%E3%83%81%E3%83%A3%E3%83%B3%E3%83%8D%E3%83%AB%E3%82%B2%E3%82%B9%E3%83%88-%E3%82%B7%E3%83%B3%E3%82%B0%E3%83%AB%E3%83%81%E3%83%A3%E3%83%B3%E3%83%8D%E3%83%AB%E3%82%B2%E3%82%B9%E3%83%88#%E3%82%B2%E3%82%B9%E3%83%88%E3%81%AE%E6%A8%A9%E9%99%90)
正社員のみにMemberを付与、業務委託はGuestなどの運用だと、DMを使わざるを得ないという状況が生まれやすいと思います。

## 理由5:根回しの重要性が高い

twitterで、

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">Slack、DM禁止することはできないけど禁止したいって言ってる知り合いの会社が最近多くて、理由はサイコパスとか社内政治に全振りしてるような人に有利すぎるかららしい。<a href="https://t.co/43Et8yaegF">https://t.co/43Et8yaegF</a></p>&mdash; takano (@iototaku) <a href="https://twitter.com/iototaku/status/1061961284755709953?ref_src=twsrc%5Etfw">2018年11月12日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>




という投稿を見かけました。根回しをオープンにやることは考えにくいので一理ありそうです。ある程度の根回しは必要だと思いますが、その重要性が高くなりすぎるとひきづられるようにDM割合も高くなる、という感じでしょうか。

### 理由6:正しいDMの使い方をしている

おまけっぽい要素です。[個人の DM にメモやファイルを保存する](https://slack.com/intl/ja-jp/help/articles/219899267-%E5%80%8B%E4%BA%BA%E3%81%AE-DM-%E3%81%AB%E3%83%A1%E3%83%A2%E3%82%84%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%92%E4%BF%9D%E5%AD%98%E3%81%99%E3%82%8B) は、Slackが公式に使い方として案内しているやり方です。スターやリマインダのセットもできるのでわりかし便利です。

## おわりに

DM比率が高くなる理由について自分なりにまとめてみましたがいかがでしょうか。感想、編集リクエストお待ちしております！
React Redux の 高負荷なコンポーネントを高速で突き止める


React Redux でアプリを作っていると
いつのまにやら過剰にアップデートを繰り返すコンポーネントがでてくることがあります。
こいつらはなんら関係ない動作をしてもアップデートすることがあり、
**CPU使用率を爆上げ**し、**FPSを爆下げ**ます。

場合によってはいくつかのコンポーネントを制御するだけで動作が驚くほど改善するので
なるべく検証前に確認しておきたいところです。

今回は、過剰にアップデートを繰り返す、高負荷なコンポーネントの突き止め方を紹介します。

## 環境準備
昨今の開発用マシンは性能が良いものが多く
パッと見、負荷の高い処理も問題なく見えてしまうジレンマがあります。

そこで、ブラウザ上でのCPU性能を抑制して検証を進めます。
`Chrome開発者ツール` -> `Performance` -> `CPU` で環境のCPU性能を下げていきます。
<img width="405" alt="スクリーンショット 2018-12-03 14.38.41.png" src="https://qiita-image-store.s3.amazonaws.com/0/59151/0fdeb7e0-a520-3801-6db4-7006dfeca053.png">

環境が用意できたら
ローカルの開発環境にて、アプリを実際に使用し、動作が遅いと感じる部分を探します。

## 動作計測
動作が重い箇所を見つけたら
`Chrome開発者ツール` -> `Performance` -> `Record` で計測してみましょう
`Record` はパッと分かりにくいですが左上の ● マークです。
<img width="515" alt="スクリーンショット 2018-12-03 16.44.00.png" src="https://qiita-image-store.s3.amazonaws.com/0/59151/39110ef0-7a68-9daf-b91f-a9a9408fcf93.png">
長時間計測すると解析に時間がかかってしまうため
計測時間は2秒〜10秒ほどを目安とするのが良い感じです。

![スクリーンショット-2018-12-03-15.08.32.png](https://qiita-image-store.s3.amazonaws.com/0/59151/e5fd5425-e8da-95a5-bc85-2bedf2d93753.png)
実際に計測したものがこちら
まず、赤の破線に囲まれた `CPU使用率` に注目します。
黄色い領域は `Script処理` を表しており、CPU使用率が高いことが分かります。
紫の領域は `Paint処理` を表していますが、CPU使用率は低そうです。

今回はScript処理の負荷が大きいようです。

Chrome開発者ツールの詳しい解説はこちらをご参照ください
https://developers.google.com/web/tools/chrome-devtools/

## CPU使用率の高い箇所を見る
CPU使用率が高い箇所をクローズアップしてみます。
`Interactions` と `User Timing`に注目してみましょう。
<img width="867" alt="スクリーンショット 2018-12-03 15.25.24.png" src="https://qiita-image-store.s3.amazonaws.com/0/59151/3bd34a00-c4f1-b17f-135f-7d9703b60bdc.png">
**Interactions**: `Mouse Down` `Mouse Move`などユーザーの行動が確認できます。
**User Timing**: 内部処理が確認できます。

User Timingの中で`ComponentName[update]` という記述が多々あることがわかります。
**ここが実際にコンポーネントがアップデートしている箇所です**
Chromeだとコンポーネントの名前を表示してくれるので問題のある箇所が分かりやすいですね。

このアップデートしている箇所が適切にアップデートされているならば問題ないのですが
過剰なアップデートがかかっているコンポーネントは負荷になります。

コンポーネントのアップデートの制御は、**思わぬバグを生みやすい変更**です。
State、Propsの流れを把握して施策・検証をしながら制御していきましょう。

次回は実際に行ったコンポーネントアップデートの抑制方法を紹介していきます。

## 補足
今回の内容は公式の「[Optimizing Performance](https://reactjs.org/docs/optimizing-performance.html#profiling-components-with-the-chrome-performance-tab)」の中でも少し紹介されています。

手順さえわかってしまえば、問題ある箇所を探すのに5分もかからないと思います。

当初これを知らなくて
コードとにらめっこしながら問題のある箇所を探さなければいけないのかと、途方に暮れました。

最後までお読み頂きありがとうございました。
NEMアカウントを作ろう！２

[前回](https://qiita.com/nem_takanobu/items/f8f51452d6ab653f597c)はブラウザを使って簡単にNEMアカウントを作る方法を解説しました。

今回はもう少し強度の高い秘密鍵の生成に挑戦します。
まず、乱数ですが擬似乱数と明確に区別する必要があります。

擬似乱数とは大雑把な言い方をすると、乱数表というものの中から適当に数字を取ってくるような感じです。ですのでシード値と呼ばれるものを指定すれば、かならず同じ値が手に入ります。

そうです、Math.random() のような関数で擬似乱数で秘密鍵を作ってはいけません！

では完全にランダムな乱数というものは作れるのでしょうか？
実はこれも不可能です。システムは何かしらのインプットをたよりに乱数を作ることしかできません。
なので、そのインプット値をコピーされれば同じ乱数値を再現することは可能です。
ですので、限りなくランダムに近い値を目指すしかないのです。
しかし、そのブラウザが十分にランダムなつもりではじき出した乱数も
近い将来その仕組みが解明されて再現方法が見つかってしまうかもしれません。

そのときに重要なキーワードとなるのがエントロピーという概念です。

ルービックキューブを思い浮かべてください。
何回か縦横に回されたルービックキューブは子供が偶然触ったぐらいでは元に戻せなくなります。
そして十分にぐちゃぐちゃにされたされたルービックキューブは大の大人でも元に戻すのは相当困難になるでしょう。

この原理で、秘密鍵を作成するときもランダムに生成した乱数をさらにぐちゃぐちゃにかき回して、
ブラウザが作りだした乱数をさらに復元不可能なものに変換させます。


前回同様HTMLは以下の通り

```html:index.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
  </head>
  <body>

    <!-- ライブラリ -->

	<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/crypto-js.min.js"></script>
	<script src="nacl-fast.js"></script>
	<script src="xembook-sdk.js"></script>

    <!-- app -->
	<script>
//ここにロジックを追加していきます

	</script>
  </body>
</html>
```

挿入するロジックは少し追加して以下の通りです。

```js

let r = ua2hex(nacl.randomBytes(32));
let seed = processEntropy("0124595587184571048560847563487523487394857234057", "password");
let privateKey = derivePassSha(r + seed, 1000).priv;
let k = KeyPair.create(privateKey);
let address = toAddress(k.publicKey.toString(), 104);

```

processEntropyを使用して、エントロピーとパスワードからシード値を生成します。
パスワードとはNanoWalletの場合、ログインパスワードを指しますが、今回はなんでもよいです。
そして、"0124595587184571048560847563487523487394857234057"というのがエントロピー値です。
この値が複雑であれば複雑であるほど、復元困難となります。

そして、導出されたシード値と乱数を足し合してさらに1000回グチャグチャにしたものを秘密鍵とします。
後は前回と同様にKeyPairを生成して公開鍵とアドレスを出力すればNEMアカウントセットの出来上がりです。

これで十分に強度の高いNEMアカウントを作成できました。
ちょっと説明が漏れてますね。今回固定値で指定したエントロピー値にはどういったものが適切でしょうか？
NanoWalletでアカウントを作成した人ならわかると思いますが、
マウス操作によって出力される座標値移動情報などは再現できる可能性が低く、よく利用される方法です。
（今回例示した数値列は明らかに桁数が少ないのでご注意ください）

またおいおい追加していきますので、ぜひご参考ください。
かつてフルスタックと呼ばれていたエンジニアの生存戦略2018

この記事は、[Makuake Product Team Advent Calendar 2018](https://qiita.com/advent-calendar/2018/makuake) 4日目の記事です。

世間は１２月ということで、イルミなんとかっていうのが席巻しておるようですが、皆様いかがお過ごしでしょう。 @yu0819ki です。
今年2月より株式会社マクアケに入社したわけですが、時が経つのは早いですね。

# TL;DL
「手薄」になってるところを補う働きで生きてる！

# 著者スペック
`かつてフルスタックと呼ばれていたエンジニア` と題したからには、それなりに自分のスペックを公開しなければならないでしょう、ということでちょっと箇条書していきます。

- インフラ・ミドルウェア
    - AWSでWEBサービス処理系を作れる程度のクラウドインフラ知識
    - Linuxサーバの基礎知識
    - Apache, nginx, Tomcat, php-fpmなどのWEBサーバ、アプリケーションサーバ周りの知識
    - MySQL, Memcache, Redis, その他KVSに関しての設計・運用知識
    - ネットワークや通信の仕組みに関する基礎知識
    - AnsibleやChefをつかったインフラのコード化
- サーバサイド
    - PHP
    - Javascript(Node.js)
    - Java
    - Scala
    - Python
- フロントエンド
    - JS
        - jQuery
        - React
        - Vue.js
        - TypeScript
    - Style
        - CSS3
        - SCSS
- グラフィック処理
    - Photoshop, GIMP等を使った簡単な加工や素材作成など
- その他
    - Flash
    - AS3

# 最近のお仕事
上記スペックを見ておわかりいただけるかと思いますが、一般的なWEBサービスにおいては大概のことが一人で完結できます。
それを活かして、障害や不具合が発生した際に率先して突っ込んでいったり、手薄になっているところをサポートしに行くような動きをよくやっています。
「手薄」と一言で言っても結構振れ幅があり、春ころには「Vue.jsの導入をしたいがフロントエンド人材が手薄」ということでがっつり開発をしていたこともあり、世間的なイメージの保守・運用担当とは一線を画す役割かなぁと思っております。

また最近では、新規参入メンバーに対して、スムーズに自社サービスの理解をしてもらえるように、適度な粒度のタスクを振ったりするような役割も担当しています。
入社時の意気込みとかでよくあるような「できるだけ早く戦力に慣れるようにがんばります！」をサポートする・・・的な役割ですね。
５年も運用しているサービスなので、サービスの機能全体を俯瞰できるようになるには１ヶ月ではちょっと足りなくて、約２ヶ月で大体網羅できることを目指しています。


このように、これまで培ったそこそこ幅広い知識を駆使して、サービスの運営・開発が円滑に進むことを目指して生きてきた2018年でした。
来年は・・・いや、来年も大体同じ生き方をしているような気はしますが、機会がありましたらまた来年も報告します。

# おわりに
最後になりますが、株式会社マクアケでは一緒に働くメンバーを募集しております。💪
ご興味が有りましたらご連絡いただけると幸いです！
https://www.wantedly.com/projects/26807

Makuake Product Team Advent Calendar 2018 Advent Calendar 2018
まだまだ続きますので、明日以降もよろしくお願いします！

# ...One More...?
全然関係ない路線からぶっこんでいくのですが、　[phpcs-tsv-reporter](https://github.com/yu0819ki/phpcs-tsv-reporter)というものを作りました。
PHPCSにはもともとcsvのreporterが同梱されて入るのですが、tsvの方がawkで集計しやすかったので。

awkかわいいよawk
チームでのデザインは「Creative Cloudライブラリ」が便利！

みなさん、こんにちわ。 

今回はAdobeの「Creative Cloudライブラリ」（以後、CCライブラリ）を実際に利用してみたらとても便利だったので、使用してみたメリットなど共有したいと思います。



# CCライブラリとは？
CCライブラリとは、Adobeが提供しているデザインアセット管理機能です。
CCライブラリに画像、色、テキストスタイルなどのアセットをアップすると、それらのアセットを様々な環境で使用することができます。

さらにチーム内で共有することもでき、アセットを再利用、変更することもできます。

<img width="800" alt="０１.png" src="https://qiita-image-store.s3.amazonaws.com/0/218366/3d8e1870-5560-abd6-e0cd-3610026b49f1.png" style="border:1px solid #000000;">
↑これはPhotoshopでの画面で、右のパネルにあるのがCCライブラリパネルです。
種類ごとにグループ分けができ、名前なども変更できます。



# 使用するメリット
CCライブラリのメリットはいくつかあるのですが、僕が実際に感じたメリットを３つ、絞ってみました。

### メリット１　正しい色を共有できる
複数のデザインを複数人で作業していると、途中で色が微妙に違う色になる危険性が高まりますよね。

しかし使用するカラーを共通化することで、常に正しい色を使用することができます。
僕はサービスのブランドカラーを登録し、誰でも同じ色コードでデザインできるようにしました。



### メリット２　ロゴのマスターデータを開かなくてよい
たいていロゴデータはイラストレーターのファイルで、大切に保管されていると思いますが、
ファイルを開くたびに間違って上書き保存するなど、常に危険が付きまといますよね。

CCライブラリに一度登録してしまえば、もうマスターデータは開かなくて済むので、もうその危険とはサヨウナラです。
マスターデータを開かなくてすむので、効率もとてもよくなります。



### メリット３　デザインを整理できる
CCライブラリにアセットを登録すると簡単にパネル内で整理整頓ができます。
一覧でアセットを確認できるので、俯瞰してデザインを考えられるようになります。

そしてそのアセット内の要素でデザインをしようとするので、無駄な色や要素を増やすことなくシンプルにデザインすることができます。

## 逆にデメリットは？
正直、利用してのデメリットを全く感じません。
逆にもっと早く利用してこなかったことが悔やまれます（笑）

## 使い方
CCライブラリは使い方がとても簡単です。
登録したい要素をパネルにドラッグするのみでOK!
即クラウドに同期され、登録されます。（同期がめちゃくちゃ早いです）
アセットの使い方もパネルからドラッグするのみOKです。

<img width="800" alt="スクリーンショット 2018-11-30 16.33.18.png" src="https://qiita-image-store.s3.amazonaws.com/0/218366/1dc14c8d-f807-8409-2b1c-031b3b9a8316.png" style="border:1px solid #000000!important;">


Photoshopではなくても、Illustlatorはもちろん、XDやInDesignなど、Adobeの主要ソフトで利用することが出来ます。
もしくはAdobeのマイページにログインし、ブラウザ上でも管理できます。↑

ブラウザでもその色の名前を変更したり、削除など整理が簡単に出来ます。

# さいごに
CCライブラリはチームで共有することで、その便利は格段にあがります。
ぜひチームでデザインをしている人たちにおすすめしたい機能です！

上記で紹介した以外にもたくさんのメリットがありますし、様々な使い方ができると思います。
今後も利用して新しい発見があれば共有したいと思います。

より詳細な使い方はAdobeの公式サイトをご覧ください。
https://helpx.adobe.com/jp/creative-cloud/how-to/share-collaborate-libraries-teams.html

ではでは。
Ruby で XML Spread Sheet を CSVに変換

```ruby

require "roo-xls"

xml_path = "/path/to/a.xml"
csv_path = "/path/to/a.csv"

xml = Roo::Spreadsheet.open(xml_path)
File.open(csv_path,"w"){|f| f.write xml.to_csv}
```

https://github.com/roo-rb/roo-xls
keynoteにコードをハイライトした状態で貼り付ける方法

毎回忘れるのでメモ
（初めての時）homebrewでhighlightをインスコする

```terminal:terminal
$ highlight -O rtf myfile.py -o myfile.rtf
```

myfile.rtfを開いて全文コピーした後，keynoteに貼り付ければおk．
Unicornの起動・停止、あとpidファイルをロックしちゃったときの対応



サーバーが突然死んで、unicornの再起動が必要だったときに、ぱっと手順が出てこなくてすいません。
復習も兼ねて、手順のメモです。

## 環境
* OS
	* Amazon Linux
* Ruby
	* ruby 2.0.0p648 (2015-12-16) [x86_64-linux]
* Rails
	* Rails 4.2.6

## 注意
* 当然プロジェクトによって環境は異なるので、適宜読み替えてください。

## ファイル構成
### 起動スクリプト

Red Hat系のOSなので、/etc/init.d/配下におくことが多いのではないでしょうか。

* 起動スクリプト
	* ```/etc/init.d/unicorn```


### 設定ファイル

起動スクリプトに設定が書いてあります。
わからないときは設定ファイルから引きましょう。
だいたいは、rails_root配下のフォルダにあるのでは無いでしょうか。

```bash
cat /etc/init.d/unicorn
```


```bash:/etc/init.d/unicorn
...

ROOT_DIR="/{your_service}"
USER="{なんか}"
PID="${ROOT_DIR}/tmp/pids/unicorn.pid"
CONF="${ROOT_DIR}/config/unicorn.rb"
OPTIONS=""

...
```

```ruby:/config/unicorn.rb
# 設定ファイル
# -*- coding: utf-8 -*-
worker_processes Integer(ENV["WEB_CONCURRENCY"] || 3)
timeout 15
preload_app true

...

```


### PIDの場所

こちらも、設定ファイルと同じで、起動スクリプトからたどって上げればOK。

* PID
	* ```/config/unicorn.rb```


## コマンド

```bash
sudo /etc/init.d/unicorn start
sudo /etc/init.d/unicorn stop

# 無停止再起動
sudo /etc/init.d/unicorn graceful
```

gracefulはこちらが参考になります。
* Unicornのgraceful restartで少しハマった件
	* https://blog.tnmt.info/2012/10/25/unicorn-and-sig-usr2/


## トラブルシューティング
### ps aux | grep unicornってしても、出ないくせに Unicorn already started とでる

これは、pidファイルが残っているからなので、pidファイル消しましょう。
YYPHP#59「YYPHP Qiitaアドベントカレンダー、コードレビュー、未経験の人へのうまい教え方、みなさんどんな活動をしているのか聞きたい、DDDのサービスについて、テーブルドリブンテスト、友達にウェブサービス作ってて気軽に頼まれたときどうやって対応しているのか」

これは2018年11月02日に開催したPHPerイベント[YYPHP#59]のイベントレポートです。

[YYPHP]は一言で「PHPerの部室」です。PHPについて、雑に、ゆるく、ワイワイ話し合う集いです。毎回お題を決めずに雑談を出発点にいろいろなことを突発的にやります。集まった人でコードリーディングをすることもあれば、一緒に開発ツールを触ってみたり、フレームワークについての情報交換をすることもあります。開催はほぼ**毎週**、高田馬場にて。

[YYPHP#59]: https://yyphp.connpass.com/event/106391/
[YYPHP]: https://yyphp.connpass.com/
YouTubeでの配信映像はこちら-> [#YYPHP #59【PHPの情報交換・ワイワイ話そう・仲間作り・ゆるめ・にぎやかめ】](https://youtu.be/Kl_JUZqATRE)

![](https://qiita-image-store.s3.amazonaws.com/0/5354/6d9ce33d-f7df-be3e-66c2-9fd4078524f5.jpeg)

# YYPHP #59

## 参加者15名(うちリモート6名)

* PHP歴
    * 1年未満: 4名
    * 1年: 2名
    * 2年未満: 1名
    * 2年: 1名
    * 3年: 1名
    * 10年: 3名
    * 不明: 3名

## 雑談テーマ

### Qiitaアドベントカレンダー (suin)

* 参加者も購読者も募集中！
* https://qiita.com/advent-calendar/2018/yyphp

### 私のコードレビューしてほしい (カモ)

* https://github.com/LeeDDHH/qiita_daily
* スクレイピング+Qiita APIで人気記事を収集する
* DOM使うといい

### 未経験の人へのうまい教え方 (どい)

* 未経験の人をどのレベルに持っていくか？
    * レベルの定義を明確にしたほうがいい
    * それによってやる内容もやり方も変わってくる
* PHPの基礎的なこと途中で、いきなりLaravelにいっていいものなのか
    * 3ヶ月で基礎をしっかりやって、
    * 調べ方、これからの学び方を教えるのも手
* 練習を繰り返すことが一番いいと思う
* 課題も用意したいができてない
* 『はじめてのLaravel』がおすすめ
    * Laravelの同人誌
    * [絶対に挫折させないアプリ開発　はじめてのLaravel - plumsa - BOOTH（同人誌通販・ダウンロード）](https://plumsa.booth.pm/items/1048008)
    * ToDoリストを3回作る課題がある
        * 素のPHPで実装する
        * Laravelで実装する
        * Laravelでもっといい実装をする
    * 今後学んでいく方法も書いてある
    * 環境をゼロから作るところから書いてある
* PHPの基礎的な課題
    * うるう年
    * 三角形
    * ifとforを使って作る系
    * 九九の表を作れ
    * 多次元配列
    * BBS
    * Twitterのクローンを作る
        * 仕様をパクれるやつはやりやすいため

### みなさんどんな活動をしているのか聞きたい (ケイティ)

* 活動というのは、たとえば
    * 仕事でもいいし
    * PHPをどういうときに使っているか
    * Laravelで何を作ったか
* Javaで書かれている本をPHPに書き直す(写経)
    * デザインパターンをPHPで書き直す
    * テスト駆動開発をPHPで書き直す
* カモスクレイパー書いてる
* 買った書籍のReactコードを写経したりしてる
* 自分でコードを書くとき、あえてPHPを使う
    * Railsでもいいと思っても
* 仕事でLaravel使っている
    * 先輩の書いたコードを手本に自分でコード書いている
    * 自分のレベルだと人のコードを見ながら自分の書き方に置き換えてる
* 自分で作ったり、作ってもらったり
    * 自分で作るのもいいけど、一部切り分けて作ってもらう
    * それにをやるにはきれいにファイルわけしたり、クラス分けしたり
* ちょっとした便利ツール

### DDDのサービスについて (たべたつ)

* 副作用のないサービスってどう作る？
    * 副作用とは参照透過性がない
    * 参照透過性
        * 入力が決まれば、結果も決まる
    * ドメインサービスに対してのこと

### テーブルドリブンテスト (たべたつ)

* なぜGoでよく使われるのか？
* いいところとは？

### 友達にウェブサービス作ってて気軽に頼まれたとき、どうやって対応しているのか (ケイティ)

* フリーランスの工数見積どうやってるのか？
* 機能を分解して
    * WBSを作って
    * 細かく見積もって
    * あとで合算する
* それで、出てきた金額を三倍する
    * エンジニアは低く見積もりすぎるので
* 維持費、保守費も考えておく必要がある
* 契約の種類
    * 準委任
    * 請負

### 今日のYYPHPで話に出てきた図書

* [絶対に挫折させないアプリ開発　はじめてのLaravel - plumsa - BOOTH（同人誌通販・ダウンロード）](https://plumsa.booth.pm/items/1048008)
* [PHPフレームワーク Laravel Webアプリケーション開発 バージョン5.5 LTS対応 | 竹澤 有貴, 栗生 和明, 新原 雅司, 大村 創太郎, 丸山 弘詩 |本 | 通販 | Amazon](https://amzn.to/2KQiD6p)

## YYPHPは毎週やってます

PHPについてワイワイ話したい方は、[YYPHPのイベント情報](https://yyphp.connpass.com/)をチェックしてみて下さい。

以上、YYPHPのレポートでした。次回もワイワイやっていきたいと思います！ では、また来週！
Cognos Analytics 11.1.1 インストール時の注意点3個

#Cognos Analytics 11.1.1インストール時の注意点
Cognos Analytics 11.1.1をWindows環境とLinux環境でインストールしてみましたが、Cognos Analytics 11.0.Xまでと違い、一瞬迷ってしまうステップがありますので、共有しておきます。

#インストール用モジュール
基本的な構成として、以下を行いたいというシナリオでの、インストール用モジュールを記載しておきます。
・Cognos Serverをセットアップして動作させたい
・Cognos SDKも導入しておきたい
・Cognos のサンプルを導入して使用したい

Passport Advantageのサイトからダウンロードすべきモジュールは、以下となります。

**Windowsの場合**
IBM Cognos Analytics Server 11.1.1  Microsoft Windows Multilingual  CNZ15ML
IBM Cognos Analytics Installer 2.0  Microsoft  Windows Multilingual  CNV57ML

**Linuxの場合**
IBM Cognos Analytics Server 11.1.1  Linux x86 Multilingual  CNZ14ML
IBM Cognos Analytics Installer 2.0  Linux x86 Multilingual  CNV5CML

**https://www-01.ibm.com/support/docview.wss?uid=ibm10737087**
https://www-01.ibm.com/support/docview.wss?uid=ibm10737087

おやっ？と思う点がいくつかありますね。

まず、Installer 2.0なるものをダウンロードする必要があります。

Windowsの場合の例として、この2ファイル(dlmgr.proは除く)が必要になりますが、インストールのためにはca_installer_win_2.0.exeを管理者権限で実行します。
![005.JPG](https://qiita-image-store.s3.amazonaws.com/0/147246/e5b7746c-4c6c-a4d4-a601-60ee799c48c6.jpeg)

んで、インストーラーの画面の中で、本体のサーバーモジュールを指定します。
![007.JPG](https://qiita-image-store.s3.amazonaws.com/0/147246/ba795d31-6f60-a720-40e2-a8e2099a45c5.jpeg)

この後は、これまでと同様の普通のインストール手順になります。

おやっ、の二つ目は、SDKをダウンロードしていない事ですが、SDKはServerモジュールの中に含まれ、Serverを導入すれば勝手にsdkフォルダに導入されます。


おやっ、の三つ目は、Sampleモジュールをダウンロードしていない事ですが、これは次の項で説明します。


#Cognosサンプルの導入
Sampleモジュールはこれまでのようにダウンロードする事もできず、かと言って、Serverモジュールをインストールしたら入るというものでも無いようです。

どうするかと言うと、マニュアルのこちらの「Download」のリンクから「Extended_Samples.zip」をダウンロードする必要があります。※マニュアルを日本語表示するとリンクが表示されない・・・
**Download the Cognos Analytics Extended Samples**
https://www.ibm.com/support/knowledgecenter/en/SSEP7J_11.1.0/com.ibm.swg.ba.cognos.ig_smples.doc/c_install_cog_samples.html

Extended_Samples.zipを解凍すると、このフォルダ構造になります。
ここまで来れば、Cognos Analytics 11.0.Xまでと同様になりますので、後の説明は割愛します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/147246/c5a833d0-82fa-f871-5b4a-58265a155552.png)

#Framework Managerの導入
Framework Managerに関しては、
IBM Cognos Analytics Client 11.1.1 Multiplatform Multilingual (CNV58ML) 
に含まれます。
ダウンロードすると ca_client_MP_11.1.1.zip のファイル名でダウンロードされますので、ca_installer_win_2.0.exe から、ca_client_MP_11.1.1.zip を選択してください。
以下のツールの導入が選択可能です。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/147246/e5ca91eb-479a-ccf4-307f-a3333c75a1fc.png)


という3点、ご注意頂ければと思います。

#参考リンク
こちらに詳細手順の記事を投稿していますのでご活用下さい。

**Cognos Analytics 11.1 インストール手順**
https://qiita.com/shinyama/items/fbaf4a81f33de79e4687

**Cognos Analytics 11.1 サンプルセットアップ手順**
https://qiita.com/shinyama/items/b47214bf6efd73cfebad

**Cognos Analytics 11.1 Framework Manager 導入手順**
https://qiita.com/shinyama/items/7e5c87a469842978426b
Node.jsでTwitterのフォロワー数をまとめて調べる方法

Node.jsでTwitterのフォロワー数をまとめて調べる方法。

必要な環境はNode.jsのみ。`npm init`コマンドを使って、初期化します。

```bash
npm init -y
```

`puppeteer`というスクレイピング用のモジュールをインストールします。

```bash
npm i puppeteer
```

`index.js`とか適当なファイル名でJSを書きます。配列のところに、いろんな人のアカウント名を書けば、まとめて調べてくれます。

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

// ここに調べたい人のアカウント名を書いてね
const list = [
  'clockmaker',
  'tonkotsuboy_com',
];

async function start() {
  // Chroniumさん、こんにちは
  const browser = await puppeteer.launch();
  // 新しいタブを開いてね
  const page = await browser.newPage();

  for (let i = 0; i < list.length; i++) {
    const listElement = list[i];

    try {
      const url = 'https://twitter.com/' + listElement;

      // ページへ移動
      await page.goto(url);

      // 任意のJavaScriptを実行
      const count = await page.evaluate(() => {
        // フォロー数情報を抜き取る
        const stringCount = document
          .querySelector('li.ProfileNav-item--followers')
          .querySelector('.ProfileNav-value')
          .dataset.count;
        // 数値へ変換
        return Number(stringCount);
      });
      console.log(listElement, count);
    } catch (e) {
      console.error(e);
    }
  }

  // はい、終了〜
  browser.close();
}

start();
```

すると、コマンド入力をして、Node.jsを実行します。

```bash
node index.js
```

こんな感じでフォロワー数を取れます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/2544/1f3aefc7-1603-5a91-57fe-7dbb84d94bd4.png)
Git困ったぞこれ集

身の回りで起きた、Git利用で陥りがちな状況から立ち直るためのコマンド集。備忘録としてシチュエーション別でまとめます。

## 状況別

### 【コミット前】

#### ファイル変更を無かったことにしたい

全ファイルの変更を最後のコミット時点まで戻す。（要注意）

```
$ git reset --hard HEAD
```

- 特定のファイルのみ最後のコミットまで戻す場合は以下を使用する。

  ```
  $ git checkout ファイル名
  ```


#### addだけを取り消したい

ファイルの変更はそのままに、Addだけ取り消したい場合。

- HEADの位置、インデックスのみ最後のコミット位置に動かす（詳細後述）

  ```
  $ git reset HEAD
  ($ git reset --mixed HEADと同じ。)
  ```

  - 実行後、addして緑文字になったファイル群が再び赤文字になっていることを確認。



#### 間違ってmasterで実装を始めてしまった。

- 書きかけのコードはコミットせず、以下を実行する。

  ```
  $ git stash
  ```

- stashリストに変更点が退避されるので、新規にブランチを作成、切り替えた後に以下を実行するとstashリストの変更が反映される。

  ```
  $ git stash apply
  ```


### 【コミット後】

#### コミットを取り消したい

- ファイルの変更とAddはそのままに、コミットのみ取り消す。

  ```
  $ git reset --soft HEAD^
  ```

- 最新のコミットを取り消し、Addも取り消す場合は以下。

  ```
  $ git reset HEAD^
  ```



#### コミットメッセージを間違えた。

- 直前のメッセージを変更

  ```
  $ git commit --amend -m "{メッセージ}"
  ```



#### 間違ってmasterで実装を始めてしまった。(コミット後)

**ex)コミットは要らない、ファイルの変更点のみ欲しい。**

- コミットしてしまっている場合、上で説明した`git reset HEAD^`でコミットを削除した上で**"[間違ってmasterで実装を始めてしまった](#間違ってmasterで実装を始めてしまった)"**を行う。



**ex)コミット履歴も新しいブランチに移動したい。**

- ブランチを作るべき位置からブランチを作成する

  - （コミット位置=「origin/master」にするとリモートの最新コミット位置を選択できる）

  ```
  $ git branch {新ブランチ名} {コミット位置(=origin/master)}
  ```

- ブランチを移動し、移動したいコミット番号を調べる。

  ```
  $ git checkout {新ブランチ名}
  $ git log --graph {旧ブランチ名(=master)}
  ```

- 新ブランチに移動したいコミットを`cherry-pick`コマンドでコピーする。

  ```
  $ git cherry-pick {コミット番号}
  ```

  - 古いコミット番号から実行すること。

- (masterから引っ越す場合)間違えたコミットを削除する。

  - 不要になったコミットを`git reset`で削除する。

  ```
  $ git reset --hard HEAD~{削除するコミット数}
  ```

  - 下記**"[ブランチのコミット履歴を全てリモートの状態にしたい](#ブランチのコミット履歴を全てリモートの状態にしたい)"**で、master等間違えて置いた旧ブランチを戻すのもOK。

### 【その他】

#### ブランチのコミット履歴を全てリモートの状態にしたい

以下でリモートのコミットログをローカルに完全コピー可能。(≒git pull -f)

1. 残したいファイルをバックアップ。

2. リモートの最新を取得する

   ```
   $ git fetch origin {ブランチ名}
   ```

3. ローカルをリモートに合わせる

   ```
   $ git reset --hard origin/{ブランチ名}
   ```



------

## 解説

#### git resetについて

Git resetではHEAD位置、インデックス、ワーキングツリーの3要素をリセットできる。

- HEAD位置 ... 最新commitの位置
- インデックス ... addされたファイルの一覧表
- ワーキングツリー ... ファイルの変更差分



オプションでリセットする範囲を指定する。(デフォルト：--mixed)

- `git reset --soft` : HEAD位置
  - 最新commitの位置のみリセットする。
- `git reset --mixed` : HEAD位置 + インデックス(ステージング)
  - `--soft` に加えファイルのステージング(add)も取り消す。
- `git reset --hard` : HEAD位置 + インデックス + ワーキングツリー
  - `--mixed` に加えファイルの変更もリセットする



どの時点までリセットするかはオプションの後で指定する。

- HEAD ... 最新のコミット位置
- HEAD^ ... 最新から1つ前のコミット位置
- HEAD^^ ... 最新から2つ前のコミット位置



HEAD位置をずらしてコミットを取り消す場合、取り消されるのは**ローカルのみ**のため、リモートとのコミットの不整合に気を付ける。

- リモートのコミット履歴がA→B→Cの場合(HEAD==C)
  - Cコミットを削除しDブランチを作成した場合、ローカルはA→B→Dとなりマージが不可能となる。→"[ブランチのコミット履歴を全てリモートの状態にしたい](#ブランチのコミット履歴を全てリモートの状態にしたい)"