OmniAICreator/Qiita-1.07M huggingface dataset:
Python Library メモ

# Oil and Gas Subsurface

### obspy
Seismic data の読み書き、編集
https://github.com/obspy/obspy/wiki

### bruge
Geophysics tool (signal processing, rock physics, forward modeling, etc.)
https://github.com/agile-geoscience/bruges

### lasio
Las file の読み書き、編集
https://lasio.readthedocs.io/en/latest/

### welly
Well log の読み書き、編集、表示
https://github.com/agile-geoscience/welly

### pint
単位変換
https://pint.readthedocs.io/en/0.10.1/

# Machine Learning / Deep Learning
### TensorFlow
https://www.tensorflow.org/

### scikit-learn
https://scikit-learn.org/stable/

### Keras 
https://keras.io/

### XGBoost
Shallow Learningで使用
https://xgboost.readthedocs.io/en/latest/

### LightGBM
Shallow Learningで使用、文字通りXGBoostよりも計算負荷が軽い。
https://lightgbm.readthedocs.io/en/latest/

### umap-learn
次元削減で使用。
https://pypi.org/project/umap-learn/

### HDBSCAN (Hierarchical Density-Based Spatial Clustering and Applications with Noise)
クラスタリングに使用。
https://pypi.org/project/hdbscan/

# Natural Language Processing
### PyPDF2
ヘッダー情報等を含むPDFファイルをテキストファイルとして変換する際に使用。
https://pypi.org/project/PyPDF2/

### nltk
言語処理の前処理に使用。また、word2vecをロードする際にも使用。
https://www.nltk.org/index.html

### gensim
Topic modelling, document indexing and similarity retrieval with large corpora
https://pypi.org/project/gensim/

### wordcloud
Visualize words with different sizes depending on its importance
https://pypi.org/project/wordcloud/

# GIS
### GeoPandas
シェープファイル、Geojson等の地理データの読み書き、ポリゴンの作成等に使用。
http://geopandas.org/

### descartes
GeoPandasを使ってポリゴンを描画するためのライブラリ
https://pypi.org/project/descartes/

### mapclassify
GeoPandas上でカラーマップを描画するためのライブラリ
https://pypi.org/project/mapclassify/

### cenpy
アメリカの国勢調査APIを使用するためのライブラリ
https://github.com/cenpy-devs/cenpy

### Fiona
Visualization via interactive Leaflet maps
https://github.com/python-visualization/folium

### bokeh
Interactive visualization library browsers
https://github.com/bokeh

### Rasterio
Read Raster files
https://rasterio.readthedocs.io/en/latest/

### PySAL
Spatial data analysis
http://pysal.org

###
PyShp
The Python Shapefile Library (PyShp) reads and writes ESRI Shapefiles in pure Python.
https://github.com/GeospatialPython/pyshp

# Utility

### tqdm
For loopの経過をプロセスバーで表示。
https://github.com/tqdm/tqdm

### keras_tqdm
Kerasのモデルトレーニングの際に、バッチとエポックの経過をプロセスバーで表示。
https://github.com/bstriner/keras-tqdm

### cupy
GPUを使った並列計算用のライブラリ、C++の知識が必要。
https://github.com/cupy/cupy

### PyCUDA
GPUを使った並列計算用のライブラリ、C++の知識が必要。
https://documen.tician.de/pycuda/

### Plotly-express
インタラクティブにプロットするためのライブラリ。
https://plot.ly/python/plotly-express/
VSCodeのvimキーバインドをいい感じにする

## はじめに

今更ながら [Atom](https://atom.io/) から [VSCode](https://code.visualstudio.com/) に乗り換えました。
そこで早速 [VSCodeVim](https://github.com/VSCodeVim/Vim) をインストールし快適なvimライフ(?)を送っていたのですが、いくつかキーバインドに不満があったので設定してみました。
基本的には `vimrc` で書いている設定をそのまま利用できるので、わざわざ記事を書くまでもないかもしれませんが、同じような不満を抱えている方の参考になれば幸いです。

## 1. Escキーで検索のハイライトを消す

```json:setting.json
{
    "vim.normalModeKeyBindingsNonRecursive": [
        {
            "before": ["<Esc>"],
            "commands": [":nohl"]
        }
    ]
}
```

本当はEscキー2回に割り当てたかったのですが、 `["<Esc>", "<Esc>"]` としても反応せず...どなたか分かる方いましたら教えてください。
ちなみに `vimrc` では以下に相当します。

```vim:vimrc
nnoremap <ESC><ESC> :nohl<CR>
```

## 2. ノーマルモードのときにxキー、sキーで削除した文字をヤンクしない

```json:setting.json
{
    "vim.normalModeKeyBindingsNonRecursive": [
        {
            "before": ["x"],
            "after": ["\"", "_", "x"]
        },
        {
            "before": ["s"],
            "after": ["\"", "_", "s"]
        }
    ]
}
```

これは `vimrc` で設定することと全く同じですね。

```vim:vimrc
nnoremap x "_x
nnoremap s "_s
```

## 3. ビジュアルモードで連続ペーストする

デフォルトの状態ですと、削除された方のテキストがヤンクされてしまうので、貼り付けた側のテキストをヤンクします。
ヤンク自体を防ぐ方法は見つからなかったのですが、貼り付けたテキストを再びヤンクすることで解決できます。

```json:setting.json
{
    "vim.visualModeKeyBindingsNonRecursive": [
        {
            "before": ["p"],
            "after": ["p", "g", "v", "y", "e"]
        }
    ]
}
```

少しカーソルの動きが変な感じになるかもしれませんが、気にしなければこれで以下のような挙動に近づきます。

```vim:vimrc
vnoremap p "_dP
```

※ 追記
素直に上のマッピングを書いてあげればいいことに気が付きました...

```json:setting.json
{
    "vim.visualModeKeyBindingsNonRecursive": [
        {
            "before": ["p"],
            "after": ["\"", "_", "d", "P"]
        }
    ]
}
```

## 4. ビジュアルモードでインデントした際にビジュアルモードを保持する

ビジュアルモードのときに `<` `>` でインデントを増減させると、そこでビジュアルモードを抜けてしまうので、選択を保持するように設定します。

```json:setting.json
{
    "vim.visualModeKeyBindingsNonRecursive": [
        {
            "before": [">"],
            "after": [">", "g", "v"]
        },
        {
            "before": ["<"],
            "after": ["<", "g", "v"]
        }
    ],
}
```

対応するvimの設定は以下。

```vim:vimrc
vnoremap > >gv
vnoremap < <gv
```

## 5. ビジュアルモードのときにTabキーでインデントを調整する

`<` `>` でもインデントはできるのですが、Tabキーのほうが楽なので登録してあげます。
`setting.json` の `vim.visualModeKeyBindingsNonRecursive` では Shift+Tab をキーバインドにマッピングする方法が分からなかったので、 `keybindings.json` で設定します。

```json:keybindings.json
[
    {
        "key": "tab",
        "command": "editor.action.indentLines",
        "when": "editorTextFocus && !editorReadonly && vim.active && vim.mode != 'Insert'"
    },
    {
        "key": "shift+tab",
        "command": "editor.action.outdentLines",
        "when": "editorTextFocus && !editorReadonly && vim.active && vim.mode != 'Insert'"
    }
]
```

`vim.active && vim.mode == 'Normal|Insert|Visual'` を使うとだいたいのvimのキーバインドが実現できそうです。
`vimrc` でいうところの以下の設定。

```vim:vimrc
nnoremap <Tab> >>
nnoremap <S-Tab> <<
vnoremap <Tab> >gv
vnoremap <S-Tab> <gv
```

## 6. 行をまたいで移動する

```json:setting.json
{
    "vim.whichwrap": "h,l,<,>,[,],b,s"
}
```

これも `vimrc` と同じ書き方ですね。

```vim:vimrc
set whichwrap+=h,l,<,>,[,],b,s
```

## おわりに

私はそこまでvimのキーバインドの設定をいじっていない&使いこなせていないので、これで一旦のところ不満なくVSCodeを使えそうです。
皆さんもおすすめの設定がありましたらコメント等で教えてください。
それでは、良いvimライフを。
一つのローカルリポジトリに、複数アカウント & それぞれのアカウントに紐づくリモートリポジトリを設定する方法

一つのローカルリポジトリから、複数のアカウントかつそれぞれリモートリポジトリにpushやcloneする方法をご紹介します。

## ssh接続

使用したいリポジトリでssh接続を行っておく。

該当ディレクトリに移動

```
$cd ~/.ssh
```

### サブアカウント用の鍵を作成

メインアカウントでは既に設定してあると思うので、今回追加したいアカウント用に作成する。
> 参考：[GitHubでssh接続する手順~公開鍵・秘密鍵の生成から~](https://qiita.com/shizuma/items/2b2f873a0034839e47ce)

```
$ssh-keygen -t rsa
```

と打つと

```
Enter file in which to save the key (/Users/(username)/.ssh/id_rsa):
```

と聞かれるので、任意のファイル名を入力する。今回は```sub_rsa```としておく。

以下2つの質問はEnter, Enterで問題ない。

```
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
```

公開鍵のアップ方法、接続確認方法はこちらを参照お願いします。
> 参考：[GitHubでssh接続する手順~公開鍵・秘密鍵の生成から~](https://qiita.com/shizuma/items/2b2f873a0034839e47ce)



## configファイルの作成

### Host sub以下を追加

- main, subには任意の名前
- IdentityFileには先程作成した鍵のファイル名を記載

```:~.ssh/config
Host main
  HostName ssh.github.com
  IdentityFile ~/.ssh/id_rsa
  User git
  Port 22

Host sub
  HostName ssh.github.com
  IdentityFile ~/.ssh/sub_rsa
  User git
  Port 22
```


## メインアカウント・メインのリモートリポジトリを追加

- @の後にmainを入れる

```
git clone git@main:main_account/main_repository.git
```

```
git remot -v

origin  git@main:main_account/main_repository.git (fetch)
origin  git@main:main_account/main_repository.git (push)
```

## サブアカウント・サブのリモートリポジトリを追加

- [ラベル名]にはpushやpullする時に指定できるようラベルを入力する
- @の後にsubを入れる

```
git remote add [ラベル名] git@sub:sub_account/sub_repository.git
```

## 確認

```
git remot -v

[ラベル名]  git@sub:sub_account/sub_repository.git (fetch)
[ラベル名]  git@sub:sub_account/sub_repository.git (push)
origin  git@main:main_account/main_repository.git (fetch)
origin  git@main:main_account/main_repository.git (push)
```

### メインリポジトリへのpush

```
git push origin master
```

### サブリポジトリへのpush

```
git push [ラベル名] master
```



Githubアカウントを複数もつということがGithubの思想とは異なっているかもしれませんが、
使用機会があると思いましたので、共有させて頂きました。


## 参考
- [GitHubでssh接続する手順~公開鍵・秘密鍵の生成から~](https://qiita.com/shizuma/items/2b2f873a0034839e47ce)
- [リモートリポジトリを複数設定にする方法](https://qiita.com/k-o-u/items/80b31679c41a6e65376e)
- [複数のgitアカウントを使用する場合](https://qiita.com/yamataku29/items/4744c9c70ad793c83b82)
- [Gitでリモートブランチの追跡ブランチをローカルに作成する](https://qiita.com/Vermee81/items/0026fd512e5379b46422)
- [gitのssh接続に使用する~/.ssh/configの設定について](https://qiita.com/kawahara_hiroyuki/items/3ad35c548d1007c12109)
testify の assert.NoError() で fail した場合に処理続行して panic しないために

# 忙しい人のための結論
`assert.NoError()` で failした際には `t.FailNow()` すべし

# Why
goのテストコード書く場合いちいち `if err != nil` でチェックするのが面倒なのでtestifyの `assert.NoError()` を使ってチェックすることがあると思います。

```Go
	t.Run("hoge func1", func(t *testing.T) {
		hoge := NewHoge()
		result, err := hoge.func1() // return (interface{}, error)
		assert.NoError(t, err)

		actual := result.(*Hoge)
		expected := &Hoge{Hoge: "hoge"}
		assert.Equal(t, expected, actual)
	})
```

上記のテストコードはassertが通っている場合は問題なく動作しますが
assertがfailした場合 `assert.NoError` で処理が止まらずに`result.(*Hoge)` で panic したりします。
どちらにせよ失敗しているのでtest的には問題ないですが、test内でpanicするとfailの原因探るのが面倒です。

# What

`assert.NoError` は assertにfailした際に戻り値(bool)にfalseを返すので
falseの場合は `t.FailNow()` を呼んでtestを中断してあげます。

```Go
	t.Run("hoge func1", func(t *testing.T) {
		hoge := NewHoge()
		result, err := hoge.func1() // return (interface{}, error)
		if !assert.NoError(t, err) {
			t.FailNow()
		}

		actual := result.(*Hoge)
		expected := &Hoge{Hoge: "hoge"}
		assert.Equal(t, expected, actual)
	})
```

testにfailした際、上手い具合に目的のErrorだけ吐いて止まってくれます。
結局 `if err != nil` 的になってしまうのがどうもイケてない。
どうにかならんもんか。
gitがたまにゲシュタルト崩壊する

gitでたまにゲシュタルト崩壊するのでその時々の個人的メモ

# ローカルブランチと追跡ブランチ
* ローカルで作成したブランチは、pushすることで追跡ブランチにも反映される。これは、pushしたらリモートブランチにマージされ、その後それを追跡ブランチにfetchしている。
* つまり、gitのset-upstreamは追跡ブランチではなくリモートブランチを上流に設定している。


# HEADについて
* gitのHEADは現在いるブランチにおける最新コミット。
* detached HEADとはこのHEAD、と自分がチェックアウトしたコミット(現段階にとっての最新コミット)が一致しない状態。これを解決するには、

```
# 元のHEADにチェックアウトする
# ブランチにチェックアウトするとそのブランチの最新コミットにチェックアウトすることになるため
$ git checkout (CurrentBranchName)

# または、新しいブランチを切り、そのブランチに切り替える
# つまり「HEAD = 今いるブランチの最新コミット = 現在チェックアウトしているコミット」になる
$ git checkout -b new_branch_name
```
もし新しいブランチを切らずに過去のコミットまで戻りたい時には

```
# どちらか
$ git reset --hard (CommitLog)
$ git reset --soft (CommitLog)
```


# ブランチをRebase vs. Merge
* rebase+merge(ff)にするとログが見やすいが、修正がきつくなる
* mergeにするとgithubに表示されるログは時系列ごちゃ混ぜになる(やばい)が、修正がやりやすくなる

[こわくないgit](https://www.slideshare.net/kotas/git-15276118)がものすごくわかりやすいのでハマったら読む。

## 色々取り消す

```terminal
# addしたfileをunstageする
$ git reset HEAD filename

# 特定のファイルの内容をHEADまで戻す
$ git checkout -- filename

```
RxSwift疑問

めちゃめちゃメモ

# map と flatMap 違い

## map

流れて来る本来のイベントの値を加工

## flatMap

流れて来る本来のイベントの値を加工した上で、任意のObservabl型を返す関数

# bind

ObservableとObservableをくっつける
Errorをスルー

# .of(), .just()

どっちもObservableを簡単に生成するメソッド。
createでもいい。
justは１個、ofは複数可能。

## just

justは引数で渡した値1つをただ返すだけのObservableを作成するメソッド

## of

ofは引数で渡した値全部をただ返すだけのObservableを作成するメソッド

# ライフサイクル

# Hot Cold

## Hot

acceptで発火
SubjectはHot
１対多

## Cold

subscribeすると発火
一旦、Subject以外は基本Coldと思っていい
1対1(複数Subscribeできるけど別々のStreamになる)

# Scheduler

## observeOn

次の処理を引数のスレッドで実行

## subscribeOn

前の処理を引数のスレッドで実行
Coldでしか使えないよ

# Driver

Driverを使用することで購読する側に

- メインスレッドで通知
- shareReplayLatestWhileConnected を使った Cold-Hot 変換
- onError 通知しない

を強制することができます。

参考：https://qiita.com/k5n/items/44ef2ab400f47fb66731

# bind と subscribeの違い

subscribeの便利なやつがbind。
onNextしかない。ErrorもCompletedもない

# Observableをnilでフィルタしてアンラップするときどうしたらいい？

filterNil() みたいなExtension追加しよ

```swift
extension ObservableType where Element: OptionalType {

  func filterNil() -> Observable<Element.Wrapped> {
    return flatMap { item -> Observable<Element.Wrapped> in
      if let value = item.value {
        return .just(value)
      } else {
        return .empty()
      }
    }
  }
}
```

参考：https://qiita.com/ryotapoi/items/925a74ed4df9cb351c32
ZABBIX(4.0)でORACLEの表領域監視に挑戦中

ZABBIXを4.0にアップグレードした結果、ORABBIXが利用できなくなりORACLEの監視が手薄になって早半年。
せめて表領域の監視だけでも自力でできないかと挑戦開始。

*■環境*
ZABBIXサーバ：CentOS 7.7.1908
DBサーバ：WindowsServer2008R2
ZABBIXバージョン：4.0.16

*■概要*
1. マスタアイテムを作成する。
2. 依存アイテムを作成し、1のマスタアイテムから表領域使用率を取得する。(JSON形式)
3. DBサーバの表領域毎の使用率をJSON形式でzabbix_senderに渡す。（マスタアイテムのキーを指定）
4. 使用率を閾値監視してトリガーとアクションを作成。
5. 同一インスタンスの表領域使用率を１つのグラフで表示する。

*■作業記録*
1～3は以下のサイトを参考にしました。
[誰でも ZABBIX 2. 監視アイテムの追加 - 依存アイテム ](http://unam.hatenadiary.jp/entry/2018/02/18/111619)

マスタ・依存アイテムの作成は問題なかったのですが、zabbix_sender実行エラーで最初のハマり。
zabbix_sender [532]: invalid parameter "XXXXXXXX"
上記エラーがJSONの値部分の数分出力されました。
このときzabbix_senderの起動パラメータは

zabbix_sender -z *ZABBIXサーバIP* -s *監視ホスト名* -k *マスタアイテムキー* -o {"tname": "AUDIT_AREA","rate": "6.00"}

"AUDIT_AREA" と "6.00" が invalid parameter だと怒られました。
-o オプションに指定する値は途中の空白を許容しないということがわかり、全体をシングルクォートで囲ってみましたが、変わらずエラー。。。

zabbix_sender -z *ZABBIXサーバIP* -s *監視ホスト名* -k *マスタアイテムキー* -o '{"tname": "AUDIT_AREA","rate": "6.00"}'

素直に途中の空白を取り除いて実行するとようやくzabbix_senderは正常終了。
zabbix_sender -z *ZABBIXサーバIP* -s *監視ホスト名* -k *マスタアイテムキー* -o {"tname":"AUDIT_AREA","rate":"6.00"}


さて、サーバ側の最新データを見てみると、マスタアイテムには値があるけど依存アイテムに値がない。
しかもマスタアイテムの最新値は
{tname:AUDIT_AREA,rate:6.00}

ダブルクォーテーション外されちゃってました。。。
再トライ
zabbix_sender -z *ZABBIXサーバIP* -s *監視ホスト名* -k *マスタアイテムキー* -o {"""tname""":"""AUDIT_AREA""","""rate""":"""6.00"""}

これでマスタ／依存アイテム共に最新値が取得でき一段落。
単一グラフも表示され、4項後回しで5項に取り掛かったのですが、、、

各表領域の使用率を同一マスタアイテムに送信したら、表領域毎に軸が分けられません。。。

表領域の数分マスタアイテムを作成し、それぞれに使用率の依存アイテムをぶら下げる。
という方法は思いついたのですが、もっと合理的な方法がないかと、現在ここで停滞中。

妙案がありましたらアドバイス頂きたく。
EC2でwindowsインスタンスを作って、Ansibleで操作できるようにセットアップした

ansibleでwindows向けのplaybookを作る機会があったので、手軽にテストできるようにansibleで操作可能なwindowsインスタンスをEC2で作成した。そのときの手順をまとめた。


## AWSにWindowsServerインスタンスを作成

"Microsoft Windows Server 2016 Base - ami-04f188a745c1a5ecb"で検証を行った。

インスタンス作成時に注意しておくことは次の３点

- 「セキュリティグループの設定」のインバウンド設定で、RDPとWinRM-HTTPSのポートを開けておく。
- キーペアの登録は必ず行う。
- 「インスタンスの詳細設定」の「高度な詳細」>「ユーザーデータ」に次の内容をコピペしておく。これにより、インスタンス起動時にpowershellでスクリプトが実行され、AnsibleがWindowsServerと通信するために必要な、WindowsServer側のセットアップが完了する。このスクリプトは、Ansibleの公式ドキュメント [Setting up a Windows Host](https://docs.ansible.com/ansible/latest/user_guide/windows_setup.html) を参考にした。

```
<powershell>
$url = "https://raw.githubusercontent.com/ansible/ansible/devel/examples/scripts/ConfigureRemotingForAnsible.ps1"
$file = "$env:temp\ConfigureRemotingForAnsible.ps1"
(New-Object -TypeName System.Net.WebClient).DownloadFile($url, $file)
powershell.exe -ExecutionPolicy ByPass -File $file
</powershell>
```

ちなみに、上記の設定はあまり安全とはいえない設定（Basic認証など）を有効にしているので、本番環境ではこのまま使わないほうがいい。


## inventoryファイルの作成

インスタンスができたら、「アクション」 > 「Windows パスワードの取得」 で、**パブリックDNS**、**ユーザー名**、**パスワード**を取得する。

この情報を元に、inventoryファイルを作成する。

```yaml
[windows2016]
<パブリックDNS> ansible_user=<ユーザー名> ansible_password=<パスワード> ansible_connection=winrm ansible_winrm_server_cert_validation=ignore
```

## 接続確認

```
$ ansible windows2016 -i ./inventory -m win_ping                                
ec2-13-231-151-252.ap-northeast-1.compute.amazonaws.com | SUCCESS => {
    "changed": false,
    "ping": "pong"
}
```

## 起動テンプレートの作成

上記の設定で通信できることが確認できので、同じ設定でEC2の起動テンプレートを作成して、いつでも同じ設定のWindowsServerを素早く作れるようにした。
【Rails】gem install で特定のversionをインストールする

```
gem install gem_name -v version_number
```

```
gem install gem_name --version version_number
```

```
gem install gem_name:version_number
```
コロンでもversion指定ができる
https://github.com/rubygems/rubygems/blob/master/lib/rubygems/commands/install_command.rb
> Can't use --version with multiple gems. You can specify multiple gems with version requirements using gem install 'my_gem:1.0.0' 'my_other_gem:~>2.0.0'
IntelliJ IDEA (PHPStorm)でリモートブランチの内容を取り込む

今まで他にいい方法が絶対あると思いつつ、惰性でリモートブランチをチェックアウト → プル → 作業ブランチをチェックアウト → マージという回りくどい手順を踏んでいましたが、この間ついにスマートな方法を見出したのでメモ。

## 手順

#### 1. VCSメニュー -> Git -> Pull...を選択
![スクリーンショット 2020-01-09 11.29.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27674/2af126ba-b57a-f0e0-5cc3-332cc0fdd3c0.png)
#### 2. 取り込みたいリモートブランチにチェック
#### 3. (必要なら)No fast forwardなどのオプションにチェック
#### 4. Pullを選択
![スクリーンショット 2020-01-09 11.31.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27674/8fdf67eb-4ab7-e309-2a9c-0191aa3c9789.png)


#### 5. (コンフリクトが発生したら)Merge...を選択
![スクリーンショット 2020-01-09 11.37.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27674/29f181bd-3d2a-f4d0-cfc3-58962a55a73f.png)

#### 6. Closeを選択

これで最新のリモートブランチのデータを自動で取得した上で今いる作業ブランチにマージしてくれます。

以上
macでターミナルにディレクトリをドラッグ&ドロップでvscodeも一緒に起動するようにする

# 動機
1. Mac book proを使っており画面が小さい為、vscode埋め込みターミナルでは苦しい
2. ターミナルもvscodeもspectacleや、magnetでウィンドウサイズ自在にコントロールして扱いたい(横長固定だとmac book proではしんどい)

とはいえ、いちいちvscodeも起動して、ターミナルも起動してcdコマンドで移動してとか、めんどくさい...

vscodeにドラッグして、ターミナルにもドラッグすれば
どちらも一発で作業ディレクトリが開いてくれるけど
2回ドラッグするのめんどいし

例えば、先にDockのvscodeにドラッグして
その後、同じくDockのターミナルにもドラッグするとして...

だがしかし！
vscodeが開くとvscodeのウィンドウが邪魔で
いったん、ウィンドウをどかしてFinderが触れる状態にしてから
再度、Dockのターミナルに作業ディレクトリをドラッグしなくてはならない

これは、めんどい！

ということで！
ターミナルにドラッグすれば同時にvscodeも起動するようにしてしまいましょう！

# まずは、vscodeの起動コマンド「code」をインストールする
[こちらの記事を参考に](https://qiita.com/naru0504/items/c2ed8869ffbf7682cf5c)

# ターミナル起動時にvscodeも起動するようにする

これも超簡単です。
要は、ターミナル起動時に毎回必ず実行されるshell
.zshrcにshellを書いてやればいいだけのこと

カレントディレクトリをプロジェクトとして開いて起動してやるには

```shell
code .
```
こうですね。
ですがこのままでは
ホームディレクトリ「~」や「/」のパスでもvscodeが自動起動してしまいます。
これではまずいので
下記のようにしてやりましょう！
(下記を.zshrcに記述すればOKです！)

```shell
nowDir=`pwd`
if [ $nowDir != "/" ] && [ $nowDir != "$(echo ~)" ]; then
  /usr/local/bin/code .
fi
```
これで現在のディレクトリが
「~」や「/」ではない場合のみ
vscodeが起動されるようになりました！
Laravelのテストから新しくインストールした自動検出対応のパッケージが使えない

# 問題

自動検出対応のパッケージを新たに`composer require`で入れたんだけど、何故かそのパッケージを使ったテストが通らない。しかし該当の処理を`php artisan tinker`で手で実行するとちゃんと動くという謎の現象にでくわしました。

# 原因

自動検出されたパッケージの情報は`bootstrap/cache/packages.php`, `bootstrap/cache/services.php`にキャッシュされていてもしあればここに書かれた情報で動きます。composerで新しいパッケージをインストールしたときは自動的に`php artisan package:discover`を行う設定が`composer.json`に書かれているのでそれによって更新されます。

ところが、このファイルの場所は環境変数で変更することが出来て、phpunit実行時は`phpunit.xml`に以下のような記述があって変更されています。

```xml
        <server name="APP_SERVICES_CACHE" value="bootstrap/cache/services.phpunit.php"/>
        <server name="APP_PACKAGES_CACHE" value="bootstrap/cache/packages.phpunit.php"/>
```

そのため、phpunitの初回実行時にいったん作られはするのですが、その後は更新されません。このせいで新しいパッケージのサービスプロバイダの初期化がphpunitから実行するときだけ行われず動作がうまくいっていなかったわけです。

# 対処

`bootstrap/cache/services.phpunit.php`, `bootstrap/cache/packages.phpunit.php`を削除してやれば次にphpunitを実行すると新しい状態になります。

そもそもphpunitのときだけこれらのキャッシュファイルを別のものに変更する必要が普通はないような気もするので上記の設定を`phpunit.xml`からバッサリ削除して後顧の憂いを絶つのもいいかもしれません。

さらに、これは問題だと思うのでissue出そうかと調べたら、なんと既に去年の9月頃に直っていました。([[6.x] Remove testing bootstrap extension #5107](https://github.com/laravel/laravel/pull/5107)) その少し前に作ったプロジェクトなんですよね。

ただ、フレームワーク本体と違ってvendorの外にあるファイルは`composer update`などでは更新されず最初にプロジェクトを作ったときのままになるのが普通なので、この状態になっているプロジェクトも多いのではないかと思います。気をつけましょう。
仕事の考え方

##仕事の考え方
現場では考え方が違ってぶつかる事もある。
7年目にして初めて、仕事の考え方が全然違うリーダーとぶつかった。
しかもお互い相性が悪く、バチバチしまくってるのでログとして残しとく。
今後に活きるように。

**大事なのは、相手はこういう考え方の人で、自分とは違う考え方なんだな、って落とし込む事。**
相手を変えようとしても変わらんし、自分がイライラするだけ損なので。

##「具体的に教えてくれ」に対して
###事象
なにか不具合や課題があったとして、それに対する原因と対策を伝える必要があるとする。
当然ながら、まずはヒューマンエラーだとか、仕様誤認だとか、根本原因を書く。
そのうえで、「このコードのこの箇所をこういう風に直す」と書いたとして。
相手がSEでコード書いてる人だから、そっちの方が解りやすいと思ってそうしたが、「そんなん見せられてもわからない」との事。

###実態
自分にとっての具体的とは、「この箇所をこう直す」というレベルのものなんだけど、リーダーにとっての具体的は「サルでもわかるレベルで、適度に抽象化した日本語のみの説明」というものだった。

###改善
可能なら、そのリーダーが過去に対応した説明資料を見て、その人の「具体的」の基準を推測する。

##「実現可能か確認してくれ」に対して
###事象
例えば、「HTTPヘッダを追加してくれ」という依頼があり、サーバー設定を変えないといけないとして。

ローカルはtomcatしかないとする。
しかし本番環境はapacheか何かで動かしていそうに見える時。

自分は、本番環境ではどういう構成で動いているから、どのファイルを編集しないといけないかを事前に明らかにしておきたい。

ローカルはtomcatで動いている、しかし本番は違う構成で動いていたら「実現可能か確認した」事にはならないはず。

だから、apacheなのか、nginxなのか、また違う技術で動いているのか
それを事前に確認した上で、tomcatはこれのファイルをいじればOK、apacheはこのファイルをいじればOK、という形で進めたい。

自分では本番環境に触る権限がないとしても、このファイルをこう編集してくれ、と依頼するのがSEとしてやるべき仕事のはず。

###実態
しかし、ローカルのtomcatだけで実現できるか先に確認しろ、本番でできるかどうかは別の話という考え方のリーダーもいる。
全体を捉えて、筋道立ててから対応するのではなく、目の前の事をまず解決してから次を考えようってタイプだと思われる。

僕がなぜ全体を捉える必要があると考えたか、その理由を説明すると、「技術に頼りすぎ」という謎のお言葉を頂いた。
全然納得できないけど、仕事だからやるしかないね…。

###改善
リーダーがいるなら、ここのあたりを会話で見極める。
指示通りやらないと怒る人なのか、先回りで対応したほうが嬉しい人なのか。
先回りでやる事が、必ずしも喜ばれる訳ではないようだ。


##「例え話」が通用しない
###事象
何かに対する説明をしたとき、理解できてなさそうなので例え話を出すとする。
「例えば、OSレベルの違いと同じだと思ってもらえれば。WindowsとLinuxくらい、やるべきことが違うという話です」

###実態
「今回の案件でWindowsだとかLinuxになんの関係があるの？」と「例え話」と言ってるのに、例え話の内容に集中してしまい、さらにリーダーが混乱する。

###改善
なんでもない話の時に、例え話をしてみて、それが通じる人かどうか、見極める。
仕事で例え話をすると、通じない時にお互いにイライラが募るので。
相手が理解しやすくするために、例え話をすることが、万人に通じるとは限らないようだ。

##提案の仕方
###事象
問題に対する対応案が複数浮かんだとき、それを文章にまとめて送付する。
過去に説明済みの内容なので、文章のみで説明が通じると思って送付した。
すると、わからないといわれてしまった。

###実態
過去に説明済みの内容でも、再度新しく資料を作り直す必要がある。
また、メールも引用返信で履歴がついてても、そんなとこ読む暇はないから資料化してくれとの事。

###改善
工数は増えるが、資料を作ってあげる。
しかし、資料化する前にまず口頭ベースで話してくれ、というリーダーもいる。
この辺は一回試してみて見極める。

##不具合の証跡を残す
###事象
単体テストレビューで自分が気づかなかった不具合を指摘してもらったので修正。
ソース修正とともに証跡も取り直した。
しかし、不具合発生時の証跡も欲しいとの事。

###改善
レビュー担当によって、不具合の証跡が欲しいかどうかは変わると思われる。
自分は6年間やってきて、不具合の証跡保存を求められる現場はなかった。
※本番障害は別。

逐一確認するようにする。

##DBのハードコピー
DBダンプを残す際に、Excelに貼り付けてOK派と画像じゃないとNG派がいる。
あと、DBダンプの上にselect文貼り付けてくれっていうよくわからん指摘を貰う事も…

##ヘルプで入ってもシステムをすべて理解している必要がある
助けてくれ！って言われて、一切やったことないシステムの保守案件にトライ。
レビュー出してると、特定システムの細かい謎仕様の指摘を貰った。
特定データの細かい仕様とか理解してないと、レビュー工数増えるからやめろ！って怒られたりする。

##エラーメッセージはわかりやすく
細かく伝わるように作らないといけないらしい。
具体的に＊＊＊というデータが＊＊＊なので＊＊＊できません　みたいな。

##朝令暮改
何度繰り返されても、心穏やかに受け入れる。

##後から指摘
各工程のレビューを通しても、あとからコレこうしろ！って修正依頼がきたりする。
それをレビュー工数増えるとか言われて怒られたりする。
【備忘録】PythonでMongoDBを操作する

postgreSQLと併せてよく忘れるので書き残しておきます。条件指定等の細かい操作はpymongoの使い方を参照ください。

```Python
from pymongo import MongoClient


mongo_server = 'localhost'
mongo_port = '27017'
mongo_database_name = 'database'
mongo_collection_name = 'collection'

def displ
ay_data(collection, mongo_filter=None):
    data = collection.find(filter=mongo_filter)
    for elem in data: 
        print(elem)
      
 
def insert_data(collection, data):
    collection.insert_one(data)
    

if __name__ =='__main__':
    mongoclient = MongoClient('mongodb://' + mongo_server + ':' + mongo_port + '/')
    db = mongoclient[mongo_database_name]
    collection = db[mongo_collection_name]
    # データの入力
    for i in range(10):
        data = {'count' :i}
        insert_data(collection, data)
    # データの表示
    display_data(collection)
```

実行結果

```
{'_id': ObjectId('5e168f7828ba5616d6873582'), 'count': 0}
{'_id': ObjectId('5e168f7828ba5616d6873583'), 'count': 1}
{'_id': ObjectId('5e168f7828ba5616d6873584'), 'count': 2}
{'_id': ObjectId('5e168f7828ba5616d6873585'), 'count': 3}
{'_id': ObjectId('5e168f7828ba5616d6873586'), 'count': 4}
{'_id': ObjectId('5e168f7828ba5616d6873587'), 'count': 5}
{'_id': ObjectId('5e168f7828ba5616d6873588'), 'count': 6}
{'_id': ObjectId('5e168f7828ba5616d6873589'), 'count': 7}
{'_id': ObjectId('5e168f7828ba5616d687358a'), 'count': 8}
{'_id': ObjectId('5e168f7828ba5616d687358b'), 'count': 9}
```
MongoDBドキュメントを_idで検索して更新する方法は

```bash
 db.hashtag.find().toArray()
```

```bash
    {
        "_id" : ObjectId("5dedea6ade0ff88cc8edab33"),
        "hashtag" : “youToo”,
        "user_id" : "5dfe14ddf7df944f348d16dd",
    }
```

```bash
db.hashtag.update({_id:ObjectId("5dedea6ade0ff88cc8edab33")}, {$set:{hashtag: “meToo”}})
```
Java 素数の求め方

# 素数って何だっけ？

だいたい競プロの問題に挑戦すると、あー学生の頃に習ったことあるけど何だったか全然思い出せねーってなります。

素数とは、Wikipediaによると
>素数（そすう、英: prime number）とは、1より大きい自然数で、正の約数が1と自分自身のみであるもののことである。正の約数の個数が2である自然数と言い換えることもできる。

だそうです。
つまり、**1より大きい整数で、1と自分自身でしか割り切れない数**のことですね。

# 素数判断のプログラム

```java
import java.util.Scanner;

public class PrimeNumber {
  public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);
    int target = sc.nextInt();

    if (target < 2) {
      System.out.println(target + "は素数ではありません。");
      return;
    }

    for (int i = 2; i < target; i++) {
      if (target % i == 0) {
        System.out.println(target + "は素数ではありません。");
        return;
      }
    }
    
    System.out.println(target + "は素数です。");
  }
}
```

## 解説

### 1より大きい整数
```java
    if (target < 2) {
      System.out.println(target + "は素数ではありません。");
      return;
    }
```
ここでは、素数ので意義である**1より大きい整数**かどうかをチェックしています。
2より小さければ素数ではないとわかるので、出力してさっさと処理を終了させます。


### 1と自分自身でしか割り切れない数
肝になるのはやっぱりこの部分です。

```java
    for (int i = 2; i < target; i++) {
      if (target % i == 0) {
        System.out.println(target + "は素数ではありません。");
        return;
      }
    }
    
    System.out.println(target + "は素数です。");
```

for文で、2からtarget-1までの数で1つずつ割っていって、割り切れるかどうかをチェックしていきます。
ひとつでも割り切れる数が存在する場合、その数は素数ではないので、出力して`return`で処理を終了させます。

割り切れる数がない場合、`target`は素数ということになります。:clap:

# 高速化
素数かどうか調べるための単純な方法として、1と対象数以外の全ての数で割っていく上記の方法を行いました.
しかし、この方法だと調べる対象数が大きいほど、計算に時間がかかってしまいます。

そこで、コメントでいただいたように、素数かどうかは平方根以下の値のみのチェックすれば判定できるようです。

## なぜ平方根まででいいのか
素数とは、1と自分自身でしか割り切れない数のことでしたが、それ以外の数を合成数と言います。
つまり、合成数とは、1でも素数でもない数のことです。
言い換えると、合成数は**1と自分自身以外に最低でも1つの約数をもつ**ということになります。

また、合成数は**√n以下の約数をもつ**という性質を持っています。

### 合成数は√n以下の約数をもつ
なぜ合成数は√n以下の約数をもつと言えるのでしょうか？

まず合成数nは、1でない自然数a,bが存在しているため`ｎ=ab`と表せます。
もし、nが√ｎ以下の約数を持たないとすると、`√ｎ<a,√ｎ<b`となります。
√ｎは0より大きいため、`√ｎ<a,√ｎ<b`の場合（nが√ｎ以下の約数を持たない場合）、`√ｎ√ｎ(=n)`は`ab`より小さいということになってしまい、`ｎ=ab`に反します。
そのため、ｎは√ｎ以下の約数を持つと言えるのです。

つまり、nが合成数なら、√x以下の約数を持つということは、√x以下に約数があるかどうがをチェックすれば、
その数が素数かどうか判定できるということになります！

## 改・素数判断のプログラム
```java
import java.util.Scanner;

public class PrimeNumber {
  public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);
    int target = sc.nextInt();

    if (target < 2) {
      System.out.println(target + "は素数ではありません。");
      return;
    }
    if (target % 2 == 0) { // 偶数は先にリターン
      System.out.println(target + "は素数ではありません。");
      return;
    }

    for (int i = 3; i <= Math.sqrt(target); i+=2) {
      if (target % i == 0) {
        System.out.println(target + "は素数ではありません。");
        return;
      }
    }

    System.out.println(target + "は素数です。");
  }
}
```
Pythonの@propertyデコレータについてまとめる

# 大前提


```python
class Man1():
    def __init__(self, name):
        self.name = name

```

このように定義するとインスタンス変数nameの参照、書き換え両方可能である。

```python
# 初期化
Paul = Man("Paul")

# 参照可能
print(Paul.name)
# 書き換え可能
Paul.name = "Mac"
```


# プライベート変数もどきを実現したい

しかし、あるインスタンス変数を

* 必ずgetter/setter経由で参照/書き換えしたい
* 参照は許すが書き換えは禁じたい

という場合がある。この場合、

```python
# インスタタンス変数のprefixを__で定義(これにより__nameはマングリングされこの名前は参照できない)
class Man():
    def __init__(self, name):
        self.__name = name

    # この関数名は既存のインスタンス変数名と被ってはいけない
    @property
    def name(self):
        return self.__name

    # setterより前に同名のgetterの定義が必要
    # このsetterがないとnameプロパティは読み取り専用になる
    @name.setter
    def name(self, name):
        self.__name = name
```
とすることで

```python
# 初期化
Paul = Man("Paul")

# 参照
# Paul.name()ではない
print(Paul.name)

# 書き換え
# Paul.name("Mac")ではない
Paul.name = "Mac"

#　元のpropertyに直接アクセス不可(エラー）
Paul.__name
Paul.__name = "Mac"
```

ただし、`Paul._Man__name`でインスタンス変数`__name`を参照、書き換えすることは可能(だから`もどき`)
引数がいくつ入るか分からない場合 *args 可変長引数

```py:1
def greeting(word1, word2, word3):
    print(word1)
    print(word2)
    print(word3)

greeting('こんにちは', 'おはよう', 'こんばんは')
```

```:1の実行結果
こんにちは
おはよう
こんばんは
```

```py:可変長引数*argsを使って
def greeting(*args):
    for arg in args:
        print(arg)

greeting('こんにちは', 'おはよう', 'こんばんは')
```

```:可変長引数*argsを使っての実行結果
こんにちは
おはよう
こんばんは
```

引数に入れたいものをタプルに格納してから使う場合は

```py:可変長引数*argsを使って2
def greeting(*args):
    for arg in args:
        print(arg)

t = ('おはよう', 'こんばんは')# タプルに格納
greeting('こんにちは', *t)# *でタプルをアンパッキング
```
greeting('こんにちは', *t)
*tでタプルtを展開。
展開したものを
greeting関数に渡す。
*argsでタプル化される。

タプル化されたタプルargsを
for arg in args:
        print(arg)
で利用する。

```:可変長引数*argsを使って2の実行結果
こんにちは
おはよう
こんばんは
```
スタンフォード式デザイン思考


<img src="https://images-na.ssl-images-amazon.com/images/I/51w1LznpbyL._SX336_BO1,204,203,200_.jpg" width="250">

# 自分のメモ

アイディアだしのマインドセット

- ジャッジしない
    - どんな意見も決めつけたり、判断したりしない
- 大胆にいこう
    - 夢のような突飛なアイディアでも歓迎する
- Yes and
    - アイディアを肯定し、それを広げていく
- 一度に発言できるのは一人だけ
    - 誰かが話しているときにはその話を遮らない
- トピックに集中する
- 可視化する
    - ポストイットに書く
- 質より量

## 問題を明確にするためのアイディアだし

1. よいところを伸ばす
2. 悪いところをなくす
3. ひっくり返してみる
4. 前提を問い質す
5. 形容詞を変えてみる
6. ほかのリソースを使う
7. ニーズやコンテキストから連想する
8. トピックスに着眼点を適用してみる
9. 現状を変えてみる
10. 着眼点を分割する

### 目的：空港における地上での体験をデザインする
#### 例：子供連れの母親が空港のゲートで待っている間、子供たちが騒ぎ待ちくたびれた乗客をイライラさせない。何とか楽しませたい。

1. 子供たちのエネルギーで乗客を楽しませられないか
2. 子供をどう遠ざけるか
3. 待ち時間を旅行で最も面白い部分にできるか
4. 空港の待ち時間をなくすには？
5. 「苦しい」（待ち時間）を「快適な」（待ち時間）に変えられるか
6. ほかの乗客の自由な時間を活用できるか
7. 空港を温泉や遊び場所のようにできるか
8. 空港を子供たちが行きたくなる場所にできるか
9. はしゃぐ子供たちを静かにできるか
10. 子供を楽しませる方法/母親を落ち着かせる方法/連れてきた乗客を楽しませる方法それぞれ考える
【Rails】kaminariを使用して基本的なページネーション機能を実装する

## 前提
bundlerを使用して、Gemfileでgemを管理していることを想定しています。

## 使い方
### 準備(インストール)
1.Gemfile内に`gem kaminari`を記述

```ruby
# Gemfile 
gem 'kaminari'
```

2.kaminariをインストール

```shell
$ bundle install
# 「bundle」だけでもOK
```

### 設定
#### 設定ファイル作成
1.設定ファイルを作成する

```shell
$ rails g kaminari:config
```

2.設定ファイルが作成される

config/initializersディレクトリ配下に「kaminari_config.rb」ファイルが作成されます。
作成されたファイルをいじることで、「kaminari」のデフォルト設定を変えることができます。

以下の記事に詳しく書かれていたので参考にしてみて下さい。
[Railsライブラリ紹介: ページングを行う「kaminari」](https://www.techscore.com/blog/2013/01/07/rails%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA%E7%B4%B9%E4%BB%8B-%E3%83%9A%E3%83%BC%E3%82%B8%E3%83%B3%E3%82%B0%E3%82%92%E8%A1%8C%E3%81%86%E3%80%8Ckaminari%E3%80%8D/)


```kaminari_config.rb
# frozen_string_literal: true
Kaminari.configure do |config|
  # config.default_per_page = 25
  # config.max_per_page = nil
  # config.window = 4
  # config.outer_window = 0
  # config.left = 0
  # config.right = 0
  # config.page_method_name = :page
  # config.param_name = :page
  # config.params_on_first_page = false
end
```

#### Controller
Controllerでページパラメータ(`params[:page]`)を取得します。

```ruby
@users = User.order(:id).page params[:page]
# User.order(:id) ← Userモデル(usersテーブル)をid順にら並べている
# .page params[:page] ← 大切なのはここ。ページパラメータを取得している。
```

#### Views
views部分で以下のようにControllerで定義した変数名を使いましょう。

```ruby
#　@usersはControllerで定義した変数名
<%= paginate @users %>
```

以上で基本的なページネーションの機能が付けれるかと思います。

**※上手く表示されていない時は、設定ファイルを保存しているかやサーバーの再起動をしているかなどをチェックしてみてください！**

より詳しい使い方は以下を参考にしてみてください！
(表示するテキストを変えたり、テーマを変えたりとかもできます。)
【参考】https://github.com/kaminari/kaminari
デジタルフィードバックループについて

# 概要
近年 Microsoftのイベントでよく出てくる言葉「**デジタルフィードバックループ**」について。

# Microsoft の デジタルフィードバックループとは

## 定義
Microsoft では

「デジタル変革を実現する方法について記述する**フレームワーク**」
また、Microsoft における構築方法のガイドのこと。

 **デジタルフィードバックループ**と呼んでいます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183354/d51ece6e-22c2-d151-44b5-c2a61b4f9326.png)

### 変化 変更 変革 違い

#### 変化
あるものが別のものに変わること。

#### 変更
あるものを意図的に変える、又は手を加えて変えること。

#### 変革
社会や制度、仕組みなどが大きく変わること。

## 詳細

現在世界ではあらゆるものから **データ**が生まれています。
「SNSに触れたとき」
「接続された製品を使用したとき」
「航空機」 
etc...
ほとんどすべてのものが**データ**を送信しています。
その**データ**が活用でき、インサイトが得られたときにビジネスが根本から変わるまたは考え直すことができるのではないでしょうか？
よく、勘違いされる点として、何かしらの入力フォームを思い浮かべてください。誰かが入力を行い、そのデータがビジネスアプリケーションの価値やデジタル変革につながるでしょうか？
答えは Yes でもありますが、考え方次第では No となります。
そのデータをそのままにしていては No。その**データ**を活用、分析して初めてデジタル変革やビジネスアプリケーションとしての価値になります。つまり、**データ**をあらゆる視点から見ることでデジタル変革を可能にします。



デジタルフィードバックループはデータエンドポイントやシグナル(信号、きっかけ)を 1 つにまとめ、インサイトを得て継続的な変革を促進します。 
Dynamics 365 の場合は、外部ソースを含む複数のソースから複数のデータを取得し、デジタルフィードバックループを活用します。その後、データを分析し、ビジネスに利用します。

### インサイト とは
マーケティング用語で、消費者の行動や思惑、それらの背景にある意識構造を見ぬいたことによって得られる「購買意欲の核心やツボ」のことを指す。

参考
[インサイト](https://www.synergy-marketing.co.jp/glossary/insight/)

# まとめ

- デジタルフィードバックループによってデジタル変革が実現する。
- デジタルフィードバックループはビジネス全体から様々なデータを取得し、つなぎ、合成し、ビジネス改善に役立つインサイトを取得できる。
PHPでbool値をechoするとtrueは1に、falseは出力されない

とあるシステムのテンプレートをみてたら下記の様にbool値をecho してるプログラムを発見しました。

```php
<?php
// bool値
$showDetailForm = $historyError || $linkError;
?>
<div ng-init="showDetailForm='<?php echo $showDetailForm; ?>'">
```

bool値をechoしようと思ったことがなかったので、これどうなるんだろうと思って実験してみました。

```php
$true = true;
echo $true; // 1
$false = false;
echo $false; // 空
```

結果は trueなら 1 false なら空となりました。

自分では使うコトないだろうけど、コード読んでてまた「あれ？bool値のecho?」ってなりそうな気がしたのでメモっときます^^;
個人的に直近で探究したいギジュツ！

こんにちは！

先日、[PHPの言語仕様の理解を深める特殊な立ち回り](https://qiita.com/huuya/items/f9bedb6b600c55613c4b)でコアな内容を記しましたが、直近で私自身が探究したいギジュツを備忘録代わりにまとめておきます！

## 暗号学を知る

PHPの[mt_rand()](https://www.php.net/manual/ja/function.mt-rand.php)で扱われているメルセンヌ・ツイスターが以前より、暗号化の処理として扱うことは望ましくないとされてきました。
先日、その疑似乱数生成器(PRNG)の一種であるメルセンヌ・ツイスターでブルートフォースを介すこと無くシード値を取得できてしまうことが発見されました。

[Breaking PHP's mt_rand() with 2 values and no bruteforce](https://www.ambionics.io/blog/php-mt-rand-prediction)

これにより、メルセンヌ・ツイスターによって暗号化した値を復号化することは容易であることを再認識出来ることとなります。

RNGやPRNG等の理解を深めるとともに、暗号学への興味が深まったため学ぶ機会にしたいと考えています！

## WordpressのAction-Hookの仕組み

Wordpressは世界・日本シェアNo1となっているCMSですが、Action-Hookという内部実装が施されています。
これは在る種、キューイングシステムのようなものです。（C言語のgoto文チックではありますが笑）
オープンソース且つ実用例の多い、WordpressのAction-Hookを通してキューイングシステムの仕組みの理解と簡易キューイングシステムの自作に取り組みたいと考えています。

## WordpressのAdmin-Ajaxの仕組み

WordpressでAjaxを用いる際は、action名（関数名）と引数を独自のフォーマットで記述し、XMLHttpRequestで非同期通信を行います。
そして、Ajaxのリクエスト先は一貫して`/wp-admin/admin-ajax.php`であります。
客観的に見ると、.htaccessで流して、Wordpressの組み込み関数である`add_action()`や`do_action()`を介して可変関数を走らせていることは想像できます。
その仕様を`/wp-admin/admin-ajax.php`から読み解き、実際に工程を1から書きたいと考えています。


## テンプレートエンジンの仕組み

以前より、既存のテンプレートエンジンの内部仕様を読み解いて、仕組みを理解するようなことは行っていました。
そして、テンプレートエンジンは、

- LaravelのBladeのように、phpファイルに直接記述する
- Smartyのように、別途の拡張子ファイルに記述した処理をHTTPリクエスト時に、PHPファイルとしてコンパイルする

の2種類に分かれると思います。

まずはそれぞれのテンプレートエンジンの使用例を追求するために、Githubでスター数の多いオープンソースプロジェクトのソースコードから読み解いていきます！

※ここでは、あくまでテンプレートエンジンの使用例を追求することです。

そして、既存のテンプレートエンジンの記述フォーマットの違いにも触れながら、簡易テンプレートエンジンの自作に取り組もうと考えています。

## 自作OSの学習を進める

つい半年前くらいから自作OSに強く興味を持ち、学習を試みています！笑
というのも、いきなりLinuxカーネルを読もうと頑張ってみたりしてで、実際には何も学習できていませんでした！笑

なので、まずは数ヶ月に購入した[30日でできる! OS自作入門](https://www.amazon.co.jp/30%E6%97%A5%E3%81%A7%E3%81%A7%E3%81%8D%E3%82%8B-OS%E8%87%AA%E4%BD%9C%E5%85%A5%E9%96%80-%E5%B7%9D%E5%90%88-%E7%A7%80%E5%AE%9F/dp/4839919844)を通して学習する時間を増やし、その過程をQiitaで備忘録にしていきたいと考えています。

※該当書籍が国語辞典以上に分厚いので、30日で読み進めることにこだわりはありません笑

## 無線LANに関することで

私は小学校高学年の頃、ペネトレーションテストの出来る[BackTrack](https://www.backtrack-linux.org/)というLinuxディストリビューションを通して、無線LANセキュリティを学びました。

当時は、WEPやWPAが主流であり、WPA2はちらほらという感じだった気がします。
自身のハニーポットでペネトレーションテストを行った過程では、

- パケットキャプチャ
- 辞書攻撃
- ブルートフォース攻撃
- chopchop攻撃
- ARPリクエスト・リプライ攻撃

の仕組みを学びました。

他にも、`IEEE 802.11`に関する規格の違い等も学びました！
それから10年程月日が経った今、無線LANセキュリティやIEEE 802.11の現在を知りたくなったので、Qiitaで書き記そうと考えています！

## cURLやSeleniumに関して

・cURLを用いてHTTPをリクエストを行う
・ヘッドレスブラウザのSeleniumで行う

同じスクレイピングでもどう違うかというのを、レンダリングをメインテーマに書き記そうと考えています！

## 再帰処理に関して

再帰処理って、処理の連想は容易に出来ますが、いざ書こうとすると意外と容易ではないこと多かったりしますよね。

そこで、再帰処理をスムーズに書くための個人的な思索を紹介しようと考えています！
Jetson Nano で YOLO を使う方法

#概要
Jetson Nanoを使用してYoloを動かしてみようと思い、インターネット上にあるやり方を真似してみましたが、うまく画像類推させることができなかったので、自分なりにできたやり方をまとめていきたいと思います。
#開発環境
opencv 3.3.1
Python 2.7.15+
#注意すべきこと
jetson nanoには最初からopencvが入っているので、opencv-pythonを別でインストールしてしまうと、競合してエラーが起こってしまうので、余計なものを入れないように注意する。
アンスンストールするときは

```
$pip3　uninstall opencv-python 
```


#準備
###高速化の設定
Jetson NanoでYoloを効率よく使うために設定します。

```
$ sudo nvpmodel -m 0
$ sudo jetson_clocks
```

###darknetのインストール
gitからdarknetを落とす

```
$ git clone https://github.com/pjreddie/darknet.git
$ cd darknet
```

###Yoloのダウンロード
Yoloは高速化をしていてもJetson Nanoで動かすのは厳しいのでここではYolo-Tinyを使用します。 

```
$ wget https://pjreddie.com/media/files/yolov3-tiny.weights
```

###Makefileの編集

```
$ gedit makefile
```
GPU,CUDA,OPENCVを使用できる状態にします。

```
GPU=1
CUDNN=1
OPENCV=1
```
コンパイルする。

```
$ make
```

```
$ ./darknet
```
上記のコマンドを入力してusage: ./darknet のようなエラーが出れば、makeされています。
#動作確認
###画像判別

```
./darknet detect cfg/yolov3-tiny.cfg yolov3-tiny.weights data/画像の名前.jpg
```

###カメラによる画像認識

```
./darknet detector demo cfg/coco.data cfg/yolov3-tiny.cfg yolov3-tiny.weights　"'nvarguscamerasrc ! video/x-raw(memory:NVMM), width=1280, height=720, format=(string)NV12, framerate=(fraction)30/1 ! nvtee ! nvvidconv flip-method=2 ! video/x-raw, width=(int)1280, heught=(int)720, format=(string)BRGx ! videoconvert ! appsink'"
```
Swift の改行コードの挙動

Swift の改行コードの挙動について勘違いしていたので、メモとして記録する事にします。きっかけは、`Foundation` の `NSScanner`/ `Scanner` が使いにくいので、独自で同様な物を実装しようとして色々実験していた時に以下のようなコードが動かない事に気がつきました。

```.swift
let carriagereturn: Character = "\u{d}"
let linefeed: Character = "\u{a}"

let string = "123\r\n456\r\n789\r\n"
print("begin")
for ch in string {
	switch ch {
	case carriagereturn: print("CR")
	case linefeed: print("LF")
	default: break
	}
}
print("end")
```

あれ！CRもLFも出力されません。

```.console
begin
end
```

そこで、こんなコードを書いてみました。最もこのコードにたどり着くために紆余曲折しているわけですが…

```.swift
var string1 = "abc\r123\r" // CR
var string2 = "abc\n123\n" // LF
var string3 = "abc\r\n123\r\n" // CRLF
var string4 = "abc\r\n123\n\r" // irregular

var strings = [string1, string2, string3, string4]

for string in strings {
	print(string.map { $0.debugDescription }.joined(separator: ",　"))
}
```

なんと、`CRLF` は一つのキャラクターとして処理されていました。

<pre>
"a",　"b",　"c",　"\r",　"1",　"2",　"3",　"\r"
"a",　"b",　"c",　"\n",　"1",　"2",　"3",　"\n"
"a",　"b",　"c",　"\r\n",　"1",　"2",　"3",　"\r\n"
"a",　"b",　"c",　"\r\n",　"1",　"2",　"3",　"\n",　"\r"
</pre>

改行コードの分別は地味に面倒なので、これはこれでありがたいですが、カッテを知らないとすったもんだと無駄にエネルギーを消費していました。

```.console
$ swift --version
Apple Swift version 5.1.3 (swiftlang-1100.0.282.1 clang-1100.0.33.15)
Target: x86_64-apple-darwin19.2.0
```

ひょっとして、`Swift 5` から挙動が変わったのかと、手持ちですぐ試せた、`Apple Swift version 4.2` で試してみましたが、結果は同じでした。
2019年度新卒 社内SE 約一年間の軌跡

#はじめに
やったこと、触ったものについて定期的に後から振り返ることは、「より深く知識を定着させる」「今の自分を客観的に捉える」上で非常に効果的です。

今回は社内SEとして2019年に入社した新卒1年目の自分が約8ヶ月間業務を通してやってきたこと、出来るようになったことを振り返り、それを踏まえて2020年の目標を書いてみます。

# 弊社での自担当プロダクト
いろんなログを収集分析してレポートを作成するサービスになります。
現在はブラウザ利用の社内ツール開発に携わっており、主要な言語はPHP, インフラは殆どAWSを利用しています。
部署内は、基本的にフロントエンドやバックエンドのみに特化したエンジニアはおらず、皆が色々な業務に広く携わることが出来る環境です。


## 自分のスキル
新卒入社の自分でしたが、学生時代に経験したプログラミングと言えば、

- pythonで単純なアルゴリズムを書いて動かしてみる。ソートとか再帰とか
- Javaの参考書に沿ってコーディング。オブジェクト指向とはなんぞやを肌で感じる
- 参考書とにらめっこしながらRでコマンドを叩き多変量解析した気になる

レベルに留まっており、決して「プログラミング経験者」の枠に入るレベルではありませんでした。

## 2019年の取り組み

世間一般の社内SEの業務を把握していませんが、当部署では「事業部からの問い合わせ業務」と「開発業務」の大きく2つに分けられます。
自分は部署に配属後、研修期間があり、徐々に実務といった流れだったので、今回は2つの期間に分けて書いていきます。

## 2019年5月~9月 研修期間
まず配属直後に、エンジニアの基礎(Web・開発プロセス・プログラミング他)をインプットし、インプットした内容を2~3日に一回チーム内プレゼンをする研修を行いました。
頻繁にアウトプットを行う中で資料をブラッシュアップしていくので、自分がよく陥るインプットにフォーカスを当てすぎる思考を捨てられました。
よく言われていることではありますが、アウトプットすることで定着させるという考え方も非常に重要なことだと感じました。

###その他業務や学び

##### コーディング 
プログラミング学習サイトのProgateで学習後(PHP・HTML/CSS/JS・SQL・Git・Python・Bash)、ログイン機能を持った簡易的なWebサイトを作成。
##### Redmine 
部署でプロジェクト管理に利用。社内ルールを含めたチケットやバージョニング等管理方法について学びました。
##### 事業部からの問い合わせ 
簡単なものから徐々にシステム寄りへ。分かりやすく伝える文章を考える機会になっています。



## 2019年9月~12月 実務期間
この頃から、問い合わせ業務に加え開発業務に携わっています。フロント部分(Html/CSS/JS)から始まり、ロジック部分の修正等を頂くことも徐々に増えてきています。
アバウトな実装内容は下記の通りです。

- ファイルや文字列入力画面でのバリデーション追加
- データの集計に予約機能を追加 
- 画面の一部修正
- 正常動作監視用ジョブ修正

触ったツールや言語の記載は以下の通りです。

#### PHP/Html/CSS/Javascript
2つのフレームワーク(cakephp/Laravel)を使用した開発環境です。
各言語の基本文法から始め、PHPではDB接続、AWS各種サービスの操作、
JavaScriptではDOMの操作やAjax通信を覚えました。

#### Shell Script
デプロイや他プロダクト間のデータ連携を行う定時ジョブ実行にJenkinsを利用しているので
コードを見る機会はとても多いですが、自分で書くことは簡単なタスクの自動化やCrontabで定期的なデータ移行を行う程度・・・

#### Git 
Git bashやEclipseのGit連携を利用しています。CloneからMergeまで実際に手を動かし覚えました。

#### AWSサービス
##### S3
- バケットポリシーとは
- バージョニング利用
- バケット同期
- プットイベント
- Cliを用いた操作

##### Athena
- Prestoエンジン独自の関数
- パーティション等スキャン量を考慮したクエリ
- DDL,DML
- Cliを用いた操作

##### Cloudfront
- Cloudfrontの役割や出来ることの理解
- ビヘイビアによるリクエスト振り分け

##### Cloudwatch
- ダッシュボードやアラームの基本設定

##### Route 53
- ルーティングポリシー種別の理解

##### EC2
- SnapShot,EBSの管理
- AutoScaling,ロードバランシング
- Cliを用いた操作

##### Trusted Adviser
- 利用サービスの運用コスト把握


###その他業務や学び

#### ブラウザ毎の挙動確認検証
Appleが提供するSafariのITPによる影響等、Cookieの動作に影響のあるブラウザをアップデートに応じて検証を行いました。


#### システム概要のドキュメンテーション
システムの大まかなフローや仕様、DB定義書はExcelベースで作られています。
新規に参画したエンジニアの方が参照する資料であり、一部更新がなされていない部分を発見しては更新する作業になります。

 
## 2020年の目標
簡単に2019年を振り返ったので、今年取り組みたいと思っていることを書いていきます。

### 他言語の学習
普段書いているphpは動的型付け言語なので、静的型付け言語や関数型言語の知識をつける必要があると感じています。
完全に主観ですが、特定言語に特化するよりも複数言語を扱える方が実装できる幅が広いと考えているので、これからの需要を鑑み、GoやScalaなどもプライベートで触り、業務に活かせる部分を見出していきたいです。

### 他クラウドサービスの学習
サービスシェアではAWSが頭一つ抜けていますが、GCPやAzure等他サービスに触れることで今まで気づかなかったAWSのメリットやデメリットが
見えてくると思います。違いを把握した上で場面場面で使い分けることが出来れば理想形だなと勝手に妄想しています。
AWSに関しては、引き続きより多くのサービスに触れること、また資格の取得も考えています。


### コミュニケーション力向上
組織として仕事をしている以上、人と人との繋がりを断つことは出来ません。どんなに能力や知識があっても、それらを伝える力や逆に読み取る力が必須です。自分は簡潔に伝えることが苦手なので、積極的にプレゼンの場やアウトプットの機会を設けます。


## おわりに
改めて文章にすると、想定より学びが多かったか少なかったか判断出来ると思います。~~(自分は思っているよりも全然少なかった。)~~


流れの早いWebの世界では新たな知識のキャッチアップも立派なスキルの1つだと思うので、定期的に振り返り、次に何を身につけるべきか考えるきっかけとしたいです。

2020年、また一歩成長する為のモチベーションの1つとして、皆さんも一年を軽く振り返る機会を作ってみては如何でしょうか。
【ふくだ仕事録】【1日目】

# ふくだ仕事録とは？
ふくだが仕事していて「なるほど！」と思ったことに関しての備忘録。
業務上のテクニックや、考え方、使えるライブラリなどをメモっていこうと思います。
他人に見せるように書いているわけではないので、すごく読みにくいです。

※ふくだ備忘録は、概念や汎用的な知識。ふくだ仕事録は、具体的なやり方やライブラリなどのメモ。って感じですみ分けます。

# フロントエンド

### jsで引数が複数ある場合は、オブジェクト形式で渡した方が良さそう。
引数多いと、指定する順序の間違いでエラーになるし、各それぞれの引数の意味が分かりにくくなる。
それを解消するために、オブジェクト形式で渡しておいた方が良さそう。（初期値も視覚的に見やすくなる気がする）

```javascript:example.js
//関数作成時
const cooking = ({
  fruit,
  vegetable,
  meet = kobebeef,
  seafood = tuna,
}) => { 
//いろんな処理
}

//関数使用時
cooking({
  fruit:apple,
  vegetable:tomato,
  seafood:salmon,
});
  
```

# バックエンド

# サーバーサイド

# ビジネス


# 今日の一言
ローカルで`.gitlab-ci.yaml`の動作確認をする

# 背景

`GitLab-CI`を活用するために`.gitlab-ci.yml`を修正するが、その動作確認のためにpushするのは面倒だし、logが汚れるので避けたい。

GitLabサーバへpushする前に、ローカル環境で`.gitlab-ci.yml`の変更を動作確認する方法を調べた。

# 環境

* CentOS 7.5.1804
* gitlab-runner v12.6.0

# ローカルに`gitlab-runner`をインストール

> あまり環境を汚したくないので、できればDockerコンテナ版で動かしたかったが、やり方を調べる時間がなかったので、通常版のgitlab-runnerを使用する。

```bash
# リポジトリを追加
curl -O https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.rpm.sh
sudo bash ./script.rpm.sh
# インストール可能なgitlab-runnerのバージョンを取得
yum list gitlab-runner --showduplicates | sort -r
# 指定したバージョンのgitlab-runnerをインストール
sudo yum install -y gitlab-runner-12.6.0-1
```

# `.gitlab-ci.yml`のあるパスに移動して動作確認

```bash
cd {your_local_repo_path}
# docker executor
gitlab-runner exec docker {your_job_name}
# shell executor
gitlab-runner exec docker {your_job_name}
```
[Angular] 子から親のメソッドを実行したらメソッド内のServiceでエラーが発生してハマった

[[Angular] 子コンポーネントから親コンポーネントのメソッドを実行して戻り値を受け取る](https://qiita.com/kozzzz/items/97e4910e8eee306a520b)
からの派生記事です。

## やりたかったこと
- 子から親のコンポーネントを受け取りメソッドを実行する
- 親メソッド内でDIしたServiceを呼んでいる
- 戻り値を受け取りたい

## ダメな例
```html:parent-compomemt.html
<parent-compomemt>
  <child-compomemt [parentFunc]="parentFunc">
</parent-compomemt>
```
### 親から子へ渡す
```js:parent-component.ts
constructor (
   private hogeService: HogeService,
) {}

async parentFunc() {
  return this.hogeService.getHoge();
}
```
### 子で受け取る

```js:child-component.ts
@Input() parentFunc: () => Promise<Hoge>;

async callParentFunc() {
 const hoge = await this.parentFunc();
}
```
しかし、実際に実行するとメソッド内のthisが`ChildComponent`を参照しており
hogeServiceが`undefind`となってしまう。

## 解決策

### その１

一番簡単な解決方法。
子コンポーネント内では使用しないがDIしておく。
ただ、一見使用しないDIに見えるので気持ち悪い。

```js:child-component.ts
@Input() parentFunc: () => Promise<Hoge>;

constructor (
   private hogeService: HogeService,
) {}

async callParentFunc() {
 const hoge = await this.parentFunc();
}
```

### その2

私はこの方法で解決しました。
親のコンテキストを渡して実行する。
親で定義しているメソッドなので親のコンテキストを渡してあげるのが自然だと私は思う。

```js:child-component.ts
@Input() parentFunc: () => Promise<Hoge>;

private _parent: ParentComponent;

constructor (
  @Host() parent: ParentComponent,
) {
  this._parent = parent;
}

async callParentFunc() {
 const hoge = await this.parentFunc.call(this._parent);
}
```
## まとめ
今回はServiceでしたが、親コンポーネントで閉じているオブジェクトを使用する場合は注意が必要ということです。
子コンポーネントで閉じているオブジェクトは引数で渡してあげましょう。
`# frozen_string_literal: true` 内でBOM付きCSVファイルを生成する

# CSVをExcelで開くにはBOMをつけておけば良い

[UTF-8のCSVファイルでも、BOMをつけておけば、Excelで開ける](https://primarytext.jp/blog/1275)ということを昨日知りました！

Rubyでサンプルを書いてみます。

```ruby:with_bom_csv.rb
# frozen_string_literal: true

require 'csv'

File.open('with_bom.csv', 'w:UTF-8') do |file|
  bom = "\uFEFF"
  headers = ['id', 'first name', 'last name', 'age']
  csv_data = CSV.generate(+bom, headers: headers, write_headers: true) do |csv|
    csv << ['1', '太郎', '田中', '20']
    csv << ['2', '次郎', '鈴木', '18']
    csv << ['3', '亜海', '佐藤', '19']
    csv << ['4', '祐実', '安達', '21']
    csv << ['5', '三郎', '近藤', '34']
  end
  file.write(csv_data)
end
```
![with_bom.csv in Excel](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62293/f7ef3182-4702-ec5a-79db-0f6460fae154.png)
CSVファイルの内容は[CSV.generateのリファレンスマニュアル](https://docs.ruby-lang.org/ja/latest/method/CSV/s/generate.html)を漢字に書き換えました。

# 注意事項

`# frozen_string_literal: true` をファイルの先頭につけていて、文字列が凍結されるので、CSV.generateに渡すbomを `+bom` と書いて解凍しています。解凍を忘れると、 `not opened for writing (IOError)` でエラーになってしまいますよ。


# コメントを受けての追記(2020-01-09 14:19)

もう少し適切な形に書き換えてみました。

```ruby:with_bom_csv.rb
# frozen_string_literal: true

require 'csv'

BOM = "\uFEFF"
headers = ['id', "first\nname", "last\nname", 'age']
data = [
  { id: '1', first_name: '太郎', last_name: '田中', age: '20' },
  { id: '2', first_name: '次郎', last_name: '鈴木', age: '18' },
  { id: '3', first_name: '亜海', last_name: '佐藤', age: '19' },
  { id: '4', first_name: '祐実', last_name: '安達', age: '21' },
  { id: '5', first_name: '三郎', last_name: '近藤', age: '34' }
]

File.open('with_bom.csv', 'w:UTF-8') do |file|
  file.write BOM

  csv = CSV.new(file, headers: headers, write_headers: true)
  data.each do |row|
    csv << [row[:id], row[:first_name], row[:last_name], row[:age]]
  end
end
```
![with_bom.csv with CR in Excel](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62293/c93cd3bd-bed3-2963-5253-254afa2e99b4.png)
現実のCSV出力をイメージして、データをループで出力するような形にしました。
CSVファイルの内容を一時的な文字列として作成すると、巨大になる恐れもあるので、ファイル出力の形に変えてみました。
BOMをつけるとExcelで開けるという話でしたが、実は改行を含んでいても適切に開けるという点もメリットです。それを表現するためにわざわざ改行コードを入れてみました。

元々は、「CSV.generateに渡す文字列が凍結されているとエラーになるので注意！」というつもりで書いたエントリーだったのですが、CSV.generateを使わなくなっちゃいましたね。。。

# 参考

- [Excelで開くと文字化けするUTF-8のCSVを文字コードを変換せずに開く方法 | プライマリーテキスト](https://primarytext.jp/blog/1275)
- [BOM付きUTF-8で文字化けしないCSV出力 | Railsの小技 | DoRuby](https://doruby.jp/users/ueki/entries/BOM%E4%BB%98%E3%81%8DUTF-8%E3%81%A7%E6%96%87%E5%AD%97%E5%8C%96%E3%81%91%E3%81%97%E3%81%AA%E3%81%84CSV%E5%87%BA%E5%8A%9B)
- [singleton method CSV.generate (Ruby 2.7.0 リファレンスマニュアル)](https://docs.ruby-lang.org/ja/latest/method/CSV/s/generate.html)
マイクロサービスの認証認可周りについてのまとめ

そもそも、ユーザー情報や会社情報は、密結合になりやすい
実装開始時はアプリのDB上にガチガチに実装されていることが多い

なぜ分離したくなるか

- email認証以外追加したい、social認証ならOKだけどそれ以外もガンガン追加したい
- samlやopen ID connectなどの利用
- マイクロサービス


分離時の観点

- 各サービスから、認証認可を呼び出せる
  1. 認証認可サーバーを建て、API連携する
  2. 同じドメインであればクッキー管理もできる

- ユーザー情報を取れる
  1. ナビゲーションや設定などに使用するユーザー情報やユーザーの属性情報(属する会社情報)、ユーザーの設定情報など
  
- セッションの維持(タイムアウト、Single Sign Out)



方法

- 共有データベース
  密結合
  1. 問題点、大量のwriteの発生、大量のreadの発生 => redisなどを使う

- ユーザー情報APIとして切り出し
  1. アクセス毎のユーザー情報の取得となる場合、毎回アクセスが発生するのでエンドポイント側、アクセス側でキャッシュする必要が生じる
  2. サービスごとにセッション管理やユーザ情報取得(userやcompanyの情報)のコードを書くのは綺麗でない。gem or apiを作って対応できればよし

問題点


そもそも各サービスに認証認可を考えさせるのではmicroserviceにする意味ないのでは
- API Gateway pattern
https://microservices.io/patterns/apigateway.html
https://sdtimes.com/apis/securing-microservices-the-api-gateway-authentication-and-authorization/

- Auth0
apiに任せられる、ユーザーの情報取得は一つサービス作る必要あり


https://medium.com/tech-tajawal/microservice-authentication-and-authorization-solutions-e0e5e74b248a

https://stackoverflow.com/questions/29644916/microservice-authentication-strategy

https://aws.amazon.com/jp/blogs/compute/architecting-multiple-microservices-behind-a-single-domain-with-amazon-api-gateway/

https://codeburst.io/i-believe-it-really-depends-on-your-environment-and-how-well-protected-the-different-pieces-are-7919bfa6bc86

https://www.davideguida.com/handling-authentication-and-authorization-in-microservices-part-1/

https://www.owasp.org/images/2/20/Microservice_Security.pdf


- Auth0の良いところ
プロダクトが大きくなるとやりたい6つのことをやる前提で作られている

Single Sign On
Securely and easily implement Single Sign On for your customers, partners and employees

Universal Login
Standard-based login infrastructure with centralized feature management for websites and native apps

Breached Passwords Detection
Protect your users and services from password leaks.

User Management
The simplest and easiest to use tools to help administrators manage users.

Multifactor Authentication
The most usable and friction-free multifactor authentication experience.

Passwordless
Allow users to login without the need to remember a password.
github　違うブランチのリモートをPULLしたいときのメモ

## リモートブランチをプルしたい
`feat/test-01` みたいなブランチがあったとし、そのブランチをフェッチしてからプルする際のメモ
`git pull origin pullしたいリモートブランチ名:ローカルブランチ名`

で例でいえば
`git pull origin feat/test-01:feat/test-01`
とやるとできる

## どんな例でおきた
仕事ようのPC,自宅のPC分けており
仕事用のPCで開発ぼこぼこしたあとにリモートにえいや〜とプッシュをし、
それを「さて仕事やるか、お」という感じのノリで自宅PCを開いてやるときに
最新の状態にする必要があるが、その際によくおきていた（毎回面倒な時は、ブランチを新しく作り直していた）

gitは奥が深い（もっと勉強します、、、汗）