OmniAICreator/Qiita-1.07M huggingface dataset:
EC-CUBE 4.0をローカル環境でMacにインストールする

**homebrewでcomposerのインストール🍺**
---
composerがインストールされているか確認します🍺

```
$ brew search composer
==> Formulae
composer
```
composerをインストール

```
$ brew install composer
```

```
xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools), missing xcrun at: /Library/Developer/CommandLineTools/usr/bin/xcrun

Error: An exception occurred within a child process:
  CompilerSelectionError: composer cannot be built with any available compilers.
Install GNU's GCC
```

xcrunエラー解消するため、xcode-selectをインストールします

```
$ xcode-select --install
```

gccをインストールするようエラーが出たので従います

```
$ brew install gcc
```

改めてcomposerをインストール

```
$ brew install composer
```

実行して確認します

```
$ composer
   ______
  / ____/___  ____ ___  ____  ____  ________  _____
 / /   / __ \/ __ `__ \/ __ \/ __ \/ ___/ _ \/ ___/
/ /___/ /_/ / / / / / / /_/ / /_/ (__  )  __/ /
\____/\____/_/ /_/ /_/ .___/\____/____/\___/_/
                    /_/
Composer version 1.8.4 2019-02-11 10:52:10
```

ようやくインストールに成功😴


**EC-CUBE 4.0のインストール**
---

EC-CUBEの公式サイトにインストール方法は紹介されています
[インストール方法｜EC-CUBE 4.0 開発ドキュメント](http://doc4.ec-cube.net/quickstart_install)

EC-CUBE 4.0をインストール

```
$ composer create-project ec-cube/ec-cube ec-cube "4.0.x-dev" --keep-vcs
```

エラーが出ました😅

```
  Problem 1
    - The requested PHP extension ext-intl ^1.1 is missing from your system. Install or enable PHP's intl extension.
```

Homebrewで最新のPHPをインストール

```
$ brew install php@7.1
```

画面の指示通りにインストールしたPHPにパスを通す

```
＄ echo 'export PATH="/usr/local/opt/php@7.1/bin:$PATH"' >> ~/.bash_profile
$ echo 'export PATH="/usr/local/opt/php@7.1/sbin:$PATH"' >> ~/.bash_profile
$ source ~/.bash_profile
```

確認

```
$ which php
/usr/local/opt/php@7.1/bin/php
$php -m | grep intl
intl
```

改めてインストール

```
$ composer create-project ec-cube/ec-cube ec-cube "4.0.x-dev" --keep-vcs
```

しばらく時間はかかりますがインストール成功しました😆
お疲れ様でした！
Optional 型変換して値を返却（null 対応）

- parse で null 対応

``` Java
String args = "1";
Integer a = Optional.ofNullable(args).map(o -> Integer.parseInt(o)).orElse(999);
Integer b = Optional.ofNullable(args).map(o -> Optional.ofNullable(Integer.parseInt(o))).orElse(999);
```

- 非同期の exception まとめる

``` Java
List<Future<Void>> futures = new ArrayList<>();
for (ExecutorService service : ExecutorServices) {
    futures.add(service.async());
}
Exception exceptions = null;
for (Future<Void> future : futures) {
    try {
        future.get();
    } catch (InterruptedException | ExecutionException e) {
        exceptions = Optional.ofNullable(exceptions).map(exception -> {
            exception.addSuppressed(e);
            return exception;
        }).orElse(e);
    }
}
```



Optional.map で戻るのが Optional だった
Optional.flatMap は requireNonNull 

``` Java
public<U> Optional<U> map(Function<? super T, ? extends U> mapper) {
    Objects.requireNonNull(mapper);
    if (!isPresent())
        return empty();
    else {
        return Optional.ofNullable(mapper.apply(value));
    }
}
public<U> Optional<U> flatMap(Function<? super T, Optional<U>> mapper) {
    Objects.requireNonNull(mapper);
    if (!isPresent())
        return empty();
    else {
        return Objects.requireNonNull(mapper.apply(value));
    }
}
```
JQueryを使って指定したDOM要素にHTML要素を追加

## この記事について

JQueryの以下のメソッドついて記載する

```
prepend
→指定したDOM要素の前に要素を追加する
append
→指定したDOM要素の後に要素を追加する
```

## サンプルコード

要素を追加することができる。
動的な動きを作りたいときに便利。

```html:sample.html
 <!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
  <title>sample</title>
</head>
<body>
  <ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
  </ul>
  <script>
    $(function(){
      var append = $('<li>').text('added!')
      $('ul > li:eq(2)').prepend(append);
    })
  </script>
</body>
</html>
//３の後ろにタグでadded!というテキストを入れることができる
```

```html:sample.html
 <!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
  <title>sample</title>
</head>
<body>
  <ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
  </ul>
  <script>
    $(function(){
      var append = $('<li>').text('added!')
      $('ul > li:eq(2)').prepend(append);
    })
  </script>
</body>
</html>
//2と３の間にliタグでadded!というテキストを入れることができる
```
Redux 勉強会に参加してきた

## first chapter -概要-
<a href="https://qiita.com/hikka/items/7a6b2820cdac828fbc13" target="_blank">前回</a>のReact勉強会に参加させて頂いた会の続きで、Reduxの会に参加させて頂いたので記憶が消えない今日のうちにメモ。_φ(･_･

##　chapter01 - Reduxとreact-redux
- Reduxとreact-reduxは別物、分けて考えたほうが整理できる
- Reduxは状態管理ツール。Reactと一緒に使用することも、他のビューライブラリと一緒に使用することもできる。
- react-reduxは、ReactでReduxを使うためのライブラリ。

##　chapter02 - なぜReactにReduxか -
- propsバケツリレーを解消できる
- どのコンポーネントからでもstateと更新するハンドラを読み込むことができる

## chapter03 - Reduxの基礎 -
### store
- 状態管理場所。Reduxではstoreで全ての状態管理を行う。
- reducerを引数にcreateStore()メソッドを実行しstoreを作る。

```.js
const store = redux.createStore(reducer);
```

### reducer
- storeを更新する際に使用する。storeは神聖なものなのでreducerという門番を通さずには更新できない。
- Reduxには変更は純粋な関数から行われるべきという原則がある。
- actionに応じて新しいstoreを返す関数

```.js
const reducer = (state=initialState, action) => {
  switch(action.type){
    case: "COUNT_UP":
      return {...state, count: state.count + 1 };
    default:  // defaultを忘れずに書かないと、初期ロードでつまづきやすい
      return {...state, state };
  }
};
```

### action
- storeに対し、どのような変更をしてほしいか書かれたメッセージ。
- {type: string, payload?: mixed} 形式のただのオブジェクト
- typeは様々なアクションの識別子、payloadは更新してほしいデータ。
- store.dispach(action)でreducerを実行し、actionを元にstoreを更新できる。

```.js
store.dispach({type: "COUNT_UP"});
```

## chapter04 - react-reduxの基礎 -

### provider(react-reduxが持つ機能)
- <Provider>で囲ったコンポーネント配下は、reduxのstoreにアクセスできるようになる。
- ルートコンポーネントに記述すればおk

```.js
ReactDOM.render(
 <Provider store={store}>
  <App />
 </Provider>, document.getElementById("root")
);
```

### connect(react-reduxが持つ機能)
- コンポーネントとstoreを接続するための仕組み

```.js
connect(mapStateToProps, mapDispatchToProps)(Component);
```

### mapStateToProps(自作する)
- storeのどの値をコンポーネントで使用したいかを選択する機能。

```.js
// state => stateでもいいが、不必要な値は入れないほうがいい
const mapStateToProps = state => ({ value: state.value })
```

### mapDispatchToProps(自作する)
- どのactionをdispatchさせるのか定義する
- 通常アクションの生成からdispatchの実行まで行う関数を定義し、propsに渡す

```.js
const mapDispatchToProps = dispatch => { 
  dispatchAddValue: amount => dispatch(addValue(amount)) 
};
```

### actionCreator(自作する)
- actionを作る関数
- 呼ぶだけでactionを作るように自分で定義する

```.js
const checkUser = (userId) => {
  return { type: CHECK_USER, payload: id };
};
```

## Last chapter
**感想**
最初覚えられない！！！って思ったんだけど
手を動かすことで勝手になんとなく覚えてきました。
習うより慣れろですね。
でも、仕組みとか引数とか型とか
一応なんとなくでもどういうものかって
理解しないとこわいから

理解する->覚える->手を動かして慣れる->復習する

っていうのが一番効率いいかなって思いました。
Pythonで株価データ読み込みとローソクチャートの表示

株価の予測やらアルゴリズム取引のバックテストをやりたくてプログラムを組んでみることにした。個人的なメイン言語はCなのだが、表示関係のライブラリの充実、機械学習との連携、そして、勉強を兼ねてPythonでやってみることにした。

# 株価データの読み取り
とりあえず、real-timeシステムは将来に置いておくとして、バックテストに特化するものとする。ということで、ネットにある無料の株価データを取得する。

無料（条件有）の株価データはいくつかあるが、今回は「株式投資メモ」さんのものを使うことにする。特に理由はなく、ダウンロードが簡単であっただけである。[株式投資メモ](https://kabuoji3.com/stock/)
他にSBI Hyperを使う方法もあるが、無料で使うには条件がある。また、Web上からゲットする方法もあるが、今回はオフラインでのテストを繰り返したかったのでとりあえずの環境としてオフラインとする。

データを落とすと、中は日本語である。ラベルが日本語だと面倒なので、２行目だけを如何に書き換える。
元：日付	始値	高値	安値	終値	出来高	終値調整値
新：date	open	high	low	close	volume	adj close

以下はソース

```Python:
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import mpl_finance as mpf
import codecs as cd

def DataRead():
	with cd.open("./dataset/jpstock/1570_2018.csv", "r", "Shift-JIS", "ignore") as csv_file:
		df = pd.read_csv(csv_file, quotechar='"', header=1, index_col=0)	# convert data frame type by index_col
```

# ローソクチャートの表示
ローソクチャートに表示。あと、移動平均線を同時に表示させることとする。移動平均線の日数と色は、自分がＳＢＩ証券を使っているので、それに準拠。

```Python:
	df_ = df.copy()
	df_.index = mdates.date2num(df_.index)
	data = df_.reset_index().values

	fig = plt.figure(figsize=(12, 4))
	ax = fig.add_subplot(1, 1, 1)
	
	mpf.candlestick_ohlc(ax, data, width=2, alpha=1.0, colorup='r', colordown='b')
	ax.plot(df.index, df['close'].rolling(5).mean(),color='g',label="Moving Ave(5)")
	ax.plot(df.index, df['close'].rolling(25).mean(),color='m',label="Moving Ave(25)")
	ax.plot(df.index, df['close'].rolling(50).mean(),color='r',label="Moving Ave(50)")
	plt.scatter(x, y, s=100, marker="v",color='k')

	ax.grid()
	
	locator = mdates.AutoDateLocator()
	ax.xaxis.set_major_locator(locator)
	ax.xaxis.set_major_formatter(mdates.AutoDateFormatter(locator))
	plt.legend()
	plt.show()
```	


参考：
[pandas, Matplotlib（mpl_finance）でローソク足チャートを作成](https://note.nkmk.me/python-pandas-matplotlib-candlestick-chart/)
[Pythonでローソク足と出来高を1つのチャートに簡単に描く方法](https://www.madopro.net/entry/CandleStickWithPython)

将来的(Webからデータ取得)：
Webからデータ取得は、pandas_datareaderを使う。しかしこのライブラリは、日本には対応していいないので、ラッパーを作る必要がある。ラッパーを作った人もいたが、将来的なものとしてリンクだけを記載する。また、どうやら欧米のデータもiexしか使えないっぽい。例えばgoogle financeはリンクが変わっていて、ソースを書きなおす必要があるようである。
[日本株の株価を取得してpandasデータフレームに格納する](https://qiita.com/u1and0/items/f6dad2cc2ee730be321c#pandas_datareader%E3%81%A8%E7%95%B0%E3%81%AA%E3%82%8B%E6%A9%9F%E8%83%BD)
[Pythonで株価取得とローソク足チャート作成](https://qiita.com/kjybinp1105/items/be462b481b47b6f94b14)
[pandas-datareaderで株価や人口のデータを取得](https://note.nkmk.me/python-pandas-datareader-stock-population/)
[Pythonのpandas-datareaderで株価を取得してみる①](https://qiita.com/ympnov22/items/0dd0dfd1785015e8b36f)
複合ユニークのうちの一つのカラムのint値をすでに使われてるint値に更新したい

MySQLでこういったテーブルとデータがあったとする。データに任意の順番をもたせたいが、順番の値は重複を許可したくないといったケースを想定している。下記テーブルでいくと `sort` カラムが順番の値を保持しているものとする。

```sql
create table test(
    id int,
    test_id int,
    sort int,
    unique(test_id, sort)
);

INSERT INTO `test` (`id`, `test_id`, `sort`)
VALUES
	(1, 1, 0),
	(2, 1, 1),
	(3, 1, 2);
```

idが3のレコードの`sort`を1にしたい場合、普通にupdateしようとすると、複合ユニークの制約によりエラーとなってしまう😭

しかし、下記のようにSQLを発行すると、値を重複させることなく更新をかけることが可能となる。

```sql
UPDATE test SET sort = (sort + 1) WHERE sort >= 1 ORDER BY sort DESC;
UPDATE test SET sort = 1 WHERE id = 3;
```

`sort` の値が1以上の値にすべて1をプラスし、空いた1のポジションにidが3のレコードが滑り込んでいるような形である。

最初のupdate文で`ORDER BY sort DESC`を指定しているが、この指定があることで降順にレコードにupdateをかけられる。 `ASC` で処理をした場合は、もちろん複合ユニークの制約に引っかかってしまい、エラーとなってしまう。

> ORDER BY 句が指定されている場合は、指定されている順序で行が更新されます。

https://dev.mysql.com/doc/refman/5.6/ja/update.html

また、これとは別に、特定の`test_id`のレコードはすべてdeleteし、`sort`の値を振り直してinsertし直すといった洗替する方法も考えられる。

最初、バルクアップデート的なものでいけないかなと考え実際にやってみたが、残念ながらユニーク制約にひっかかってしまった。
RubyのGem::FilePermissionErrorを解決する

Macでgemをインストールしようとするとなにやらパーミッションエラー。

```
$ gem install bundler

ERROR:  While executing gem ... (Gem::FilePermissionError)
    You don't have write permissions for the /Library/Ruby/Gems/2.3.0 directory.
```

sudoでパーミッションを与えてやる。

```
$ sudo gem install bundler

ERROR:  While executing gem ... (Gem::FilePermissionError)
    You don't have write permissions for the /usr/bin directory.
```

また別の場所でパーミッションエラーが出たので、次は保存場所もlocalにしてやる。

```
$ sudo gem install -n /usr/local/bin bundler

Done installing documentation for bundler after 5 seconds
1 gem installed
```

できた。

```
$ bundle init

Writing new Gemfile to ~
```
Ubuntu18.04LTS : 2080ti*2で学習したいけどよくわからんエラー吐くよ(故障)

# きっと環境構築が悪いんだろうな...
と思っていましたが，2080tiの片方だけが単純に初期不良だったっていうのがオチです．原因に気づくまでに3,4日虚無な時間を過ごしていました．Nvlink SLIも装着してたので,もしかしたらこの子が悪さしてるのかもしれないとかも思ってました.


# どんな症状？
### keras+tensorflow-gpuで学習しようとしたらエラー
全部載せきれてないですがこんな感じのエラー吐かれます.  

```:エラー
failed to synchronize the stop event: CUDA_ERROR_ILLEGAL_ADDRESS: an illegal memory access was encountered
failed to synchronize the stop event: CUDA_ERROR_LAUNCH_FAILED: unspecified launch failure
Check failed: status == CUDNN_STATUS_SUCCESS (7 vs. 0)Failed to set cuDNN stream.
```
検索したらtensorflow-gpuのバージョンを変えたらエラー吐かないよっていうコメントもありましたが、今回の場合は想定外ですね

### マザボからGPU引っこ抜いて単体テストした時のエラー
ログインした後の画面です.
ノイズがのっているうえに，ものすごく重たい.
![IMG_9260.JPG](https://qiita-image-store.s3.amazonaws.com/0/280412/ffd3142c-88b5-6bd3-0047-54b51e76c029.jpeg)
![IMG_9261 2.jpg](https://qiita-image-store.s3.amazonaws.com/0/280412/689e3b61-0ded-a51e-cd5b-c5179c84dd44.jpeg)

# 解決策
ハードそのものが悪さしてるかもしれないので，GPUを片方ずつ引っこ抜いて単体テストしましょう．2080tiはまだ発売されたばかりなので，初期不良が多いとか．こんなの当たり前だろ記事で誰が救えるかはわかりませんが,メモ程度に置いときます.
さよならGPU

# 追記
おかえりGPU
無事に修理されて動く子になりました.
その後,Nvlink SLI装着してみましたが,VRAMはプールして 11G+11G=22G にはならないらしいですね…残念
laravelのvalidatorをtinkerでちょこっとだけ試す


# 概要
laravelのvalidatorをチョコっと試す
忘れてしまうのでメモしておく

# tinkerて何。
コンソールでlaravelとかPHPをチョコっと試せる機能だ
詳しくは・・・⬇️
https://readouble.com/laravel/5.7/ja/artisan.html#tinker
（怖い人よけの為に公式も貼っておく）
https://laravel.com/docs/5.7/artisan#tinker


# laravelのバリデーションって豊富だ。
ルールがアレコレあってチョコっとだけ試したい時があるなぁ。
https://readouble.com/laravel/5.5/ja/validation.html#available-validation-rules


# tinkerを起動したら以下の様にかく
```php
# こうかくと
>>> Validator::make([''], ['data' => 'required'])->errors()->toArray()
# こう返ってくるよ
=> [
     "data" => [
       "The data field is required.",
     ],
   ]

# あとは好きに試す
>>> Validator::make(['data' => 'yeah'], ['data' => 'numeric'])->errors()->toArray()
=> [
     "data" => [
       "The data must be a number.",
     ],
   ]

```
【Python unittest】mockでリストを返してもらうときの注意

##概要
Pythonでmock使ってテスト書いてたら、リスト返してもらうところでちょっとはまったのでメモ

##mock.return_valueは参照を返す

Mockにreturn_valueとしてリストを設定

```python
#from unittest.mock import Mock を省略しています
>>> mc = Mock()
>>> mc.return_value = [0,1,2]
>>> mc()
[0, 1, 2]
```
Mockを呼び出して、返り値を編集する

```python
>>> test = mc()
>>> test
[0, 1, 2]
>>> test[0]=9
>>> test
[9, 1, 2]
```
もう一回モックを呼び出すと

```python
>>> test = mc()
>>> test
[9, 1, 2]
#[0,1,2]がほしかった
```
うーん
ちなみにこういうことをしてもだめ

```python
>>> import copy
>>> mc.return_value = copy.deepcopy([0,1,2]) #ついでにlambda:[0,1,2]もだめ
>>> test = mc()
>>> test
[0, 1, 2]
>>> test[0] = 99
>>> test
[99, 1, 2]
>>> test=mc()
>>> test
[99, 1, 2]
```
##side_effectに関数を設定しましょう
```python
>>> mc = Mock()
>>> mc.side_effect = lambda:[0,1,2]
>>> test = mc()
>>> test
[0, 1, 2]
>>> test[0]=9
>>> test
[9, 1, 2]
>>> test = mc()
>>> test
[0, 1, 2]
```
とりあえずよかった。
一度試したらクセになるメールをslackに転送する方法

## はじめに
普段、生活をしているとTwitterやSlackやメールなど様々な形で情報が入ってきます。

情報をSlackで一元管理できたらどんなに楽なことか…

エンジニアなら一度は考えたことがるのではないでしょうか？

この記事ではメールをSlackに転送する方法を書きました。

気になるメルマガをSlackのチャンネルに流すように設定するとスクロールで過去の分もすいすいチェックできるのでめっちゃ快適です！！

それでは、メールをSlackに流す方法を説明していきます。方法はいくつかあります。

## 方法その１「Slackアプリで連携する」
一番簡単なのがSlackのアプリ一覧からEmailアプリをインストールする方法です。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/331674/2f2d4c09-13a5-35c2-df4b-f80bb894109b.png)
ただし、この方法は、無料プランだと利用できません。
もしもなんらかの有料プランのワークスペースを利用していてそこにチャンネルを作れる状況ならこの方法が一番手軽に出来ます。

## 方法その２「Zapierで連携する」
違うやり方として[Zapier](https://zapier.com)を使う方法です。[Zapier](https://zapier.com)は様々なWebサービスを自動的に連携させることが出来るサービスです。このサービスを使ってメールとZapierを連携させます。無料で使用できるので私はこの方法をおすすめします。まずは[Zapier](https://zapier.com)でアカウントを作成してください。
作成したら右上にある「Make a Zap!」![image.png](https://qiita-image-store.s3.amazonaws.com/0/331674/cde9d7ce-839b-9553-bd66-dd19483b4ec9.png)というボタンをクリックします。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/331674/8362de2e-60dc-9ac0-0503-7954dcf0a069.png)

トリガーとなるアプリをまず選択します。今回はEmailをトリガーにするのでテキストボックスに「Email Parser by Zapier」を選択します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/331674/056561f6-9780-c78b-2eae-e5235e6ce90a.png)

アプリ一覧に![image.png](https://qiita-image-store.s3.amazonaws.com/0/331674/40070edf-ad52-9298-fc95-f429052195d5.png)GmailがあるのでGmailを使っているとこれを選択してしまいそうですが、私が試したところメールを受信してから10-15分ほど経ってからSlackに通知されたのでこちらは選ばない方が良いです。
「Email Parser by Zapier」はZapier内でメールアカウントを作成してそのメールアカウントに受信したメールを別のWebサービスに連携させる方法になります。こちらだと私が試したところほぼリアルタイムで通知されたのでおすすめです。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/331674/2dbf479c-8ae0-de11-1656-131358763d56.png)
下部に青文字で![https://parser.zapier.com](https://parser.zapier.com)にリンクがあるのでそこをクリックしてZapierのメールボックスを作成します。右上にある![image.png](https://qiita-image-store.s3.amazonaws.com/0/331674/495aed3a-c71d-c2dd-59c7-1b7bdbe97d99.png)をクリックすればすぐにメールボックスが作成されます。
XXXXX@robot.zapier.comのようなメールアドレスが作成されると思います。
メールアカウントを作成したらZap作成に戻り、トリガーに先程作成したメールアカウントをトリガーに選択します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/331674/15320e16-fbe9-12af-857f-19b38879148a.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/331674/ffb761df-74a4-82b7-4ea6-a56fccc6ad8e.png)
この画面がでたら青文字のリンクをクリックして今度はアクションを選択します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/331674/c5790939-d4c3-8342-693f-09d641b9e9bf.png)
アクションではもちろんSlackを選択します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/331674/ab4d2e30-82da-ecd7-b38f-7087b9b8b4a6.png)
「Send Channel Message」がおすすめです。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/331674/cead5938-1971-4045-89fa-1a193076c340.png)
ここでは送信先のSlackチャンネルやSlackで受信したときのメッセージのフォーマットを設定することができます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/331674/3e6b93bd-8bc4-4872-79d2-902bfb7410f5.png)
ここでは設定したZapの名前を入力します。
必ず下の「YOUR ZAP IS OFF」のOFFボタンをクリックしてONにするのを忘れないでください。

あとはGmailでSlackに送信したいメッセージを先程作成したメールアカウントXXXXX@robot.zapier.comに転送するようフィルタ設定すればすべて完了です。

お疲れ様でした！！快適なSlackライフを楽しみましょう(^-^)/

エンジニアに役立つ情報をTwitterでも発信していますので宜しければTwitterの方もフォローをよろしくお願いします！
[Twitterへのリンクはコチラ](https://twitter.com/mr_t_free)
vector の中の与えた値の位置を求める（c++11）

こんにちは。
値を与えて、vector 内でのその位置を求めてみました（c++11）。通常は ```find()``` で良いと思いますが、今回の動機として、set（順序付き集合）に似せた機能を、代わりに vector を用いて実現することを考えました。欲しい機能は、

- ソート、重複除去は外部から動かす（必要なタイミングに）
- ```find()``` は、代わりに ```lower_bound()``` を動かす（ソートされている場合）

```console
$ clang++ -std=c++11 find.cpp
$ ./a.out
unique vector input
11 12 10 
 0  1  2  (indices by order)

11 12 10 
 1  2  0  (indices based on value)
```

```find.cpp
#include <vector>
#include <iostream>
#include <algorithm>

#define NOTFOUND -1

typedef uint64_t my_int_t;
typedef std::vector<my_int_t> my_vec_int_t;

class MyVecInts{
private:
	bool sorted = false;
	my_vec_int_t data_;
public:
	MyVecInts() {}
	MyVecInts(std::initializer_list<my_int_t> init)
		: data_(init.begin(), init.end()) {}
	decltype(data_) data() {
		return data_;
	}
	void push(MyVecInts from) {
		copy(from.data_.begin(), from.data_.end(), back_inserter(data_));
	}
	void sort() {
		sorted = true;
		std::sort(data_.begin(), data_.end());
	}
	void sortMakeUnique() {  // sort and make unique
		std::sort(data_.begin(), data_.end());
		data_.erase(std::unique(data_.begin(), data_.end()), data_.end());
	}
	bool checkUnique() {
		decltype(data_) data_copy;
		copy(data_.begin(), data_.end(), back_inserter(data_copy));
		std::sort(data_copy.begin(), data_copy.end());
		return data_copy.end() == std::unique(data_copy.begin(), data_copy.end());
	}
    int find(my_int_t i) {
    	decltype(data_)::iterator itr;
    	if (sorted) {
    		itr = lower_bound(data_.begin(), data_.end(), i);
	    	if (itr == data_.end()) {return NOTFOUND;}
    		if (*itr != i) {return NOTFOUND;}
    	} else {
    		itr = std::find(data_.begin(), data_.end(), i);
    		if (itr == data_.end()) {return NOTFOUND;}
    	}
        return distance(data_.begin(), itr);
    }
    void print() {
		for (const auto& i : data_) {
		  std::cout << i << " ";
		}
		std::cout << "\n";
    }
};

void my_print(MyVecInts ids1, MyVecInts ids2) {
    for (const auto& i : ids2.data()) {
        std::cout << " " << ids1.find(i) << " ";
    }
}

int main() {
	MyVecInts ids = {11, 12, 10}, ids_copy;
	if (ids.checkUnique()) {
		std::cout << "unique vector input\n";
	}

	ids.print();
	ids_copy.push(ids);
	my_print(ids_copy, ids);
	std::cout << " (indices by order)\n\n";

	ids.print();
	ids_copy.sort();
	my_print(ids_copy, ids);
	std::cout << " (indices based on value)\n";
}
```
firebaseのログインについて

# 概要
まとめました。

# 環境
- CDN

# 手順
1. Authentication > ウェブ設定からconfigをコピー
2. firebaseuiの読み込み
3. uiの生成
4. ログイン画面の生成
5. ユーザー情報取得

**ログイン後の操作**
- サインアウト
- アカウント削除

※エラーは、firebaseuiが処理してくれます。

## firebaseuiの読み込み
```
<script src="https://www.gstatic.com/firebasejs/ui/3.5.2/firebase-ui-auth__ja.js"></script>
<link type="text/css" rel="stylesheet" href="https://www.gstatic.com/firebasejs/ui/3.5.2/firebase-ui-auth.css" />
```

## uiの作成
`ui`は一回だけ作成します。再度、ログイン画面を表示する場合は、同じ`ui`を使います。

```
ui = new firebaseui.auth.AuthUI(firebase.auth())
```

## ログイン画面作成

- `credentialHelper`を設定しないと、`accountchooser.com`に遷移してしまいます。
- `signInSuccessUrl`は、googleで必要になります。

```
ui.start('#firebaseui-auth-container', {
    signInSuccessUrl: '/',
    credentialHelper: firebaseui.auth.CredentialHelper.NONE,
    signInOptions: [
        firebase.auth.GoogleAuthProvider.PROVIDER_ID,
        // firebase.auth.EmailAuthProvider.PROVIDER_ID,
    ],
});
```

## ユーザー情報取得
- 自動 / ログイン / ログアウトで発生します。
   - ここを監視しとけば問題ないです。

```
firebase.auth().onAuthStateChanged((user)=> {
    console.log(user)
})
```

## サインアウト

```
firebase.auth().signOut()
```

## アカウント削除

```
user.delete()
```



# サンプル
練習用に作成しました。

- https://github.com/YamasakiKenta/190225_firebase_login

# 参考

- https://github.com/firebase/firebaseui-web/blob/master/README.md
- https://firebase.google.com/docs/reference/js/firebase.User
- https://firebase.google.com/docs/auth/
DjangoでHerokuデプロイ

基本的にローカル環境で一通り稼働したアプリケーションをHerokuにデプロイする際の
変更点を記述する。Flaskとも異なるので


①デプロイに必要なファイルはFlaskの時と同じく（修正は必要）
・Procfile
・requirements.txt
・runtime.txt
②修正する部分は
settings.py
wsgi.py

③異なる作業は
.デプロイ後のマイグレーション

-----------
まず
whitenoiseをinstallしておく

①
・requirements.txtは使用しているライブラリーに加えwhitenoiseが
うまく動かないのでversion4からverison3に下げた

・ただしアプリケーションの駆動が異なる点であり、wsgi.pyに修正が必要
　かつそのためProcfile ではgunicorn wsgiにする.つまりProcfileに以下のように記述する


Procfile

```
　web: gunicorn myapp.wsgi
```


settings.py

```
ALLOWED_HOST=[*]
```

HOSTを解放しておく。


wsgi.pyは以下のようにした。

wsgi.py

```

import os

from django.core.wsgi import get_wsgi_application

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myapp.settings')

application = get_wsgi_application()

from whitenoise.django import DjangoWhiteNoise
application = DjangoWhiteNoise(application)

```


デプロイはFlaskの時と同じ



push heroku master後にDBマイグレいとが必要だが
以下のコマンドでherokuに指示する。

```
heroku run python manage.py makemigrations
heroku run python manage.py migrate
```

おかしい部分があるような気がしたが問題なくアプリケーションが起動できた。
ちなみにDBはPostgresSQLが使用され、それはAWS上のにあるとのことらしい。

ちなみにHeroku git:remote -aアプリ名 で特手にのheroku appに接続できる。
Ruby Silverに合格したので、勉強方法をまとめてみた(2019年2月版)

(2020/12/16 追記)
Ruby Gold にも合格したのでそちらも書きました！
[Ruby Goldに合格したので、勉強方法をまとめてみた(2020年11月版)](https://qiita.com/jonakp/items/c7b7ecfe3eb9ee8c950e)

-----
先日Ruby Silverに合格した。
86点という普通ちょい上感あふれる絶妙な点数。
需要の程は分からないが、勉強方法をまとめてみる。

Ruby Silverは基本暗記Onlyで、
恐らく他のIT系の資格と比較して範囲も広くはない。
勉強にしてもできる事の幅は広くないので、
恐らく再現性は高いと思う。
(かといって決して楽だという話ではない)

# とりあえず結論
- 合格記事をさら〜っと眺める
- とにかく色々な問題集を解きまくる
- 各問題集で9割以上正答＆理由も説明できるようにする
- 仕上げに先人が残してくれた要注意情報に目を通す

# 前提
とりあえず学習開始時点での私のスペックを記載する。
以下勉強方法を読む際の参考に。

- Rubyに関しては3ヶ月独学＆研修で2週間
    - Rubyの経験は無くはない、という程度
- 他言語の経験あり
    - 大学時代 C/Javaを履修(?)
    - 会社員になってから5年程度、たまーに業務でコードに触れる程度
- IT系の知識は薄く広く
    - 基本情報は持っているとかその程度。

# 学習期間 & 学習時間
- 学習期間：約2週間
- 学習時間：約30時間

# 学習方法
## 1. 合格記事をさら〜っと眺める
"Ruby Silver", "勉強法"あたりでググって記事を眺めてみる。
勉強方法やら出題傾向やらが書いてあるので、
なんとなく雰囲気を理解する。

例えば、
- String/Array/Hashクラスのインスタンスメソッドに関する出題が多い
- 同じ機能で別の名前を持つメソッドの記憶は必須
- 破壊的メソッドとそうでないメソッドの見分けも重要
- File/Dir/Timeクラスに関しての出題もそこそこ多い
などなど。。。

細かく理解する必要はなく、そんな感じなんだなぁと思うくらいでOK。
適当にGoogle検索結果の上から5,6個いい感じのを、流し読みするくらい。

## 2. とにかく問題集を解く
具体的な対策としては、問題集を周回するのが一番手っ取り早い。
ソシャゲのマラソンみたいなノリで、ひたすら走るべし。

(ただしRubyのことを何も知らない、プログラミングもほとんどやったことない、
という人は対象外。Rubyの入門本を1冊消化した方が多分良い)

1つだけじゃ無くて、色々な問題集を取っ替え引っ替えするのがオススメ。
やってるうちに、共通点やら傾向が自然と理解できる。

私が実際に使った問題集は、主に以下の3つ。

### 公式模擬問題集
https://www.ruby.or.jp/assets/images/ja/certification/examination/exam_prep_jp.pdf
pdfと見せかけてどこぞのgithubリポジトリに飛ぶ。無料。
一番最初にやって7割弱取れた。恐らく一番難易度低め。

### REx
https://www.ruby.or.jp/ja/certification/examination/rex
受ける度に問題の内容が変わる。8割共通で残りの2割が入れ替わる。
もちろん以前の問題を再び受け直すことも可能。解説も割と書いてある。
スマホからも受けられて便利。もちろん無料。恐らく一番使った。
githubアカウントとの連携が必要。

### [改訂2版］Ruby技術者認定試験合格教本（Silver/Gold対応）Ruby公式資格教科書
https://www.amazon.co.jp/dp/B0756VF9Y3/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1
これだけ普通の書籍。
3600円と結構なお値段がするが、十分その価値はある。
問題集だけでなく、出題範囲に関する一通りの知識も記載されているので、
リファレンスとしても活用できる。

時間があるなら、3,4,5章あたりは一通り読んでおいても良い。
ただし問題集を解いた上で、不明な点に絞って読んだ方が遥かに効果がある。

## 各問題集で9割以上正答＆理由も説明できるようにする
上記で挙げたいくつかの種類の問題集で、
9割以上解ける＆理由も説明できるようになるまで、
知識の完成度を高めていく。


その際、理解するための手段は色々な方法を試すと良い。

- 問題集の解答を読む
- Ruby技術者認定試験合格教本の該当箇所を読む
- ネットで関連情報をググる(主にRubyリファレンスなど)
- irbで実際に動作を確かめる

などなど。。。
この辺りを広くやればやるほど、
応用の効く知識が身につき、恐らく本番に強くなる。
(例えば正答に関係ない選択肢でも、分からなければ積極的に調査する、など）

逆に問題集の解答を丸暗記しただけだと、
本番で足元をすくわれる可能性が高くなる、と思う。

## 仕上げに先人が残してくれた要注意問題に目を通す
本番の試験は、6,7割は問題集ほぼそのままの内容だったが、
残りは妙にひねった所のある、いやらしい内容だった。

試験の前日などに、先人が残したくれた情報に目を通すとその辺りの対策になる。

私が実際に直前に確認して助かったのは以下2つの記事。
そのおかげで多分3問くらいは助かった。

Ruby Silver試験前に見直すと幸せになれるメモ
http://tamata78.hatenablog.com/entry/2015/08/07/200454

Ruby技術者認定試験Silver version 2.1を受けて…
https://qiita.com/motty93/items/413485469e4ec665c329
Notificationのタイトルに色を付ける方法

こったプッシュ通知(notification)だと色付きのものをよく見るがそれをする方法
意外と調べても出てこなかったので掲載

```addColorMethod.kt
private fun addColor(title: String): SpannableString {
    return SpannableString(title).apply {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
            return@apply
        }
        setSpan(ForegroundColorSpan(ContextCompat.getColor(context,
                R.color.notification_job_title_text)), 0, title.length, 0)
    }
}
```

```NotificationCompatBuilderでの利用法.kt
NotificationCompat.Builder(yourContext, "yourId")
    .setContentTitle(addColor("your notification title"))
    .set .. // 中略
    .build()
```

現場からは以上です
はじめてのC++【1日目】

#１日目
昨日コメントくれた方ありがとうございました。
コメントの返信方法がよくわからなかったのでいいねボタンだけ押しときました。
unityとC#をやらない理由は、私の就職したい会社がC++を必要としているからです。そして、C++はUE4に使われているので、UE4とc++のセットで学びます。

3章から書きすすめます
※C言語を少しかじったことがあるので1~2章は流し見程度で
##03-01
####ビットとバイト
bitは0か１
byteは8bitで0~255ということ
とりあえず、適切な型を選べってことかな
####キャスト

```cpp
int x = 5;
std::cout<< (double)x <<std::endl;
```
この場合は5.0になる
これをキャストというがあまり多用すべきでない.

##03-02
値を入れて昭和かどうか判断するプログラム
実行結果
<img width="217" alt="スクリーンショット 2019-02-25 16.37.14.png" src="https://qiita-image-store.s3.amazonaws.com/0/298612/eb006889-0890-37c5-00e8-846482318128.png">

```cpp
cout << "西暦を入力してください" << flush;
```
「flush」とは？endlと何が違うのか？
ネットで調べた結果,

 「endl」＝改行した上で、バッファーをフラッシュする
 「flush」＝改行はせず、バッファーをフラッシュする

意味がわからないです。
ロベールで調べてみると（ロベールのこと忘れてた）、1-2説に解説が載っていました。

 「endl」ー改行をして文字を出力させる
 「flush」ー改行無しで文字を出力させる
  ※この２つがないと出力されないことがある
だということです。
##参照
方の後ろに＆をつけると参照ができる。

```cpp
int &x
double &x
```
など
引数を参照にしておくと、呼び出すときに使った変数の代わりになる。
このような引数の渡し方を「参照渡し」という。
ただし、参照は初期化することしかできない。
また、さんしょうさきを後から変更することもできない。
##03-03
文字コードは環境依存（環境によって与えられている数字が違う）

ややこしいキャストがあった

```cpp
(int)(unsigned char) // char型
```
これは、まずunsigned char で正の値のみにする。そして、intで数字に変換する。
##文字列
一文字一文字は配列のようにつながっている。
文字列の長さを調べるには”sizeof”がいい
そして、最後の配列の中にはnullが入っている。
"\0"はヌル文字
#####様々な変更に耐えうるプログラムを組むことはバグの抑制につながる。

##03-06プロトタイプ宣言
includeのしたに関数を定義することをプロトタイプ宣言という
プログラムが見やすくなる。
##includeの秘密
自分で作ったiostreamに依存しているヘッダファイルをiostreamより以前にインクルードするとビルドエラーが起きる

しかし自分で作ったファイルをインクルードする順番は関係なくビルドエラーが起きない。

##今日の反省
ペースが遅い
明日はクラスのところまで進めたい
cloud9でfirebaseを使おうとしたら詰まった話

## 技術書をせっせこやっていこう2
[前回](https://qiita.com/ginger893/items/efb0a80b73a0721d1a61)から引き続きcloud9で技術書をやってイグゥ！

## やってる技術書
- Vue.jsとFirebaseで作るミニWebサービス(@ 3.3 Firebaseのセットアップとデプロイ)

## 環境
[前回の記事](https://qiita.com/ginger893/items/efb0a80b73a0721d1a61)と同じ。

## firebaseと連携させていこう

firebaseと連携するにはfirebase loginを行います。
以下みたいな感じで打つと、ずらっとURLが出てくるので、

<img width="810" alt="スクリーンショット_2019-02-25_23_23_47.png" src="https://qiita-image-store.s3.amazonaws.com/0/304374/7611a4d2-f6fe-e8b2-b9fa-09e0822a2915.png">

そのURLにアクセスすると、Googleアカウントと連携することになります。
ログインしているアカウント(+ログインしたことがある&&cookie等に残ってる)が並ぶので、適切なものを選択。

<img width="473" alt="スクリーンショット_2019-02-25_23_23_59.png" src="https://qiita-image-store.s3.amazonaws.com/0/304374/682cb2c3-62d2-ef4d-6520-8d00b1616a61.png">

Firebase CLIが以下の権限を使いますよーというよくあるやつ。
~~細かいことは考えずに~~ 一応ちゃんと読んでから許可していきましょう。

<img width="484" alt="スクリーンショット_2019-02-25_23_24_06.png" src="https://qiita-image-store.s3.amazonaws.com/0/304374/b7aaf53f-1462-30d8-797b-169f49aff3ed.png">

するとこんな画面が…

<img width="599" alt="スクリーンショット_2019-02-25_23_24_14.png" src="https://qiita-image-store.s3.amazonaws.com/0/304374/424c59a9-b465-cd8c-06af-acfaee98dc01.png">

**えぇー…(ドン引き)**

## オプションを見てみる

エラー画面のURLに「localhost」とある通り、firebaseはローカルで開発することを前提としているっぽい。
何かオプションあるかなー？と掘ってみると、

<img width="815" alt="スクリーンショット 2019-02-25 23.43.38.png" src="https://qiita-image-store.s3.amazonaws.com/0/304374/b13b576f-be70-8ac3-135e-0dfab11c0144.png">

「--no-localhost」、そういうのもあるのか！

## 再チャレンジ！

「--no-localhost」をつけてfirebase loginを再実行すると、さっきとは異なりペーストする欄が出てきます。

<img width="811" alt="スクリーンショット_2019-02-25_23_45_46.png" src="https://qiita-image-store.s3.amazonaws.com/0/304374/dfd882ce-6105-c0f1-f557-e9ac68725922.png">

提示されたURLにアクセスして、アカウントの選択と権限を確認すると、貼り付けるためのコードが表示されます。

<img width="515" alt="スクリーンショット_2019-02-25_23_45_35.png" src="https://qiita-image-store.s3.amazonaws.com/0/304374/2d300963-607b-316f-d63f-7e316c8c59b0.png">

表示されたコードをコピーして、ペーストする欄に貼り付けると「Success!」。

<img width="811" alt="スクリーンショット_2019-02-25_23_46_01.png" src="https://qiita-image-store.s3.amazonaws.com/0/304374/627d434c-1e1c-685e-74d3-b1e461214767.png">

以上、お疲れ様でした。

## 参考資料

[Cloud9からfirebase loginする時のエラー回避の方法](https://blog.f-arts.work/archives/817)
世界一わかりやすいAndroid Things + Rainbow HATの使い方〜14セグメントディスプレイ編〜

## はじめに
[Android Things](https://developers-jp.googleblog.com/2019/02/an-update-on-android-things.html?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+GoogleJapanDeveloperRelationsBlog+%28Google+Japan+Developer+Relations+Blog%29) + [Rainbow HAT](https://shop.pimoroni.com/products/rainbow-hat-for-android-things)を購入してチュートリアルを試してみたものの、次に何をしたら良いか分からない人（自分がそうでした）のために、何かを作るモチベーションになれば良いなと思い記事にしてみました。
14セグメントディスプレイは、何となく英数字は表示できることは分かるけど、どこまでの文字表示に対応しているかを調べるのにそこそこ時間がかかったので、同じ疑問を感じた方の時間短縮になれば幸いです。

## 表示の元となるフォントデータ値と実際の表示
### サンプルコード
```
private AlphanumericDisplay mSegment;
...
// 初期設定
mSegment = RainbowHat.openDisplay();
mSegment.setBrightness(Ht16k33.HT16K33_BRIGHTNESS_MAX);
mSegment.setEnabled(true);

// 表示内容変更
for (int i = DATA[0]; i < DATA.length; i++ ) {
    char b = (char) i;
    // 引数: 文字値, ディスプレイ番号(0-3), ドット表示の有無
    mSegment.display(b, 0, false);
    // 1秒(1000ms)毎に表示切り替え
    SystemClock.sleep(1000);
}
```

### フォントデータ値が存在するソースコード
[androidthings/contrib-drivers](https://github.com/androidthings/contrib-drivers/blob/master/ht16k33/src/main/java/com/google/android/things/contrib/driver/ht16k33/Font.java)

### 実際の表示
|Font.DATA[24]|Font.DATA[48]|Font.DATA[49]|Font.DATA[50]|
|:------------------:|:------------------:|:------------------:|:------------------:|
|0b0001001011001001|0b0000110000111111|0b0000000000000110|0b0000000011011011|
|![0b0001001011001001.PNG](https://qiita-image-store.s3.amazonaws.com/0/362837/aab524f2-efe9-63ff-bd76-58450899f97f.png)|![IMG_4697.PNG](https://qiita-image-store.s3.amazonaws.com/0/362837/df30ead2-1b0d-5355-ef6a-08f9deff5a43.png)|![IMG_4698.PNG](https://qiita-image-store.s3.amazonaws.com/0/362837/3360365a-d92f-9d8d-b897-5b747f177da2.png)|![IMG_4699.PNG](https://qiita-image-store.s3.amazonaws.com/0/362837/d533cfc8-79fc-ab0c-4c8d-abcd1b301d74.png)|

|Font.DATA[51]|Font.DATA[52]|Font.DATA[53]|Font.DATA[54]|
|:------------------:|:------------------:|:------------------:|:------------------:|
|0b0000000010001111|0b0000000011100110|0b0010000001101001|0b0000000011111101|
|![IMG_4700.PNG](https://qiita-image-store.s3.amazonaws.com/0/362837/d4a678a2-4e89-3e36-fa31-594544ed7b95.png)|![IMG_4701.PNG](https://qiita-image-store.s3.amazonaws.com/0/362837/e6dad606-2be2-f107-74dc-45ae0302275c.png)|![IMG_4702.PNG](https://qiita-image-store.s3.amazonaws.com/0/362837/d2e07d9c-7716-041a-abb8-74cec7956126.png)|![IMG_4703.PNG](https://qiita-image-store.s3.amazonaws.com/0/362837/4430f6a2-5b24-799b-37fa-7fd68d33d8d2.png)|

|Font.DATA[55]|Font.DATA[56]|Font.DATA[57]|
|:------------------:|:------------------:|:------------------:|
|0b0000000000000111|0b0000000011111111|0b0000000011101111|
|![IMG_4704.PNG](https://qiita-image-store.s3.amazonaws.com/0/362837/368a9e55-7281-234f-0d18-3c5405916934.png)|![IMG_4705.PNG](https://qiita-image-store.s3.amazonaws.com/0/362837/69672920-b21d-07aa-ef00-7d062344efaa.png)|![IMG_4706.PNG](https://qiita-image-store.s3.amazonaws.com/0/362837/9ab1afee-d621-aa55-2319-d0dbaed152d1.png)|

## おわりに
本当は、表示可能な文字の画像を全て載せようと思い動画だけは撮っているのですが、数字の分を加工した段階で力尽きました。。。
もしコメントなどで要望があれば追記したいと思います。
IntelliJでJavaScriptのconsole.logをショートカットで書く

普段はJavaScriptをIntelliJで書いております。
JavaScriptを書くときにconsole.logはよく使うと思いますが、長くて記入するのが面倒ですよね。
そこで便利なショートカットを紹介します。

```javascript
const x = 3;

x.log // ここでtabキーを押すと
console.log(x); //これに変化します。
```

このように、ログしたい変数.logと記入してtabキーを押すと、その変数をconsole.logにぶち込むことが出来ます。
## 終わりに
私は現在、Web3のサービスの開発をしています。詳しくはこちらの記事をご覧下さい。
        [無料でイーサリアムが当たる、Web3時代の寄付サイトを作った話](https://note.com/kenroda/n/n814347fbdcd7)
【 Laravel 】配列の参照渡しをするならば、代わりにコレクションを使う方が良さそう

## コレクション :book:
コレクションは、配列データを操作するためのクラスです。

配列で参照渡しを行う必要が出てきた場面で、Laravelの場合にはコレクションを使った方が良さそうです。参照渡しは便利ですが以下のようなデメリットがあります:thinking:

### 参照渡しのデメリット :point_up:  

* 参照渡しの `&` に気づきにくい。 
* 影響範囲が分かりにくくなる。

そのためにミスや間違いが多くなってしまいます。


### 配列の参照渡しを使う例

配列に参照渡しで値を追加するコード:robot:

```
public function getIndex()
{
    $array = [];

    // 参照渡しで3回実行
    $this->appendValue($array);
    $this->appendValue($array);
    $this->appendValue($array);

    // 配列の確認
    var_dump($array);
}


// 引数に配列の参照渡し
public function appendValue(array &$array)
{
    $array[] = 'value';
}


--------------------------------------------------------

出力結果↓↓↓

// var_dump($array);
array (size=3)
  0 => string 'value' (length=5)
  1 => string 'value' (length=5)
  2 => string 'value' (length=5)
```

`&` に気づきにくく、配列を初期化しているにも関わらず代入をしていないので影響に気づきにくいです。:taco:

配列に対して、returnをせずに中身の変更や追加をしたい場合には参照渡しよりもコレクションを作ってしまった方が影響範囲を狭くできます。:point_up:

### 代わりに、コレクションを使う例 

例としては以下の通りです。

```
public function getIndex()
{
    // collect()ヘルパでインスタンスを作成
    $collection = collect();

    // コレクションへの追加を3回実行
    $this->appendValue2($collection);
    $this->appendValue2($collection);
    $this->appendValue2($collection);

    // コレクションの確認
    var_dump($collection);

    // コレクションを配列形式で確認
    var_dump($collection->all());
}

// 引数にコレクションを指定
public function appendValue2(\Illuminate\Support\Collection $collection)
{
    $collection->push('value');
}

--------------------------------------------------------

出力結果↓↓↓

// var_dump($collection);
object(Illuminate\Support\Collection)[422]
  protected 'items' => 
    array (size=3)
      0 => string 'value' (length=5)
      1 => string 'value' (length=5)
      2 => string 'value' (length=5)


// var_dump($collection->all());
array (size=3)
  0 => string 'value' (length=5)
  1 => string 'value' (length=5)
  2 => string 'value' (length=5)
```

以上のように配列の参照渡しと同様のことをコレクション化しても実現できます。:raising_hand:

## まとめ 
参照渡しの配列を使う場合...
同じ操作をコレクションでも実現できるので、どうしても配列型でなければならないケース以外はコレクションで渡した方が良いです :grinning:
ざっくりStruts2

# Struts2のインターセプタについてざっくりまとめてみる
プログラミング業界に入っておよそ1年半が経った。 
当然まだ知らないことだらけ。大体のことは「何だそれ、、」「何だっけこれ、、」から始まる。
学ぶことがたくさんあるのは良いことだが、仕事中以外のアウトプットが無いに等しいので練習がてら記事を書いてみる。

今回は知識整理も兼ねて、現場で使っているフレームワークであるStruts2についてかなりざっくりだがまとめる。
Qiitaには既に他の筆者の良記事は大量にあるので、引用とともに掲載させていただく。


# アジェンダ
・struts2とは
・struts2におけるMVCモデル
・Interceptor（インターセプタ）

## Struts2とは
Webアプリケーションフレームワークの1つ。
一般にStrutsというと「Ver1.x系」、Struts2というと「Ver2.x系」を指す。
Struts2といっても元は「WebWork2」というフレームワークが名称変更した結果であり、Struts1とは設計背景から異なる（知らなかった）。

## struts2におけるMVCモデル
#### そもそもMVCモデルとは
M(Model)V(view)C(Controller)の略であり、機能で分けて実装するコーディングモデルのこと。ざっくり。

#### Struts2では
![struts_2_architecture.gif](https://qiita-image-store.s3.amazonaws.com/0/367247/cc8f25a6-2054-18f9-0657-5de7d426e790.gif)
（図１）

Model：Actionクラスに代表され、入力データの保持や操作を行う。ActionクラスのほかにBusinessクラスやModel、Entityクラスもこれに含まれる。
View：JSP。Strutsの場合は"S:～"で始まるような独自のタグライブラリを持つ。（例：s:formでformタグ）
Contoroller：代表的なものはInterceptor(インターセプタ）クラス。クライアント（ユーザ）からの入力データをModelに渡す。

## Interceptor(インターセプタ）
#### Interceptor(インターセプタ）とは
□英語の意味
Interceptor：横取りする人、さえぎる人、迎撃機

Modelの主要となるActionクラスによる処理の前後に、インターセプタの設定に基づいて処理を挟み込むことができる。
![struts_2_interceptor.gif](https://qiita-image-store.s3.amazonaws.com/0/367247/2d6d9875-8fbf-0784-a85e-a08943fbadd2.gif)
（図２）


つまり、クライアントからデータを受け取ってActionクラスに渡す前に、バリデーションやトークンチェックなどの共通処理を行うことができる。

インターセプタの定義はstruts.xmlで行う。


```
<struts>
    <package name="hoge-package" extends="json-default" abstract="true">
<!-- インターセプタ定義 -->
        <interceptors>
<!-- インターセプタ・クラス定義 -->
            <interceptor name="sample" class="sample.sample"> 
            <interceptor name="hoge" class="hogehoge.sample"> 
        </interceptor>
<!-- インターセプタ・スタック定義 -->
            <interceptor-stack name="samplestack1">
                <interceptor-ref name="xxx" />
                <interceptor-ref name="yyy" />
            <!-- 上記のように、複数のインターセプタをひとまとめに構築できる -->
            </interceptor-stack>
        </interceptors>
    </package>
</struts>
```
機能ごとにxmlファイルを分けることも可能で、その場合はstruts.xmlの中で他のファイルをインクルードしてあげればよい。

```
<!-- インクルード -->
<include file="sampleA.xml">
<include file="sampleB.xml">
```
また、このインターセプタはクラス単位だけでなくメソッド単位での実装も可能。
・AbstractInterceptor（クラス単位）
・MethodFilterInterceptor （メソッド単位）

\*の部分にメソッド名を指定してあげればよい。

```
<interceptor-ref name="samplestack1" />
<!-- インターセプタを有効にする場合はインターセプタ名.includeMetohds -->
    <param name="xxx.includeMethods">*</param>
<!-- インターセプタを無効にする場合はインターセプタ名.excludeMetohds -->
    <param name="yyy.excludeMethods">*</param>
</interceptor-ref>
```

##### 参考文献
[Strutsのバージョンについて]
http://write-remember.com/archives/4983/
[【超初心者向け】Struts2超入門 - 2018年版]
https://qiita.com/tarosa0001/items/889faa2ab5853005f26b
→Strutsとはから始まり、導入メリットと環境構築手順についてわかりやすくまとめられています。
[Struts 2 - Architecture] ※図１の引用先
https://www.tutorialspoint.com/struts_2/struts_architecture.htm
→StrutsにおけるMVCモデルの解説
[MVCモデルについて]
https://qiita.com/s_emoto/items/975cc38a3e0de462966a
→他の筆者によるMVC説明記事です
[インターセプタ(interceptor)]
https://qiita.com/alpha_pz/items/f155b1ba1b5de4bd0a26
→Struts2のインターセプタに焦点を当ててまとめられている記事です。
[Struts 2入門（4）～インターセプターという仕組み～]※図２の引用先
https://codezine.jp/article/detail/3264
14日目。HTML&CSSの課題にとりくみました。

#14日目。今日はProgateのHTML&CSS中級編

デザインしたらHTMLにしたいし、CSSってなんだこりゃ、だったのですが。
段を組んだり、ボタンを作ったり。いろんな手順を一つ一つ丁寧に進めていって。

#完成しました！

いやー
うれしいですね！！！
ど素人でもこんなにおしゃれなものができると。
HTMLの本を買ったこともあったのですが、いままでは途中でめんどくさくって「いいじゃん読めれば」と放り出してきたのですが・・・。このページを作る手順はなんと１８段階に分けて、その中でさらにステップごとに丁寧に解説しています。いやー完成しましたよ！また言うってくらいうれしいです。

完成したページはこちらです。
http://appdays.herokuapp.com/Day14/


##HTML＆CSS中級編
学べること一覧

１章　レイアウトを作ろう
目標物を確認しよう
全体のレイアウトを作ろう

２章　トップ部分を作ろう
トップの部分を作っていきましょう。
トップ部分のレイアウトを作ろう
透明度、文字の間隔を調整しよう
ボタンを作ろう
レイアウトを整えよう
アイコンを使おう

3章　ヘッダーを作ろう
ヘッダーの部分を作っていきましょう。
ヘッダーのレイアウトを作ろう
ログインリンクを作ろう
ログインリンクを完成させよう


４章　レッスン一覧部分を作ろう
レッスン一覧の部分を作っていきましょう。
レッスン一覧のレイアウトを作ろう
レッスンを並べよう
レイアウトを整えよう

５章　メッセージ部分を作ろう
メッセージの部分を作っていきましょう。
メッセージ部分のレイアウトを作ろう
立体的なボタンを作ろう
クリック時に変化をつけよう

６章　フッターを作ろう
フッターの部分を作っていきましょう。
フッターを作ろう

７章　ヘッダーを固定しよう
ヘッダーを固定しましょう。
ヘッダーを固定しよう
JavaScript よく使うもの まとめ

## プログラミングをはじめて・・・
Qiitaで学んだことをまとめていこうと思い、4~5ヶ月前にアカウントを作成しました。
ただ、インプットするのが楽しくなってしまいアウトプットをなかなかできていませんでした。
アウトプットをしないせいで覚えが悪く、、といった悪循環。
ブログをやればまとめる力もつくということで、続けていこうと思います。

## JavaScript よく使うもの まとめ

### 'use strict' 
これをscriptタグ内のはじめにつけると、
ブラウザが厳密なエラーチェックをしてくれるようになります。
間違いがあったときに見つけやすくなります。

### document.getElementById('〜')
document　は文章全体のことです。
getElementById('〜')　は指定した id を持つ要素を取得するという意味。

### EventListener
イベントを追加するときに使用する。
ex.) クリックイベント、ドラッグイベントなど

### toggle
クラスがついていたら外す、ついていなかったらつける、といった処理をしてくれます。

---
### 会社紹介

**株式会社 Mosaica**  
最先端テクノロジーで社会課題を解決し、持続可能な未来を創造する IT カンパニー。
AI ソリューション、クラウド統合、DX 推進、経営コンサルティングなど包括的なサービスでビジネス変革を支援しています。  

詳しくは [公式サイト](https://mosaica.co.jp/) までお気軽にご相談ください。
公式サイト： https://mosaica.co.jp/
プログラミング学習記録9〜関数は関数でいいのか問題〜

##今日やったこと
- Progate JavaScript4,5,6

クラス、インスタンスも最初はわけわからなかったのですが、結局関数と同じように楽にコードを書くため（読むため）にあるんだな〜〜というのは理解できました。

これはおそらく他にも思っている方がいると思うのですが、プログラミング言語によく出てくる「関数」という言葉は、関数ではなく別の言葉にした方がわかりやすいのではないかと思います。

私的にはウェポンとかマテリアの方がしっくりきますね。

他にもなんかいい表現が思いついたらまた書きます。

###Progate JavaScript4 感想
JavaScript4のレッスンで「コンストラクタ」という初めて聞く単語が出てきたが、概念はRubyでやったinitializedと同じだったので、すんなり理解できました。

これもまた先ほど書いたクラス、インスタンスと同じように楽にコードを書くため（読むため）にあるんでしょうね。きっと。

###Progate JavaScript5 感想
JavaScript5のインポート、エクスポートがいろんなファイルでぐるぐるしてて、こんがらがってしまいました。

このレッスンはあと２周くらいして理解を深める必要がありそうです。

どこからエクスポートしてて、どこでインポートするのかを一つずつ確認しながらもう一度挑戦したいと思います。

###Progate JavaScript6 感想
配列を操作するメソッドについて学びました。

誰かが作った便利なプログラム（パッケージ）をimportして利用できるのは便利でいいですね。


ということで、明日からも引き続きプログラミング学習を頑張っていきたいと思います。

おわり
GASでSlackのinteractive messageの作成 ① Webhookアプリ編

Google Apps Scriptでとあるメッセージを元に選択肢を返し、その選択肢に応じて反応するbotみたいなものを簡易的に作成。

ChatOps目指してデプロイフローを構築するための前弾として

## 今回作るもの
- Slackのmessageに対し反応するアプリ
- アプリ設定

## 1. Slackでアプリ作成
1. https://api.slack.com/ から右上の`Your Apps`をクリック
2. 真ん中あたりの`Create New App`をクリック
3. アプリ名と適用するWorkSpaceを設定して作成
4. アプリ一覧から先ほど作ったアプリ名をクリック
5. サイドバーにある`Incoming Webhooks`を選択
6. `Add new Webhook to Workspace`をクリックしチャンネルを指定し連携する。
7. URLが発行される。（のちのコードで使う）

## 2. コードの作成

今回はこのコードで書きました。
エラーハンドリングとかまでは詳しくやっていないです。（簡易的なので）
SlackがこのアプリのURLを叩き、`doPost`が作動するようになっています。

``` doPost.gs
function doPost(e) {
  var params = JSON.parse(e.postData.getDataAsString());
  var response = {};
  if(params.type === 'url_verification') {
    response = {'challenge':params.challenge};
  } else if(params.type === 'event_callback'){
    if(params.event.type == 'message') {
      response = eventHandler(params.event);
    }
  }
  
  return ContentService.createTextOutput(response).setMimeType(ContentService.MimeType.JSON);
}

function eventHandler(event){
  if(event.text == 'dinner') {
     return sendSlack();
  }
  return {};
}
```

`
  if(params.type === 'url_verification') {
    response = {'challenge':params.challenge};
` ここの表記は認証時のパラメーターにSlack側から`challenge`を送られてくるので、challengeで返すように書いています。
普段は`else if`部分を通ります。

今回は`dinner`というチャットに対して反応するように作成しました。
SpreadSheetに記入した文字に対して反応するように追加改修する予定

### slackでテキストを生成して送るところを別ファイル化

``` sendSlack.gs
function sendSlack() {
  
  var url = "https://hooks.slack.com/services/YOUR_SLACK_HOOK_URL"
  var payload = createPayload()
   var options =
   {
     "method" : "post",
     "contentType" : "application/json",
     "payload" : JSON.stringify(payload)
   };
  return UrlFetchApp.fetch(url, options);
}

function createPayload() {
  var attachments = [{
            "text": "どっち食べたい?",
            "fallback": "Sorry, no support for buttons.",
            "callback_id": "ButtonResponse",
            "color": "#3AA3E3",
            "attachment_type": "default",
            "actions": [
              {
                    "name": "button",
                "text": "お寿司:sushi:",
                    "style": "primary",
                    "type": "button",
                    "value": "お寿司"
              },
              {
                    "name": "button",
                "text": "しゃぶしゃぶ:cut_of_meat:",
                    "style": "danger",
                    "type": "button",
                    "value": "しゃぶしゃぶ"
              }
            ]
          }];      
  
  return {
     "attachments": attachments,
     "username" : "InteractiveNotification",
    　　"text": "todays dinner"
   };
}
```

## 2. アプリの作成
1. GASの上部メニューより、`公開` → `ウェブアプリケーションとして公開`
1. 一番下の`アプリケーションにアクセスできるユーザー`を`全員（匿名ユーザーを含む）`にする。
1. `更新`を押す
2. URLが発行されるので残しておく。

## 3. Slackアプリの設定
1. Slackアプリ設定ページのサイドバーに`Event Subscriptions`という項目があるので選択
2. GASのアプリ作成時に発行されたURLに`Request URL`に貼り付ける
3. `Subscribe to Workspace Events`にある`Add Workspace Event`をクリックして、`message.channels`をセットし保存する。
4. `dinner`とチャンネルに書き込みアプリから返答が来たら完成！
ユーザーのフォロー・フォロワー一覧から一括ブロックするやつ

Twitter用。ただのメモです。

```js
a=Array.prototype.slice.call(document.querySelectorAll("div.ProfileCard-content div.dropdown"));

a.forEach(function(e) {
    e.querySelector("button").click();
    e.querySelector("li.block-text button").click();
    dialog = document.querySelector("#block-dialog");
    dialog.querySelector("button.block-button").click();
})
```
Gitのcommitメッセージを複数行入れる方法

## -mオプションを使う方法

よくコミットの説明で出てくる`-m`のオプション。
このオプションを複数使うことでメッセージも複数になります。
ただ仕様なのかメッセージの間に1行分隙間が空いてしまうようです。

__例.__

```bash
$ git commit -m "hoge" -m "piyo"
```

__結果.__

```bash
commit 728861eb41697c4f7b4943f8e7215c6cf0622663
Author: User
Date:   Mon Feb 25 13:05:45 2019 +0000

    hoge

    piyo
```

## ヒアドキュメントを使う方法
コミットの際に`git commit -F- <<EOM`と入力すると、`EOM`と入力するまで文字を入力することができます。

__例.__

```bash
$ git commit -F- << EOM
> foo
> bar
> EOM
```

__結果.__

```bash
commit 401ce885fb46915d35664b88a8fbbf5ae05041c8
Author: User
Date:   Mon Feb 25 13:11:52 2019 +0000

    foo
    bar
```

## エディタを使う方法

ターミナル上のエディタ(VimやEmacs、nanoなど)が使えるのであればこれが一番シンプルに使いやすいです。
使い方は簡単で、`-m`のオプションを__付けずに__コミットをするだけです。
これでGitのデフォルトに設定されているエディタ(標準ではnano)が開くので、あとは好きなように記述してエディタを終了するだけで完了です。

__例.__

```bash
$ git commit
```

```vim:Vim
hogepiyo
foobar
```

__結果.__

```bash
commit d3e81e0f05c380e4637662b302936dd07c320172
Author: User
Date:   Mon Feb 25 13:50:18 2019 +0000

    hogepiyo
    foobar
```
Azure DevOpsでPullRequestが発生したらBuildを行うようにしたい

GitHubとかでできたあの感じです。

tl;dr
-------

ドキュメントに書いてあります。

https://docs.microsoft.com/en-US/azure/devops/repos/git/branch-policies#build-validation

Azure Repos→BranchesからブランチのBuild Policiesを開き、Build Validationを有効にする（設定をする）。

詳しい設定手順はドキュメントに図付きで出ている。
でも英語が読めないのでほとんどわかっていない・・・時間があればちゃんと読みたい。


動作イメージ
------------

Build Validationの設定後、そのブランチに対してPullRequestを作成すると、Buildが行われる。
以下はビルドの履歴。トリガーが「Pull request build for ...」という形になり、PullRequestをトリガにして行われた事がわかる。


![実行イメージ](https://qiita-image-store.s3.amazonaws.com/0/52527/f25b79b1-c043-aa81-b7f0-840085ec1700.png)
（下から手動実行時、ブランチ更新時、PullRequest実行時）


### おまけ：Build時とPullRequest時で異なる環境変数メモ

PullRequest(PR)にビルド結果の情報を連携したいときに、PRの番号が取れないと困るが取れるのか？と疑問に思ったので、ビルドマシン上で環境変数をdumpして差分をみてみた。どちらもHostedなubuntu 16.04。

`BUILD_REASON`と`BUILD_SOURCEBRANCH`変数が異なり、`SYSTEM_PULLREQUEST_`で始まる変数が加わっている。

|変数名 | Build時 | PullRequest時 |
|-----|----|----|
|`BUILD_REASON` | `IndividualCI` | `PullRequest` |
|`BUILD_SOURCEBRANCH` | `refs/heads/master`（ビルド時のブランチ） | `refs/pull/2/merge` (PRの番号が2の場合) |
|`SYSTEM_PULLREQUEST_PULLREQUESTID`| - | `2` (PRの番号が2の場合)|
|`SYSTEM_PULLREQUEST_SOURCEBRANCH`| - | `refs/heads/feature/update-pipelines`（PRのブランチ名） |
|`SYSTEM_PULLREQUEST_SOURCECOMMITID`| - | `cc86efe4ab885b7e3973074f4f30c4ec3345fdc5` （PRのコミットID） |
|`SYSTEM_PULLREQUEST_SOURCEREPOSITORYURI`| - | `https://ユーザ名@dev.azure.com/組織名/プロジェクト名/_git/Gitリポジトリ名` |
|`SYSTEM_PULLREQUEST_TARGETBRANCH`| - | `refs/heads/master` |

変数名が`SYSTEM`始まりで見落としてた。調べたらこの辺りはドキュメントに書かれていた。ドキュメント嫁。

https://docs.microsoft.com/en-us/azure/devops/pipelines/build/variables#system-variables

ここまで来たら、PR番号を使ってコメントを投げる部分もやりたいが、週末頑張る。
なお、PRのアクションに合わせてRelease実行するには、単純にmasterブランチのマージをトリガにすればよさそう。
ORACLEとSQLSERVERでのTIMESTAMP型の違い


ORACLEのTIMESTAMP型の項目をSQLSERVERにそのままリプレイスすると
処理内で登録/更新しようとした際に以下のようなエラーになる

・登録
>timestamp 列に明示的な値を挿入できません。timestamp 列を除外する列リストを指定して INSERT を使用するか、timestamp 列に DEFAULT を挿入してください。

・更新
>timestamp 列は更新できません。


## Why？
ORACLEでは日時を表す型としてTIMESTAMP型を使用しているが、
SQLSERVERではTIMESTAMP型は少し位置づけが異なるため。


SQL ServerのTIMESTAMP型はユーザーによって設定されない想定の型であるため、上記エラーになるとのこと。
※中身もバイナリっぽいですので、そもそもそのまま人が見ることは想定しない項目の様子。

なので、datetime もしくは datetime2にする必要がある。

https://docs.microsoft.com/ja-jp/sql/t-sql/functions/date-and-time-data-types-and-functions-transact-sql?view=sql-server-2017

どっちが悪いとかではないんだろうけど、同じ型名で全然違うものを示すのはやめてほしいところ。
GitHub 上にある自作の npm パッケージを dependencies に指定する方法

## はじめに

npm は GitHub や BitBucket を npm パッケージの置き場所に指定できます。
ここではその方法について説明します。

## プライベートリポジトリの場合

自作の npm パッケージを開発しているとき、開発したリソースをプライベートな場所に置きたい場合があります。
プライベートリポジトリの場合は認証を通す必要があるのですが、やり方が2通りあって、以下のようにします:

### 1. SSH config に github.com の接続情報を登録しておく

```
Host github.com
  User git
  Port 22
  Hostname github.com
  IdentityFile ~/.ssh/id_rsa
  TCPKeepAlive yes
  IdentitiesOnly yes
```

ここでは方法は紹介しませんが、事前に個人認証用のキーペアを生成しておき、秘密鍵を `~/.ssh/id_rsa` におきます。
また、 GitHub に public キーを登録しておきます。

### 2. アクセストークンをつかう

以下の方法で事前にアクセストークンを取得しておきます。
https://help.github.com/en/articles/creating-a-personal-access-token-for-the-command-line

`package.json` の `dependencies` に以下のように指定します:

```
"package-name": "git+https://<github_token>:x-oauth-basic@github.com/<user>/<repo>.git"
```

たいてい `package.json` は Git 管理するため、アクセストークンを埋め込みたくないと思うので、1の方法を使うのが一般的だと思います。

## GitHubリポジトリを指定する (基本)

`package.json` の `dependencies` に以下のように指定します。

`git+ssh://git@github.com/<user>/<repo>.git#[branch|tag|commit]`

### 常に最新のmasterを参照させる場合

最新の master に固定されます。
ただし、 package-lock.js にはコミットIDが含まれるので、リモートを更新したら `npm update` が必要。

```json
  "dependencies": {
    "hikyaku-lib": "git+ssh://git@github.com/<user>/<repo>.git"
  }
```

### タグを指定する場合

`v3.0.0` というタグのついたコミットに固定します

```json
  "dependencies": {
    "hikyaku-lib": "git+ssh://git@github.com/<user>/<repo>.git#v3.0.0"
  }
```

### コミットを指定する場合

```json
  "dependencies": {
    "hikyaku-lib": "git+ssh://git@github.com/<user>/<repo>.git#8a9bb6d32a6899ccecd6ba0b6cfff330a37bbbb6"
  }
```

### ブランチを指定する場合

```json
  "dependencies": {
    "hikyaku-lib": "git+ssh://git@github.com/<user>/<repo>.git#dev"
  }
```

### セマンティックバージョニングを指定する場合

```json
  "dependencies": {
    "hikyaku-lib": "git+ssh://git@github.com/<user>/<repo>.git#semver:^2.0.0"
  }
```

## 参考

* https://stackoverflow.com/questions/28728665/how-to-use-private-github-repo-as-npm-dependency
* https://stackoverflow.com/questions/14187956/npm-install-from-git-in-a-specific-version
* https://stackoverflow.com/questions/46452335/version-number-annotation-for-private-repositories-with-npm