OmniAICreator/Qiita-1.07M huggingface dataset:
Ruby  で平仮名を打つとエラーが発生した！！

rubyで平仮名を打つとエラーが発生していろんなことをしてみたが解決できなくて、

which ruby

をしてみると、

/usr/bin/ruby

とのことだった。

echo $PATH

をした後に

open ~/.bash_profile

をしまして、

下記２つのがあれば良いらしいが、よくないことに、全然違うことが書いてあった。
①export PATH="$HOME/.rbenv/bin:$PATH"
②eval "$(rbenv init -)"

.bash_profileの中身を削除して上記のものを書いて保存をした後に、

$ source ~/.bash_profile

をして反映させる。

which ruby

をしてみると、

/Users/自分の名前/.rbenv/shims/ruby

と言う感じでいけた。

ruby --version

をするとしっかりと反映されていた。

参考にした記事
https://qiita.com/SAYJOY/items/be06302ae8a2fac7f0c4

めちゃくちゃわかりやすかったです、ありがとうございましたww
Linuxでsshサーバをたてよう

#今回の目的
Linux(Ubuntu18.04.3)でLAN内でsshサーバーを立ててMacからログインしよう

#sshサーバーをたてましょう
まずは下のコマンドでパッケージをインストールしてからサービスを起動させましょう

```
# sudo apt-get install openssh-server
# systemctrl start ssh
```
ちなみに、サービスを止めたり、ステータスを確認するには下のコマンドで可能です

```
# systemctrl stop ssh
# systemctrl status ssh
```
`systemctrl`でサービスの設定を変更することが可能です

#別のデバイスからsshでログインしましょう
今回は、Macのターミナルを使ってログインします

```
# ssh -l xxx IPアドレス
```
上のコマンドを実行すればLAN内のデバイスからならssh接続可能です。
`xxx`はリモートホストのログイン名になります。`-l`オプションはログイン名を指定するために必要です。
あとは、パスワードを入力して完了です。

#Next
ローカルのsshは家にサーバーがある人用ですね。
外部からのssh接続も挑戦してみます。
[playframework2.6]ehcacheのログ有効化/logback.xml 

Play組み込みのehcacheのDIがうまく動作してくれないので、独自にehcache2.10.4を使ってキャッシュヘルパーを実装したのですが、一部のオブジェクトでキャッシュされないという事象が発生しました。

当初、`new Element(key, obj)`も`cache.put(elem)`で例外が発生しないので、キャッシュ処理でなく周辺を探していたのですが、ログ出力設定が漏れていただけで、実際にはehcache内部でエラーが発生していました。

logback.xmlに設定を追加したらしっかりと問題を報告してくれました。

```config:logback.xml
	<logger name="net.sf.ehcache" level="ALL"/> 
```

# 参考
spring - How to enable logging of Ehcache - Stack Overflow
https://stackoverflow.com/questions/10705107/how-to-enable-logging-of-ehcache/10705998#10705998
Gitチートシート

備忘録兼誰かの役に立てばと思い、Gitのチートシートを作りました。
Gitはそんなに使ったことがないので、間違っていたり、これ便利だよということがあったら、ご指摘いただけたら嬉しいです。

## 基本用語

#### リモートリポジトリ
専用のサーバに置く共有するためのリポジトリ


#### ローカルリポジトリ
自分の手元のコンピュータ上に配置するリポジトリ


#### コミット
リポジトリに変更を記録すること
もしくは変更した記録


#### ワークツリー
Gitの管理下に置かれた作業しているディレクトリ


#### インデックス
リポジトリにコミットする準備をするための場所


#### プッシュ
ローカルリポジトリの変更履歴をリモートリポジトリにアップロード


#### プル
リモートリポジトリからローカルリポジトリを更新


#### クローン
リモートリポジトリを複製してローカルリポジトリに


#### ブランチ
履歴の流れを分岐して記録していくためのもの

- マスターブランチ
最初に作成されるブランチ。masterという名前。

- 統合ブランチ
分岐したものが統合されていくブランチ

- トピックブランチ
課題に関する作業を行うために作成するブランチ


#### HEAD
現在使用しているブランチの先頭


#### チェックアウト
作業するブランチを切り替える

#### マージ
現在のブランチへ、他のブランチの更新を取り込む処理

#### タグ
- 軽量タグ
名前を付けられる
- 注釈付きタグ
名前、コメント、署名を付けられる

## Gitインストール時に行う作業

#### ユーザー名とメアドの設定

```
$ git config --global user.name "<ユーザ名>"
$ git config --global user.email "<メールアドレス>"
```

#### Git Bash上で日本語を正しく表示できるようにする

```
$ git config --global core.quotepath off
```

## リポジトリ作成時に行う作業

#### ディレクトリに移動してローカルリポジトリ作成

```
$ git init
``` 
    
#### リモートリポジトリを追加（originは他の名前でも可）

```
$ git remote add origin URL
``` 

#### （すでにリモートリポジトリがあるとき）ローカルリポジトリとして複製

```
$ git clone URL
```    
        
## 実行コマンド
        
#### ファイルをインデックスに登録

```
$ git add ファイル  (スペース区切りで複数指定)
$ git add .  (こうするとすべてのファイル)
```    
    
#### インデックスに登録後、コメントをつけてコミット

```
$ git commit -m "コメント"
```    
    
#### コミット後、リモートリポジトリにプッシュ

```
$ git push -u origin master
二回目以降orクローンしたものは↓
$git push
````    
    
#### リモートリポジトリからプル

```
$ git pull origin master
```

## ブランチ操作コマンド

#### ブランチの作成

```
$ git branch ブランチ名
```

#### ブランチの削除

```
$ git branch -d ブランチ名
```

#### ブランチのチェックアウト

```
$ git checkout ブランチ名
$ git checkout -b ブランチ名 (作成とチェックアウトを同時に)
```

#### マージ

```
$ git merge ブランチ名
```

## タグ操作コマンド

#### 現在のHEADに軽量タグをつける

```
$ git tag タグ名
```

#### 注釈つきタグをつける

```
$ git tag -am "コメント" タグ名
```

#### タグを消す

```
$ git tag -d タグ名
```

## 確認コマンド

#### ワークツリーとインデックスの状態を確認

```
$ git status
```    
    
#### リポジトリの変更履歴を確認

```
$ git log
```    
    
#### リポジトリの変更をより見やすく表示

```
$ git log --graph --oneline
```

#### タグ情報を含めた変更履歴を表示

```
$ git log --decorate
```

#### ブランチのリストを表示

```
$ git branch
```

#### 現在のHEADのタグを確認

```
$ git tag
$ git tag -n （注釈つき）
```


## その他の役立ちコマンド

#### エイリアスの設定

```
$ git config --global alias.短縮形 展開形
```

#### コミットからの相対位置
~(チルダ):何世代前の親かを指定する
^(キャレット):ブランチのマージで親が複数ある場合に、何番目の親かを指定する

```
Head~1
Head^1
```

### 参考URL

- [サルでもわかるGit入門〜バージョン管理を使いこなそう〜【プロジェクト管理ツールBacklog】](https://backlog.com/ja/git-tutorial/)

- [今さら聞けない！GitHubの使い方【超初心者向け】 \| TechAcademyマガジン](https://techacademy.jp/magazine/6235)

- [gitで便利なエイリアス達 - Qiita](https://qiita.com/peccul/items/90dd469e2f72babbc106)

- [はじめてのGit！initコマンドでリポジトリを作成してみよう！ \| 侍エンジニア塾ブログ（Samurai Blog） - プログラミング入門者向けサイト](https://www.sejuku.net/blog/71268)
格子暗号とフーリエ変換

## 概要
格子暗号のバックエンドでなぜフーリエ変換を使うNTLなどのライブラリが使われているかを初歩的ながら考えてみた。備忘録的な要素あり。

## 内容

- 格子暗号
- 離散フーリエ変換(DFT)
- 高速フーリエ変換 (FFT)
- バタフライ演算　

## 格子暗号
量子コンピュータ耐性があり、さらに加算と乗算に関しての完全準同型性があるとされ注目されている次世代の暗号スキームのこと。
ひどく簡単にまとめると、多項式環を公開鍵である多項式でイデアル化することによって暗号空間へとマッピングし、その空間での準同型性を用いることで、暗号空間での演算を可能にしている。
大きい多項式を用い、それらの演算をする際に、畳み込み演算が必要となる。この際に、離散フーリエ変換が高速化のために必要となる。

## 離散フーリエ変換
正直言って、[wikipediaの離散フーリエ変換](https://ja.wikipedia.org/wiki/%E9%9B%A2%E6%95%A3%E3%83%95%E3%83%BC%E3%83%AA%E3%82%A8%E5%A4%89%E6%8F%9B)の記事で説明は事足りる。
ひどく簡単にまとめると、有限体の標本点を用いて離散化されたフーリエ変換を行う。いろいろな応用先があるが、その１つとして多項式の乗算（本質的には畳み込み）を簡単に行えるため、格子暗号のライブラリでは離散フーリエ変換を裏で用いている。
この[project nayukiのページ](https://www.nayuki.io/page/number-theoretic-transform-integer-dft)に多項式の乗算を、DFTを用いて高速化するやり方がわかりやすくまとめられていたので参考にしたい。

## 高速フーリエ変換
これに関しても[wikipediaの高速フーリエ変換](https://ja.wikipedia.org/wiki/%E9%AB%98%E9%80%9F%E3%83%95%E3%83%BC%E3%83%AA%E3%82%A8%E5%A4%89%E6%8F%9B)の記事がわかりやすい。
簡単にまとめると、高速フーリエ変換は上の離散フーリエ変換を高速に行うための手法である。例えば、 N次元の多項式同士の乗算を考える時に、お互いを離散フーリエ変換したもの同士を乗算し、結果を離散フーリエ逆変換すると畳み込み結果が得られるが、これを正直にやるとO(N^2)の計算量が必要である。しかし、高速フーリエ変換を用いると、これがO(NlogN)で済む。これは、Nが因数分解できるとき、例えばN=PQとできるときは、N次元のベクトルに対する離散フーリエ変換が、P組のQ次元離散フーリエ変換に変換できるからである。この際、Nが２の乗数で書かれているとすると、この落とし込みを繰り返すことで最終的に２次の離散フーリエ変換（２次と４次はより早く求めることができるため、区別される）にできる。このため、格子暗号では多項式の剰余環のモジュラスとして、２のN次のオーダーの多項式を使うことが一般的である。（多分他にもこれを使う理由はある。）

## バタフライ演算
上の高速フーリエ変換において、低次の２次もしくは４次の離散フーリエ変換を行うことを、バタフライ演算と呼ぶ。


これからも格子暗号などを中心に簡単に論文などをまとめていければいいと思うので、もし興味ある人いましたら「いいね」、「コメント」お待ちしております。

おわり
機械学習始めました

# 機械学習始めました

学習戦略
- Pythonの理解
- 各基本モデルと基礎数式の理解
　　決定木
　　回帰
　　ニューラルネットワーク

- 最近のトレンド

*********************

機械学習を始めるにあたり、ネットで気になる情報を集めました。

YOLOの記事が分かりやすいです。
https://orako-column.com

物体検知が分かりやすいです
https://www.slideshare.net/YujiKobayashi7/foss4g-2018-tokyo

物体検知
　　RCNN[2013]とDeepLearning
　　FasterRCNN[2015]とRegion Proposal Network
　　YOLO[2015]とone stage detector
　　SSD[2016]とMulti-scale feature maps
　　Feature Pyramid Networks[2017]
　　RetinaNet[2017]とFocal Loss
　　M2Det[2018]とMulti-Level Feature Pyramid Network
　　Cascade RCNN[2019]
　　CBNet[2019]

　　https://lib-arts.hatenablog.com/entry/object_detection1
　　https://lib-arts.hatenablog.com/entry/object_detection2
　　https://lib-arts.hatenablog.com/entry/object_detection3
　　https://lib-arts.hatenablog.com/entry/object_detection5

PyTorch
　　M2Detの著者実装を読みます。
　　https://lib-arts.hatenablog.com/entry/object_detection4
pandasのMultiIndexで階層取り出しでミスった

pandasのMultiIndexは便利なのだが、単純にIndexの多次元版として扱っていたらハマったのでメモしておく。

## ハマったこと

例として次のようなテーブルが`hoge.csv`として存在することとする。

|||val|
|:--:|:--:|:--:|
|1|a|b|
|2|c|d|
|3|a|d|
|4|b|c|
|5|a|b|

`hoge.csv`のval以外の列をindexとして読みだしてみるとMultiIndexのDataFrameとして読みだされる

```python
>>> import pandas as pd
>>> df = pd.read_csv("hoge.csv", index_col=[0, 1])
```
```
>>> df
    val
1 a   b
2 c   d
3 a   d
4 b   c
5 a   b
```

この適当なDataFrameをvalでフィルタリングしてみる

```python
>>> tmp_df = df.query("val=='b'")
```
```
>>> tmp_df.index
MultiIndex([(1, 'a'),
            (5, 'a')],
           )
```

全5要素のDataFrameから2要素が取り出された。

更に、フィルタをかけた結果に対して`levels`プロパティの0階層目を取得すると、`1,5`が取り出されるかと思いきや…

```python
>>> tmp_df.index.levels[0]
```
```
Int64Index([1, 2, 3, 4, 5], dtype='int64')
```

フィルタに無関係で**オリジナルのDataFrameの0階層目の要素群が取り出される**
テーブルの値に条件を設けてフィルタ後の状態で、各階層の値を取り出したいことはあるので、これでは困る。

## 解決

levelsはあくまで、各階層に含まれる要素を格納しているリストで、各level間の関係を定義することで組み合わせて実現しているみたい。

そこで、MultiIndexを解除して、最終的に取り出したい階層を残したシングルのIndexにしてからフィルタをかける。

```python
>>> df.reset_index(level=1)
  level_1 val
1       a   b
2       c   d
3       a   d
4       b   c
5       a   b
>>> tmp_df = df.reset_index(level=1).query("val=='b'")
>>> tmp_df.index
Int64Index([1, 5], dtype='int64')
```

こうすると、そのままIndexがフィルタの要素通りになるので、フィルタしてからある階層を取り出したい時は、上記のように`reset_index`で対応しないといけない。

`reset_index`ではMultiIndexのカラム名が降られていればその名称を、降られていなければ`level=`の引数に解除したい階層の番号を指定する。
【リベンジ】全員登壇！FlashTalk大会 #1に行ってきた話

# 目的

- 題名の登壇イベントに行ってきて得たものをまとめる

# 参加させていただいたイベントの内容

- 参加者全員が登壇するイベントである。
- 一般参加枠だとイベント中に「自己紹介」と「技術的な話題」の二つについて１分で話す。
- 1分をすぎたら強制終了されるが、短いなら1分経つまで告知などをしてもOKである。
- 発信力を鍛えるためのイベントである。
- お固い登壇会ではなく、みんなで登壇の練習をした感じである。

# 参加させていただくイベントの詳細ページ

- connpassのリンクを下記に記載する。  
[【リベンジ】全員登壇！FlashTalk大会 #1](https://engineers.connpass.com/event/153594/)

# エンジニアの登壇を応援する会って？？

- エンジニアにアウトプットによって成長することを伝え、支援を行うコミュニティである。
- 主に「勉強会やカンファレンスに登壇すること」「ブログや技術書を執筆すること」などの内容の支援を行なっている。
- エンジニアの登壇を応援する会の各リンクを下記に記載する。  
connpasグループ: [エンジニアの登壇を応援する会](https://engineers.connpass.com/)  
Twitter: [エンジニアの登壇を応援する会](https://twitter.com/engineers_lt)  
参加ガイド: [README](https://esa-pages.io/p/sharing/10407/posts/320/0bb2faf43a53b3226482.html)  

# オイシックス・ラ・大地株式会社さん(会場スポンサー)

- エンジニアのための会場提供を行なっている。
- ２日分の野菜を取れる野菜ジュースをもらった。これを飲めば明日は野菜を取らなくていい！やったね！
- 三つの会社？事業？(Oisix、らでぃっしゅぼーや、大地を守る会)がくっついて今の社名になったらしい。
- 一般のお客さん向けの食品宅配事業などを展開している。
- 会場無いに季節柄おせちのポスターなどが張ってありとても美味しそうだった。

# 人生初登壇をして見ての感想

- 考えや思っていることを言葉にすることって本当に難しい。
- こればっかりは一朝一夕でうまくなるものでは無いと痛感した。話がうまくなりたいなら人前に積極的に出る必要あり。
- しかし、登壇は緊張はするがその場でフィードバックがもらいやすいので言葉では表せない経験が蓄積されてゆく。
- ほどよい緊張は大切である。

# 今回のイベントに参加して筆者が感じたこと

- 自分のことを話すことは知識の棚卸になる。
- 少なくとも聞いてくれているみなさんは優しい。失敗しても怒られたりはしない。(もしかすると当たり前かもですが、初めてだとマサカリが飛んでくるのでは？と緊張した。)
- 話し方や内容など含めて登壇した全員に勉強になる部分があった。
- エンジニアは何かしらのこだわりを持っている人が多い、趣味にしても、エンジニアリング系の話にしてもみなさんすごい熱意を感じた。
- まずは経験してみることが大切である。自分に合う合わないはそのあと決めれば良い！
- 神奈川の座間の日本酒美味しかったです。

# 付録

- 筆者が登壇した際のスライドを記載する。

1. 自己紹介スライド

    TBD

1. 技術的な話題スライド

    TBD
[UE4]Custom Primitive Dataを使ってAuto Instancing機能を活用する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363464/92dca61b-1ee9-dec9-8ba8-eac53534e60f.png)
UE4.23からAuto Instancing機能が搭載され、上記の様に同一マテリアルの同一オブジェクトをレンダリングする際にインスタンシングされる（一つのドローコールにまとめる）様になりました。

下図の様にドローコールがLOD単位でひとまとめにされます。便利。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363464/b20a5ac1-9ba6-7918-9321-b635884e0753.png)

しかし、以下の様にマテリアルインスタンスを各オブジェクトに設定するとインスタンシングされません。（めんどくさかったので先頭の6つのオブジェクトしかやっていません。）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363464/c7997ae7-7bc7-5b98-cc71-dfcdb18cc3a6.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363464/2bfd6d1b-bf8b-ace7-fd42-939019065bcf.png)

参考: 使用した親マテリアル
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363464/3ccb48be-28c2-2f71-f538-1003649ca395.png)
この様に異なったマテリアルインスタンスにしてしまうとインスタンス化はできないのですが、それだけだとちょっとパラメータが違うだけのオブジェクト達も常に別々にドローコールされてしまいもったいないです。UE4ではそれを解決するCustom Primitive Dataという手法を用意しています。

親マテリアルの変数を選択すると設定に、"Use Custom Primitive Data"という項目があります。こちらにチェックをいれます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363464/6d6a61b4-b841-012f-122b-3da36e8cb737.png)

するとマテリアルの変数がCustom Primitive Dataという名前に変わります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363464/1ea7ab30-dd37-99d4-417f-8fec612ebc20.png)

このCustom Primitive Dataはマテリアル単位で設定するのではなく、各Mesh Component単位で値を設定します。それぞれのメッシュのRenderingカテゴリの中に"Custom Primitive Data"という項目があると思うので、そこに今回設定したい色をそれぞれ設定します。 (この項目は4.24から。4.23ではC++/BPのみから設定可能？)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363464/855ec3ce-f672-081f-95c3-0fd03c719728.png)

すると、別々のマテリアルインスタンスにすることなく、下図のように一つのマテリアルを用いながらも、Custom Primitive Dataをマテリアル内で参照することで、マテリアルインスタンスと同様の効果を得ることができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363464/4424439b-a9ef-f408-d738-7ff427201b7e.png)

同一マテリアルなので、下図のようにAuto Instancingが機能しており、それぞれのメッシュのパラメータが違っていてもドローコールがまとめられています！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363464/29f25b22-b064-bcb1-29c6-e8afd7ee9848.png)

ご参考になれば幸いです。
PythonでINSERT文を発行するとno such columnが表示される


PythonでINSERT文を発行するとno such columnというエラーが表示されて、「？？」となった時のお話です。


printを使ってコンソール画面にSQLを表示してみたら…

**INSERT INTO license (license_nm) values (基本情報技術者試験)**

どうやらシングルクォーテーションがないため、エラーが起きていたみたいです…。

■問題となったコード
---------------------------------
   # データの挿入
   sql = "INSERT INTO license (license_nm) values "
   sql += "("
   sql += in_shikaku
   sql += ")"

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




■修正版のコード
---------------------------------
   # データの挿入
   sql = "INSERT INTO license (license_nm) values "
   sql += "("
   sql += "'" + in_shikaku + "'"
   sql += ")"

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



初歩的なミスでした…。

いちいち、"'"で囲むのも嫌なのでDB発行処理をどうにかしなければ・・・。
「何がわからないのかわからない」は何がわからないのか

## 背景と目的
駆け出しエンジニア界隈で「何がわからないのかわからない」ってよく聞きますね。
自分も新人の頃「何がわからないのかわからない」と苦しんだので、整理できるようになった今、実際のところ何がわかっていなかったのか振り返ってみました。

「何がわからないのかわからない」状態から脱する助けになれれば幸いです。

## 対象読者
・何がわからないのかわからなくて苦しんでいる新人エンジニア
・後輩に「何がわからないのかわかりません」と言われて、「そんなこと言われてもなぁ」と困ってしまった先輩エンジニア

##「何がわからないのかわからない」とは
### 手当たり次第に理解しようとしてませんか？
新人の頃はわからないことの連続です。
現場で飛び交う言葉がわからない、環境構築したものの何をやっているのかわからない、仕様書を読んでも意味がわからない、仕事の進め方がわからない、調べても説明が理解できない・・・
波のように押し寄せてくるので、パニック状態になるかもしれません。

でも、落ち着いてください。
全部があなたの仕事に必要な内容ですか？
何を目的としてその「わからないこと」を調べているのか、きちんと説明できますか？

目先の「わからないこと」に惑わされず、仕事を完遂するために必要なことから潰していきましょう。

### つまり、何がわかっていないのか
思うに「何がわからないのかわからない」状態の原因は
・「わかっておくべきこと」がわかっていない
・「現状どこまで理解できているか」がわかっていない
だと思います。
なので、最低限の「わかるべきこと」チェックリストを作ってみました。

###「わかるべきこと」チェックリスト
以下のこと、どのくらい説明できますか？
経験上、どこかで躓くと芋づる式にわからなくなります。
曖昧なまま作業を進めると、8割方どこかのタイミングで揉めます。

1 . アサインされたプロジェクトの全体像
2 . 全体像の中で、自分の担当（どの機能？どのフェーズ？）
3 . 作業対象の初期状態
4 . 作業対象の目標の状態
5 . 目標に至るために必要な作業
6 . 各作業の所要時間
7 . 参照するべき資料
8 . 資料へのアクセス方法
9 . 「作業が完了した」ことを、誰がどのように判断するのか
10. ここまでに整理した作業すべてを、いつまでに実行すればいいのか

これらを、**自分の言葉**で**できる限り具体的に**書き出してみましょう。
ノートに図など描くと頭の中が整理しやすいのでおすすめです。

何がわからないのか、わかりましたか？

###「わからないこと」がわかったら
何がわかっていないのか理解できた！あとは質問するだけ！と思ったあなた、ちょっと待ってください。
「わからないこと」をすぐ質問しに行くのは危険です。

何故ならば、あなたが**「わかっている」と思っている**内容、全く見当外れな可能性があります（私も新人の頃そうだったので）
そして、その見当外れな前提をもとに質問をすると、質問された先輩は「何言ってるのかわからんぞ」と困ってしまいます（先輩になってからわかりました）。

まず「わかっている」内容を**ノートなりテキストなりにまとめて**ください。
そして先輩に時間をもらって、まとめた内容を見せながら**お互いの理解が一致しているか確認**しましょう。
驚くほどに認識がずれていることがあります。

「わからないこと」を聞くのは、「ここまでわかっている」と合意がとれてからにしましょう。お互いのために。

## まとめ
「何がわからないのかわからない」状態になったら、一旦落ち着いて、「わかるべきこと」を整理しましょう。
苦しむ人が少しでも減ることを祈っています。

以上です。ありがとうございました。
【Rails】セキュアなパスワード【Rails Tutorial 6章まとめ】

生のパスワードをデータベースに保存すると、セキュリティ上問題になる。
そこで、bcryptジェムとhas_secure_passwordメソッドを用いて、パスワードをハッシュ化して保存する。
ハッシュ化とは、Rubyのハッシュのことではなく、文字列をランダムな文字列に変換することである。
暗号化のようであるが、復元できないという点が違うらしい。

##bcryptジェム
Gemfileにbcryptを追加する。

```Gemfile.rb
gem 'bcrypt', '3.1.12'
```
bundle installしておく。

##has_secure_passwordメソッドとpassword_digestカラム
Userモデルにhas_secure_passwordメソッドを追加する。

```app/models/user.rb
class User < ApplicationRecord
  .
  .
  .
  has_secure_password
end
```
このメソッドを使用するためには、Userモデルにpassword_digestカラムが必要になる。
カラム追加用のマイグレーションファイルを作成する。

```
$ rails generate migration add_password_digest_to_users password_digest:string
```

```db/migrate/[timestamp]_add_password_digest_to_users.rb
class AddPasswordDigestToUsers < ActiveRecord::Migration[5.0]
  def change
    add_column :users, :password_digest, :string
  end
end
```
マイグレーションファイルの末尾をto_usersとし、カラム名と型を入れておくと、自動でadd_columnを追加してくれる。
$ rails db:migrateしておく。

###テストの修正
この時点で、テストが失敗する。
has_secure_passwordには、仮想的な属性としてpasswordとpassword_confirmationが追加されており、これらにはバリデーションが設定されている。
Userモデル用のテストでは、setupでこれらの属性の値を指定していないため、テストが失敗する。

そこで、これを修正しておく。

```test/models/user_test.rb
  def setup
    @user = User.new(name: "Example User", email: "user@example.com",
                     password: "foobar", password_confirmation: "foobar")
  end
```
テストをして、成功することを確認する。

##パスワードの最小文字数
パスワードは必ず存在していなければならない。
また、パスワードは短すぎてもよくない。
そこで、存在性の検証と、最小文字数を制限するバリデーションを追加する。

まずはこれらについてテストを書く。

```test/models/user_test.rb
 test "password should be present (nonblank)" do
    @user.password = @user.password_confirmation = " " * 6
    assert_not @user.valid?
  end

  test "password should have a minimum length" do
    @user.password = @user.password_confirmation = "a" * 5
    assert_not @user.valid?
  end
```
最小文字数は６文字とし、空白は無効である。
ここでは、多重代入を使って、@user.passwordと@user.password_confirmationの二つに、同時に文字列を代入している。

Userモデルのpasswordカラムに、存在性と文字数制限のバリデーションを追加する。

```app/models/user.rb
class User < ApplicationRecord
  .
  .
  .
  has_secure_password
  validates :password, presence: true, length: { minimum: 6 }
end
```
テストをして、成功することを確認する。
なお、password_confirmationに対するバリデーションは不要のようである。

##authenticateメソッド
has_secure_passwordメソッドをUserモデルに適応したことで、Userオブジェクト（インスタンス）に対してauthenticateメソッドを使用できるようになる。
password属性（カラム）に代入された生のパスワードは、bcryptによってハッシュ化され、password_digestに保存される。
authenticateメソッドは、生のパスワードを引数に取り、それをハッシュ化して、password_digestに保存されているハッシュ値と比較する。
比較した結果が正しければ、このメソッドは該当するUserオブジェクトを返す。

```
>> user.authenticate("foobar")
=> #<User id: 1, name: "Michael Hartl", email: "mhartl@example.com",
created_at: "2016-05-23 20:36:46", updated_at: "2016-05-23 20:36:46",
password_digest: "$2a$10$xxucoRlMp06RLJSfWpZ8hO8Dt9AZXlGRi3usP3njQg3...">
```

ログイン機能の実装には、このUserオブジェクトの論理値がtrueであることを利用するので、これに!!(bang bang)を使用して論理値に変換する。

```
>> !!user.authenticate("foobar")
=> true
```
LAN接続時にブラウザが勝手に起動するのを抑制する

### 方法

- レジストリエディタで次のキー値を変更する。
  - キー：HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NlaSvc\Parameters\Internet\EnableActiveProbing
  - 変更値： 1 → 0 

- 戻す場合は再度 0 → 1 に変更する。

- 以下『参考にしたURL』の 1. に詳しい説明があります。

### 参考にしたURL

1. コンピューターが企業ネットワークまたはパブリック ネットワークに接続すると、Internet Explorer または Edge ウィンドウが開く
  https://support.microsoft.com/ja-jp/help/4494446/an-internet-explorer-or-edge-window-opens-when-your-computer-connects

1. LAN接続時に勝手にMSNに接続される
  https://social.technet.microsoft.com/Forums/ja-JP/83014987-01a1-4839-b28b-b41a2d01f6f9/lan25509321542617812395212132516312395msn123952550932154123731242?forum=win10itprogeneralJP
Xcode外で追加したXcodeプロジェクト内のファイルをXcodeに認識させる


Xcode外で追加したファイルはXcodeに認識されないことがよくあります。

例えば、

 - Firebaseに必要なGoogleService-Info.plistをFinderで追加した
 - 画像ファイルをFinderで追加した
 - xcconfigを外部エディタで作成した
 
 など・・・。

そのような場合は、Xcode でドラッグ＆ドロップして追加することで問題なく認識されます。
このとき、``Copy items if needed``にはチェックをいてておきましょう。
（その場所に同じファイルがなければコピーして作ってくれます。もしない場合にチェックしていなければ、選択したものを直接参照するようになります）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24241/67ae1fa8-b27e-687d-f199-0445f55acc60.png)

たまーにGoogleService-Info.plistをXcodeが認識してなくてFirebaseがエラー※1を吐いちゃってるけど、
なぜエラーがおきてるかわからないという人がよくいたので記事にしてみました。

※1: Could not locate configuration file: ‘GoogleService-Info.plist’.
[UE4] 動画ファイル(mp4など)をpakファイルに含めて外部から見えないようにしよう！

# はじめに
UE4にはMedia Frameworkという機能があり、この機能のおかげでmp4などの動画ファイルを簡単に再生することができます。
https://docs.unrealengine.com/ja/Engine/MediaFramework/HowTo/index.html
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363889/302d7a77-06a8-bdac-ee11-4b97cb304741.png)
しかし、以下のページに書かれている通り、動画ファイルを「Content/Movies」に入れてパッケージングしないと実行ファイルでは正しく動画が再生されません。
https://docs.unrealengine.com/ja/Engine/MediaFramework/HowTo/FileMediaSource/index.html
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363889/e03969e5-65fe-1ab9-b4b8-4a26e4ac1c2a.png)
ただし、上記の手順を踏んだ場合、動画ファイルがpakファイルに含まれずそのままパッケージに格納されるため、動画ファイルがユーザから丸見えという問題があります…
# 解決方法①
**追記：Mac, iOS, tvOSの場合はこの方法ではエラーが出るので後述の「Content/Movies」以下に動画ファイルを置く方法を使用して下さい**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363889/985b806c-7428-4bf5-abe5-7cb3b7250933.png)
実はこの問題、プロジェクト設定/Packagingにある ```Additional Non-Asset Directories to Package``` 機能を使うことで回避可能です！
```Additional Non-Asset Directories to Package``` は```.uasset/.umap```形式以外のファイルもpakファイルに含めるための機能です。そのため、例えばPakMoviesというフォルダに動画ファイルに格納した後に上図のように設定することで、動画ファイルをpak内に隠蔽しつつ正常に動画再生することが可能になります。

ちなみに、iniファイルに直接書きたい場合はDefaultGame.iniに以下のように追記します。

```
[/Script/UnrealEd.ProjectPackagingSettings]
+DirectoriesToAlwaysStageAsUFS=(Path="PakMovies")
```

# 解決方法②
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363889/a42c5c2b-1095-0fab-3184-f5478b09cac6.png)
先程説明したとおり、「Content/Movies」以下にある動画ファイル（正確には.uasset /.umapファイル以外）は強制的に外部から丸見え状態でパッケージに含まれます。この挙動を制御するための項目がUE4.22から追加されました。

```Exclude movie files when staging```を有効にした場合、「Content/Movies」以下にある```Specific movies to Package```で指定された動画ファイルのみをpakファイルに含めるようになります。そのため、今回のケースでは上図のように設定することになります（```Specific movies to Package```の設定項目には拡張子は含めてはいけません）。

```Additional Non-Asset Directories to Package```はフォルダ単位の大雑把な管理でしたが、この追加機能を使うことで動画ファイル単位での細かい管理が可能になります！

具体的にどのような処理をしているのか興味のある方は、
```Engine\Source\Programs\AutomationTool\Scripts\CopyBuildToStagingDirectory.Automation.cs``` の ```CreateStagingManifest``` 関数をご確認くださいまし。

# まとめ
プロジェクト設定/Packagingにある項目を活用して、見られたくない動画ファイルはpakファイルにどんどんしまっちゃおうね～
おしまい

# おまけ
```Additional Non-Asset Directories to Package``` に Content/Moviesフォルダを設定してもpakファイルに隠蔽されないのでご注意を
JavaScriptの基本文法

#はじめに

この記事は、2019/11/1からプログラミング学習を始めた学生がプロのプログラマーになるまでのアウトプットする為の書き込みの場である。

#JavaScriptを呼び出そう
HTMLのコード中にJavaScriptのコードを記入しJavaScriptを呼び出す

     <script src="script.js"></script>

##基本文法
- 出力　console.log
- 変数　変数の前にvarを入れる
- 変数　変数を宣言する場合、前にletとconstを入れる必要があります。1
  - letは、後で書き換えることのできる変数宣言
  - constは、後で書き換えることのできない変数宣言
- 条件分岐(ES6バージョン)
 - 条件式は()でくくる必要がある
 - Ifの終わりに{}で囲む必要がある
 - rubyでは、elsifであるが、else ifと記入する
- 条件分岐(ES5バージョン)
 - 宣言する変数の前にvarをつける！！
- 関数
 - rubyの場合、関数の前にdefがつきますが、jsの場合、functionと記入する

##今日の感想　明日から
インプットをする機関を取りすぎてしまいアウトプットする時間が作る事ができない
今回のように今日インプットした、もの全てをアウトプットする事ができない
明日からは、今は、インプットする事に専念し、アウトプットについては簡単に端的にまとめたアウトプットをしていこうと思います

 
##終わりに

もっとこうした方が良いよなどご指摘頂けると幸いです
Windows10でスタートアップタスクを登録する

仕事で個人にPCが貸与されるが、勤怠管理のアプリやメーラアプリなど、PowerON時に自動起動してほしいアプリがある。
Windows7までは、スタートメニューからスタートアップディレクトリに飛べたのだが、Windows10になって以来複雑になって、登録の度に調べなおしているので備忘録的にまとめる。

## 結論

とりあえずスタートアップディレクトリは以下のパス(xxxはユーザ名)
**C:\Users\xxx\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup**

## 開き方

- `Windows + r`で"ファイル名を指定して実行"を開いて、`shell:startup`を入力
- エクスプローラーでスタートアップのディレクトリが開くので、PowerOnで起動したいアプリのショートカットを登録(コピー)[^1]

[^1]: 厳密にはPowerOnではなくログイン毎

## 参考

[Windows10 起動時にアプリを自動起動 - スタートアップに登録](https://pc-karuma.net/windows-10-app-startup/)
1-100までのカードをn-1枚置きに裏返す(Ruby)

1-100までの数字が書かれたカードが裏返しで横に並んでいます。（1, 2, 3, 4, 5... 99, 100）
①初めは２番目のカードから1枚置きにカードを裏返して行きます。
②次に３番目のカードから2枚置きにカードを裏返して行きます。
③次に４番目のカードから３枚置きにカードを裏返して行きます。
・
・
・
このようにn番目のカードからn-１枚置きにカードを裏返していって、これ以上カードの向きが変わらなくなるまで続けます。
#####その時に裏返っているカードは何番かを調べていきます。

##考え方
カードを左から順に裏返す処理を書いていきます。カードが表か裏かはTrue（表）, またはFalse（裏）で表すことが出来ます。

### まずはカードを１００枚用意します。

```ruby:qiita.rb
n = 100
cards = Array.new(n, false)
```
配列はArray.newで作成することが出来ます。
また、その時に第2引数を指定すると、新しい配列をそのオブジェクトで埋めます。
ここでは１００枚全てfalse(裏)にして配列を作成しました。


### 次にカードを裏返して行きます。

```ruby:qiita.rb
(2..n).each do |i|
  j = i - 1
  while j < cards.length do
    cards[j] = !cards[j]
    j += i
  end
end
```
初めは２番目のカードから裏返していくので、(2..n)として２番目のカードから順番に処理をしています。
また、n-１枚置きにカードを裏返すために、jにn−１の値を格納します。
そうしたら、whileのループの中で、n-１枚置きにカードを裏返す処理を行います。


###最後に裏返しのカードの番号を表示します。

```ruby:qiita.rb
no = 1
cards.each do |i|
  puts no if !i
  no += 1
end
```
初めのカードから順番に、false(裏)だったらその番号(no)をputsしています。

###答え
```ruby:qiita.rb
1
4
9
16
25
36
49
64
81
100
```



###ちなみに
カードの番号とその裏表の状態を同時にハッシュで保持出来るともっと簡単に記述出来るかもしれないと思ったり。。。


```ruby:qiita.rb
n = 100
cards = Array.new(n, false)

(2..n).each do |i|
  j = i - 1
  while j < cards.length do
    cards[j] = !cards[j]
    j += i
  end
end

no = 1
cards.each do |i|
  puts no if !i
  no += 1
end
```
Ubuntu18.04にPython3系の環境を構築する。


WebArena Indigoのユーザー名は

```sh
Ubuntu
```

である。パスワードはなし。
https://web.arena.ne.jp/indigo/spec/security.html

そのままではPython3系が入ってないので以下を入れる。

```sh
sudo apt install python3.7
```

pip3が入ってないので以下を入れる。

```sh
sudo apt install python3-pip
```


あとはsudo pip3 install ○○で以下をインストールしていく

```sh
sudo pip3 install requests
sudo pip3 install pyyaml
sudo pip3 install pandas
sudo pip3 install websocket-client
sudo pip3 install sortedcontainers
sudo pip3 install matplotlib
```
KeycloakのFAPI(Financial-grade API)対応について(2019/12 update)


日立製作所　中村雄一

OpenID Foundationで策定が進むプロファイルである「Financial-grade API(FAPI)」へのKeycloakの対応のための開発を筆者のチームで進めています。昨年(2018年末時点)の状況については、[以前の記事](https://qiita.com/yuichi-nakamura/items/a33d29a71535a8889aa7)をご覧ください。
　本記事では、KeycloakのFAPI対応状況のこの1年のupdateを記します。

# KeycloakのFAPI対応状況(機能面)
　昨年に引き続き、日立の@tnorimatさんが中心となって対応のための開発が行われています。主に機能面のアップデートを表に記します。

|非対応項目のJIRA|概要|Pull Request|対応バージョン|
|--:|--:|--:|--:|
|[KEYCLOAK-9756](https://issues.jboss.org/browse/KEYCLOAK-9756)|	リクエストオブジェクトのPS256/386/512署名アルゴリズム対応|[5974](https://github.com/keycloak/keycloak/pull/5974)|6.0.0|
|[KEYCLOAK-10747](https://issues.jboss.org/browse/KEYCLOAK-10747)|PKCE設定項目追加|[6135](https://github.com/keycloak/keycloak/pull/6135)|6.0.0|
|[KEYCLOAK-6748](https://issues.jboss.org/browse/KEYCLOAK-6748)|IDトークン暗号化||7.0.0|

多くの人に関係すると思われるのが、PKCE(RFC7636)の設定項目の追加です。Keycloak6.0.0以前では、認可コードを取得する際、PKCE関連のパラメタが無くとも認可コードが払い出されていました。つまり、PKCE関連のパラメタをクライアント側が付け忘れることを防止することができませんでした。
Keycloak 7.0.0以降では、管理コンソールに下図のような設定項目が追加されました。

![PKCE_Enabling.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267380/3a06477b-6824-52b9-f386-f47daa2a50cb.png)

例えば「S256」を選択すると、認可エンドポイントへのクライアントからのリクエストにcode_challenge_method=S256およびcode_challengeが含まれていないと、リクエストがエラーで帰ってきます。これにより、クライアント側で確実にPKCEを使わせることができるようになりました。

#Conformance Testパスに向けた状況

 この1年の間に、OpenID FoundationよりFAPIについても[Conformance Test](https://openid.net/certification/fapi_op_testing/)がリリースされました。Keycloakとしても、Conformance testにパスすることが望まれます。OSSセキュリティ技術の会を通じて関係する[日本企業の協力を得て](https://github.com/jsoss-sig/keycloak-fapi)、@tnorimatが中心となりConformance testパスのための課題をJIRAに登録しました。
結果を下記表にまとめました。エラー処理などの細かな課題が中心となっています。13個あり、うち3件は既にKeycloak8.0.0で対応済です。

|非対応項目のJIRA|概要|Pull Request|対応バージョン|
|--:|--:|--:|--:|
|[KEYCLOAK-11251](https://issues.jboss.org/browse/KEYCLOAK-11251)|JWTでのクライアント認証において署名アルゴリズムES256またはPS256サポート|[6414](https://github.com/keycloak/keycloak/pull/6414)|8.0.0|
|[KEYCLOAK-11252](https://issues.jboss.org/browse/KEYCLOAK-11252),[KEYCLOAK-11253](https://issues.jboss.org/browse/KEYCLOAK-11253)|well-knownにてサーバメタデータ返却の漏れ|[6351](https://github.com/keycloak/keycloak/pull/6351),[6354](https://github.com/keycloak/keycloak/pull/6354)|8.0.0|
|[KEYCLOAK-11254](https://issues.jboss.org/browse/KEYCLOAK-11254)|Hybridフローの一部をクライアントに強制|未|未|
|[KEYCLOAK-11255](https://issues.jboss.org/browse/KEYCLOAK-11255)～[KEYCLOAK-11262](https://issues.jboss.org/browse/KEYCLOAK-11262)|リクエストオブジェクトのエラー処理|未|未|
|[KEYCLOAK-11263](https://issues.jboss.org/browse/KEYCLOAK-11263)|[MTLS](https://tools.ietf.org/html/draft-ietf-oauth-mtls-17)のエラー処理|未|未|


#今後の課題
　Keycloakも大きなレベルではFAPIのPart1とPart2の機能は備えており、あとはconformance testのパスという状態です。一方で、新しい仕様であるCIBAフローへの対応については、まだ進んでおらず、貢献が待たれます。
再帰処理を使ったファイルの削除【Java】

# はじめに
本記事では再帰処理を用いてファイルやディレクトリを削除する方法を紹介します。
初投稿なのでご意見等あればコメントお願いします！

## 実装

```java
/**
 * ファイルを再帰的に削除する
 * @param file 削除するファイルまたはディレクトリ
 */
public static void deleteFile(File file) {
		
	// ファイルが存在しなければ終了
	if (!file.exists()) {
		return;
	}	
	// ディレクトリであれば子を削除
	if (file.isDirectory()) {
		for (File child : file.listFiles()) {
			deleteFile(child);
		}
	}		
	// 対象のファイルを削除
	file.delete();
}
```

ディレクトリであれば子のファイルオブジェクトを先に削除することで空の状態で削除することができます。

### おまけ
再帰処理が使えて喜んだのも束の間、やっぱり先駆者様がたくさんいました…笑
これだけで終わるのはもったいないので、少し応用的なものを紹介します！

```java
/**
 * ファイルまたはディレクトリに含まれるファイルの数のみをカウントする
 * @param file ファイルまたはディレクトリ
 * @return ファイルの数
 */
public static int countFile(File file) {				
	int count = 0;	
	// ファイルが存在しなければ終了
	if (!file.exists()) {
		return count;
	}
	// ディレクトリであれば子を再帰的にカウント, ファイルであれば自己をカウント
	if (file.isDirectory()) {
		for (File child : file.listFiles()) {
			count += countFile(child);
		}
	} else {
		count = 1;
	}
	// 合計を返却
	return count;
}
```

上のメソッドは引数のオブジェクト以下に存在するファイルの数のみをカウントできます！
このメソッドの実用性はともかく、再帰処理はプログラミングしてる感じがして好きですね笑
RailsアプリのViewをReactに変えた後、デプロイする手順

# この記事は？
Railsサーバーと通信するReactアプリをデプロイする時の、自分が踏んだ手順を紹介します。
以前作成したRailsアプリのViewをReactで作り直し、最低限の機能実装まではできたのでデプロイしようとしたら手間取りました。

# 手順
以下、自分が踏んだ手順を紹介します。
## git pull
Jenkinsとか使ってる人はいらないでしょう。

## npm install -g npm
そのまま`npm install`しようとしたら、先にやるように警告された。
そのまま打ったら「permission denied」エラーを出したので`sudo`をつけた

## npm install
`create react app`で使用するパッケージを読み込む
終わったら`node_modules`ディレクトリが増えていることを確認します。

## npm run build
Reactをこれでビルドします。

が、ここで問題が発生

```
$ npm run build

> client@0.1.0 build /var/www/rails/foreign_books_search/client
> react-scripts build

Creating an optimized production build...
Failed to compile.

./src/App.js
Cannot find file './css/App.css' in './src'.
```

確認してみると、そもそも`./src/css/`ディレクトリが存在しない。

よく考えたら、自分はCSSではなくSCSSを使用しているので、Reactをビルドする前にまずSCSSをビルドしなければならない。

というわけで、自分が作成したgulpfile.js 

``` JavaScript
'use strict';

var gulp = require('gulp');
var sass = require('gulp-sass');

sass.compiler = require('node-sass');

gulp.task('default', function () {
  return gulp.src('./src/**/*.scss')
    .pipe(sass().on('error', sass.logError))
    .pipe(gulp.dest('./src/css'));
});

gulp.task('sass:watch', function () {
  gulp.watch('./sass/**/*.scss', ['sass']);
});
```

なので、以下のコマンド

```
$ gulp
-bash: gulp: コマンドが見つかりません
```

...?

node_modulesにPATHが通ってない！

```
$ export PATH=$PATH:node_modules/.bin
$ gulp -v
CLI version: 2.2.0
Local version: 4.0.2
$ gulp
[23:02:47] Using gulpfile /var/www/rails/my_app/client/gulpfile.js
[23:02:47] Starting 'default'...
[23:02:47] Finished 'default' after 53 ms
```

`./src/css/`があることを確認したので、改めてReactのビルドを行います。

```
$ npm run build

> client@0.1.0 build /var/www/rails/foreign_books_search/client
> react-scripts build

Creating an optimized production build...
Failed to compile.

./src/App.js
Cannot find module: '@material-ui/core'. Make sure this package is installed.

You can install this package by running: yarn add @material-ui/core.
```

今度はmaterial-uiが無いと。。。

指示に従いインストール

```
$ yarn add @material-ui/core
yarn add v1.15.2

※色々表示される

Done in 92.95s.
```

３度めの正直を祈って！

```
$ npm run build

> client@0.1.0 build /var/www/rails/foreign_books_search/client
> react-scripts build

Creating an optimized production build...
Compiled successfully.

File sizes after gzip:

  92.81 KB  build/static/js/2.f13f31dd.chunk.js
  3.75 KB   build/static/js/main.29ffb305.chunk.js
  772 B     build/static/js/runtime-main.b240f91f.js
  681 B     build/static/css/main.9ea7ac83.chunk.css
  580 B     build/static/css/2.94155858.chunk.css

The project was built assuming it is hosted at the server root.
You can control this with the homepage field in your package.json.
For example, add this to build it for GitHub Pages:

  "homepage" : "http://myname.github.io/myapp",

The build folder is ready to be deployed.
You may serve it with a static server:

  yarn global add serve
  serve -s build

Find out more about deployment here:

  https://bit.ly/CRA-deploy

```

Compiled successfully !

`build/`ディレクトリに`index.html`があることも確認しました。

## Nginxの設定
設定ファイルの`root`を`build/`ディレクトリにする

設定の読み込み

```
$ sudo systemctl reload nginx
```

その後、ドメインにアクセスし、アプリが表示されることを確認！

ついでに、今後新しい修正を反映するときは`npm run build`やunicornの再起動を忘れずに。
docker-compose upでPythonのログが出力されない

## 結論
`-u`オプションで解決した

```yaml:docker-compose.yml
command: python -u main.py
```

## 経緯
以下のようなファイルをdocker-compose.ymlの`command`に指定したらログに何も出力されなかった。[^1]

[^1]: 「動作しない」ではなく「出力されない」だと気付くのにもだいぶ時間かかった

```python
import time

print('hoge')

while True:
  print('fuga')
  time.sleep(1)
```

原因調査のために部分的に切り分けていきます。

[^2]: `import`文を削除したら出力されることがあったが、これはエラーによってその行で動作が停止しただけだった

* `docker-compose run`だと動作する
* `docker-compose run python bash`で入ったbash内で立ち上げたpythonインタプリタ内でも動作する

最終的にpythonスクリプトを何行かづつコメントアウトしたりして、ついに`while True:`以下が問題らしい事がわかりました。[^2]

## 標準出力とバッファリング
Pythonの`print()`などによる標準出力はすぐには出力されずバッファリングされ、タイミングを見て出力されます。

つまり、`while True:`によって実行がいつまで経っても終了せず、またバッファが一杯になることもないため、出力を受け取るdocker-composeに結果が渡されなかったということでした。

`python`にはバッファリングを無効化するためのオプション`-u`があり、これを指定することで解決できました。

参考: 
[Python 3 で標準出力のブロックバッファリングを止める方法 - Qiita](https://qiita.com/bmtsstl/items/8b6ef88d40a6846ea1e3)
[head コマンドの不思議な挙動と標準入出力のバッファリング - CUBE SUGAR CONTAINER](https://blog.amedama.jp/entry/2017/11/23/162226)
ABC088B - Card Game for Two

#問題
https://atcoder.jp/contests/abs/tasks/abc088_b
<img width="1118" alt="スクリーンショット 2019-11-27 23.04.25.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307024/e68f6c10-4353-4e5a-1b7c-8c279d57c143.png">

#1回目
##回答
```ruby
N = gets.to_i
A = gets.split.map &:to_i
 
for i in 0..N-2 do
  for j in 0..N-2-i do
    if A[j] < A[j+1] 
      hoji = A[j]
      A[j] = A[j+1]
      A[j+1] = hoji
    end
  end
end
 
i = 0
aliceSum = 0
bobSum = 0
while i < N
  aliceSum += A[i]
  if i+1 < N
    bobSum += A[i+1]
  end
  i += 2
end
 
puts aliceSum - bobSum
```
##結果
<img width="1088" alt="スクリーンショット 2019-11-27 23.06.57.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307024/7ab057cd-917a-542a-a541-aa69aa10bf70.png">

#2回目
##回答
```ruby
N = gets.to_i
A = gets.split.map(&:to_i).sort.reverse

result = 0

for i in 0..N-1
  if i % 2 == 0
    result += A[i]
  else
    result -= A[i]
  end
end

puts result
```
#結果
<img width="1085" alt="スクリーンショット 2019-11-27 23.17.16.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307024/3db7867e-6483-9706-3b26-ce62bd1c73ab.png">

#感想
sortあるんか〜〜〜〜〜い
ハードディスクのデータを全消去する方法

今まで使用していたディスクを、次の人に申し送るのに、ディスクのデータを全消去して渡したい時があると思います。
そんなときに使えるのが、shred コマンドとなります。
自分の身の回りにいるエンジニアでも、知っている人がいませんでした。
とても便利なコマンドなので、覚えておくといいと思います。
システムが Linux でも Windows でも Mac でもデバイス指定するので、関係なく使えると思います。

対象のシステムに、CD/DVD ドライブがあれば、そこに、LiveOS を入れます。Fedora などは最適だと思います。

LiveOS が立ち上がったら、コンソールを立ち上げ、root になります。

```
$ sudo su -
```
デバイスを確認します。

```
# ls /dev
```

/dev/sda が、/dev/sda1 /dev/sda2 となっているものを全消去するなら、以下のコマンドを実行します。

```
# shred -v /dev/sda2
（かなり時間が必要）
# shred -v /dev/sda1
（かなり時間が必要）
# shred -v /dev/sda
（boot loader を消してくれる）
```

shred コマンドは、デフォルトで 3回実行してくれます。
終了したら、CD/DVD を抜いて、マシンを再起動してみてください。

すっきり、気持ちいいですね。
エンジニアスタンプラリー～フロントエンド編＃16

## 企画主旨
[Frontend Developer Roadmap](https://roadmap.sh/frontend)をひたすら巡回する企画 
詳しくは[こちら](https://qiita.com/tonchan1216/items/8d5f072cf769dfe1bc4f)

## 今回の実施内容
モバイルアプリ

## Desktop Applications

#### Electron
[Getting Started](https://facebook.github.io/react-native/docs/getting-started)を参考に導入及び環境構築を実施。
今まで作成してきたデザインや機能をそのまま移植する。

```tsx:App.tsx
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import Form from './Form'
import List from './List'
import Bottom from './Bottom'

type P = {

}

type S = {
  page: string,
  front_skill: string[],
  back_skill: string[],
  inputText: string
}
export default class App extends React.Component<P, S> {
  constructor(props) {
    super(props)
    this.state = {
      page: 'front',
      front_skill: [],
      back_skill: [],
      inputText: ''
    }
    this._onPushButton = this._onPushButton.bind(this)
    this._onChangeText = this._onChangeText.bind(this)
    this._onChangePage = this._onChangePage.bind(this)
  }

  _onPushButton(): void {
    let { inputText, page, front_skill, back_skill } = this.state
    if (inputText !== '') {
      if (page === 'front'){
        front_skill.push(inputText)
      } else {
        back_skill.push(inputText)
      }
      inputText = ''
      this.setState({ front_skill, back_skill, inputText })
    }
  }

  _onChangeText(inputText: string): void {
    this.setState({ inputText })
  }

  _onChangePage(page: string): void {
    this.setState({ page })
  }

  render() {
    return (
      <View style={styles.container}>
        <View style={styles.form}>
          <Form inputText={this.state.inputText} _onPushButton={this._onPushButton} _onChangeText={this._onChangeText} />
        </View>
        <View style={styles.list}>
          <List skills={this.state.page === 'front' ? this.state.front_skill : this.state.back_skill} />
        </View>
        <View style={styles.bottom}>
          <Bottom _onChangePage={this._onChangePage} />
        </View>
      </View>
    )
  }
}
```


## 成果物
あまりコードの流用ができず、同じJavaScriptでも全く別物の印象。
https://github.com/tonchan1216/WDR-frontend-reactNative
[UE4] BPノードをダブルクリックするとVisual Studioなどが勝手に立ち上がるのがストレスな方へ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363889/8b8be6a0-e649-3d80-6c1e-aa89ca9cb566.png)
UE4にはBPノードをダブルクリックすると、自動的にVisualStudio(またはXcode)が立ち上がりそのBPノードが実装されているコードを開いてくれます。
そのノードの使い方や処理内容を細かく把握したいときなどに便利なのですが、BPでガリガリ実装している途中に誤ってダブルクリックしてVisualStudioが勝手に立ち上がるのがストレスになるときも正直あります…

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363889/aa5923bc-959a-4d4f-0a19-44fae30fb67c.png)
そんな時はエディタ設定の ```Navigate to Native Functions from Blueprint Call Nodes``` を無効にしましょう！ノードをダブルクリックしてもVisualStudioが勝手に立ち上がらなくなります！やったね！

よいBlueprintライフを
おしまい
Linuxコマンドはじめの一歩

Linuxコマンドを全く使ったことのない状態で、
初歩的なものの使い方をメモ程度にまとめました。

#pwd　(print working directory)
　現在、作業しているディレクトリを表示

#cd　(change directory)
　現在、作業しているディレクトリを移動
　■cd　[移動したいディレクトリ名]

#ls　(list segments)
　現在、作業しているディレクトリに存在するファイルまたはディレクトリを表示

#ls -a
　現在、作業しているディレクトリに存在するファイルまたはディレクトリを**隠しファイルを含めて**表示

#mkdir　(make directory)
　指定した名前のディレクトリを作成
　■mkdir　[作成したいディレクトリ名]

#touch
　ファイルを作成
　■touch　[ファイル名]

#cp　(copy)
　指定したファイルをコピーする
　■cp　[コピーしたいファイル][コピー先]
　■cp　[コピーしたいファイル][コピー後の名前]※名前を変更してコピー

#cp　-r
　指定したディレクトリをコピーする
　■cp　-r　[コピーしたいディレクトリ名][コピー先]

#mv　(move)
　存在しているファイルを別のディレクトリに移動
　■mv　[移動させたいファイル][移動先]
　ファイル名の変更もできる
　■mv　[名前を変更したいファイル][変更後の名前]

#rmdir
　空のフォルダを削除
　■rmdir　[フォルダ名]

#rm　(remove)
　指定したファイルを削除
　■rm　[削除したいファイル]

#cat　(catenate)
　ファイルの中身を表示
　■cat　[表示したいファイル]
　※表示したいファイルを複数指定することで、複数のファイルをつなげて表示

#echo
　1行テキストを表示
　■echo　[オプション][文字列]
勉強記録　4日目 〜コピーコンストラクタが呼ばれる場合〜 - Effective C++ 第3版 -

#　はじめに

Effective C++ 第3版のイントロダクションxxiiのページから勉強していきます。
今回は、前回からの続きの、「コピーコンストラクタが呼ばれる場合」についです。

# Effective C++ 第3版 - イントロダクションxxii -

## コピーコンストラクタが呼ばれる場合

### コピーコンストラクタが主に呼び出される場合とは？

前回の投稿では、「コピーコンストラクタは、オブジェクトを「同じ型の別のオブジェクト」で代入するときに使われる。」と書きました。
「オブジェクトを「同じ型の別のオブジェクト」で代入するとき」とは、どのようなときかというと、

オブジェクトが関数に値渡しされるときに呼び出されるとき。

があります。

下にコピーコンストラクタを用いてオブジェクトを関数に値渡ししたときのサンプルコードを示します。


下のサンプルコードで関数 testFunc はWidget 型の引数を値で受け取る関数です。

実行結果を見ると、関数が呼ばれた際にコピーコンストラクタが呼ばれていることが分かる。
このように、コピーコンストラクタは、関数でオブジェクトが値渡しされる際に呼び出されます。

前回、コメントで教えて頂いたのですが、コピーコンストラクタにexplicitを付けると、コンパイルエラーになることが分かります。
これは、関数の値渡しの際に暗黙の型変換が行われているためです。
なぜかというと、
値渡しは、関数内で新しくオブジェクトを生成する必要があるため、

```cpp
Widget w = a // (a はmainで生成した Widget 型のオブジェクト)
```
このように、暗黙の型変換が行われるためです。

### サンプルコード

```cpp:intro_default_constructor4.cpp
#include <iostream>
class Widget {
 public:
  explicit Widget(int a) { std::cout << "コンストラクタ" << std::endl; };
  Widget(const Widget& rhs) { std::cout << "コピーコンストラクタ" << std::endl; };
  Widget& operator=(const Widget& rhs) { std::cout << "コピー代入演算子" << std::endl; };
};

void testFunc(Widget w) { std::cout << __func__ << " : " << __LINE__ << std::endl; };

int main(int argc, char* argv[]) {
  std::cout << "intro_default_constructor4.cpp" << std::endl;
  Widget a(1);  // コンストラクタ
  testFunc(a); // コピーコンストラクタが呼ばれる
}
```

### 実行結果

![intro_default_constructor4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367151/545a8a78-b8b5-885e-1b73-1369ff349bb9.png)



## 参考文献

・https://www.amazon.co.jp/gp/product/4621066099/ref=dbs_a_def_rwt_hsch_vapi_taft_p1_i0
picoCTF 2019 vault-door-6 - Points: 350

#問題

https://2019game.picoctf.com/problems

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/f4ac4001-e33a-9d2f-42eb-3f3aaba27e3c.png)

#解いてみた

ソースを見てみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/b1e46923-d507-1d34-522d-2610af9d641e.png)

checkPasswordメソッドの中でtrueになるように頑張る問題です。

checkPasswordメソッドを見てみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/ebbef717-8b52-2b85-cc0a-c1996feeb863.png)

入力した文字列のそれぞれのバイトをとって、それを0x55とxorした値がmyBytesと一緒ならOKという問題。
myBytes xor 0x55をやれば答えが出ますね。

pythonでこんな感じで作ります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/86fb57db-2a7c-9fec-dcad-2fda234bc3db.png)

これを実行すると

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/6d1a0757-cb5d-bb29-1588-89013e857492.png)

答えが出ました。
Elmのコレクションパッケージを見比べてみよう

Elmを始めたばかりの人がリストの操作に対して疑問や機能不足を感じるとの意見がたびたび見受けられるので、カルチャーショックを無くし、Elmをよりよく使っていただけるように記事を残しておきます。

# コレクションライブラリのパターン

他の言語でよく見られるパターンとして、基本的に配列を扱い続けるパターンといくつかのコレクションを汎用インターフェースで扱うパターンの二種類があります。(他にもこんなパターンの言語があるよ！というのがあったら教えてください)

一つ目のパターンの言語としては、JavaScript(TypeScript)・Python・Ruby・Go(スライス)等の言語が挙げられます。配列リテラルなどを起点として使われることが多いのが特徴です。他にも配列の機能拡張をサードパーティのライブラリなどが補う使い方もよく見られます。ElmではListがリテラル ```[1, 2, 3]``` によって生成されるのでこちらのパターンに近いですが、[Coreパッケージ](https://package.elm-lang.org/packages/elm/core/latest)だけでも`Array`と`Set`の二つのコレクションが存在します。また、サードパーティの補助ライブラリも多く存在します。

二つ目のパターンの言語としては、Java・Scala・C#等の言語が挙げられます。Javaでは配列が存在するものの共変であったり、汎用性の観点などからパフォーマンスがシビアではない場合、基本的に`List`インターフェースを実装したArrayList等の利用を推奨されます。Elmでは、そもそもインターフェースの概念が存在しないため、このパターンの考えには属しません。

それでは、ElmのListパッケージの特徴とArray, Setパッケージの特徴を見比べていきましょう。

# Elmのコレクションパッケージの特徴

## Listパッケージ

Elmの[List](https://package.elm-lang.org/packages/elm/core/latest/List)は、線形リストのデータ構造とその操作を集めたパッケージです。線形リストは関数型のイミュータブルな特徴やパターンマッチとの相性がよく多くの場合は、これで事足りてしまいます。先頭の要素に対する操作や全ての要素に対して何かを計算する場合に適しています。代わりにランダムアクセスや集合的操作をするには適していません。例えば、以下のように添字を指定して要素を取り出すような操作はListパッケージには存在しません。

```
 node
> [1, 2, 3, 4][1]
2
```

## Arrayパッケージ

[Array](https://package.elm-lang.org/packages/elm/core/latest/Array)は、配列のデータ構造とその操作を集めたパッケージです。配列は添字を利用したランダムアクセスに優れたデータ構造です。他の言語と違う配列の特徴として、Listと同様に一種類の型の値しか含めることができません。またイミュータブルなデータ構造のため[set](https://package.elm-lang.org/packages/elm/core/latest/Array#set)や[push](https://package.elm-lang.org/packages/elm/core/latest/Array#push)、[append](https://package.elm-lang.org/packages/elm/core/latest/Array#append)は新しい配列を生成します。他にも[get](https://package.elm-lang.org/packages/elm/core/latest/Array#get)は、配列外参照をした場合を考慮して、Maybe型が戻り値となっています。逆に言えば、*map*, *foldl(r)*, *filter*のような汎用関数以外はArrayではサポートしていません。代わりに List <-> Array を相互変換する関数を備えているため**データ構造が得意としない操作は新しく自分で作らない限りはそもそもできない**ようになっています。Setも同様ですが、これがElmのコレクションパッケージの一番キモな特徴になっています。

## Setパッケージ

[Set](https://package.elm-lang.org/packages/elm/core/latest/Set)は、Set(集合)のデータ構造とその操作を集めたパッケージです。Setは値の被りがないことが保証された、数学の集合の特徴を備えたデータ構造です。挿入や削除、その値が入ってるかどうか([member](https://package.elm-lang.org/packages/elm/core/latest/Set#member))が、*O(log n)*で処理できることができます。他にもListやArrayにない集合的な特徴として、集合同士の和([union](https://package.elm-lang.org/packages/elm/core/latest/Set#union))や共通部分を取り出す積([intersect](https://package.elm-lang.org/packages/elm/core/latest/Set#intersect))、差([diff](https://package.elm-lang.org/packages/elm/core/latest/Set#diff))を求めることができます。あとはArrayと同様に汎用関数とListとの相互変換の関数を持ちます。

## extraパッケージ

Coreパッケージは本当によく使われる操作だけをシンプルに保つようにしているため、難しいコレクション操作をしたい場合には不足だなと感じてしまうシーンがあります。そういった場合には、[Collection]-extraのような拡張パッケージがElmコミュニティから提供されています。例えば、[list-extra](https://package.elm-lang.org/packages/elm-community/list-extra/latest/)などが存在します。Elmの特徴としてインターフェースやマクロなどが無い分、抽象度が高いライブラリが作れませんが、代わりに文法がシンプルで具象度が高いため関数を手軽にコピーすることでライブラリの依存を減らしたり、関数型の勉強がとてもしやすかったりして、個人的にかなり気に入っています。

# まとめ

Elmでは、多くの場合Listが万能に仕事をこなしますが、主に計算量を考慮して効率的な操作では無い場合には、無理に汎用的なコレクションとはせず役割分担を別なコレクションに任せることで、誰でも一定のパフォーマンスが発揮出るようになっています。また、質が高く学習しやすいCoreパッケージ以外のライブラリも豊富なため、他の言語を利用する場合でも役に立つことが多いです。それでは良いElmライフを！
Google Chromeのインストールの仕方！

# Google Chromeとは？
そもそも知らない方もいらっしゃるんではないでしょうか？  
**Google Chrome**とは、アメリカのGoogleというIT企業が開発しているウェブブラウザです！

とっても便利なのでみなさんにもぜひ使ってほしいです

https://www.google.com/intl/ja_jp/chrome/

↑こちらからインストールできます！！

Google Chromeが使いやすかったと思ったらぜひこの記事にコメントしてくださいね😜
ChromeならiPadでコンソール出力を確認できる

Chrome for iOSがv.74からjavascriptのコンソールのログ出力に対応していました。

# 使い方

通常のChromeのように開発者ツールを開くのではなく、アドレスバーに chrome://inspect と入力してアクセスすると以下のページが表示されます。
<img width="1194" alt="37CD8AB7-1A3B-4188-BBCB-CE4B376BC921.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479523/02f95c6d-b800-ceed-181c-aab59a44fe1b.jpeg">
"ログ記録を開始"ボタンを押して、他のタブでページを開くとこのページにログが記載されていきます。
![06D60A03-632A-4D6B-B1EA-50561814002B.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479523/7f73a150-eda7-c827-0925-fe03fdcc8bca.jpeg)
便利！

開発者ツールが使えるようになったわけではありませんが、ログ出力が見れるようになっただけでも大助かりです。

参考
- https://blog.chromium.org/2019/03/debugging-websites-in-chrome-for-ios.html
- https://www.softantenna.com/wp/software/chrome-for-ios-inspect/
Java学習５日目

<h1>スッキリわかるjava入門　第２版 p250まで</h1>

<p>５章のまとめの練習問題で正しいメソッドの作成方法を学んだ。戻り値(return)がある場合はvoidではなく戻り値の型にする事 returnの前に返す値をメソッド内で定義してから戻り値に返すようにする</p>

<h2>JDKを用いた開発の全体像</h2>①テキストエディタでソースコードを作成<br>②javacコマンドでコンパイルしクラスファイル(機械語に変換)
③javaコマンドで実行され、黒い画面（コマンドプロンプト）に実行結果が出力される</p>
<br>
<p>Javaプログラムの完成品は、複数クラスファイルの集合体なので、一つのクラスファイルで作成されている訳ではない。なので誰かに配布する場合は、全てのクラスファイルを渡す必要がある</p>

<p>別のクラスからメソッドを呼び出す場合は、クラス名.メソッド名（）で呼ぶ<br>
パッケージには親子関係や階層関係はない、package文がないクラスにはデフォルトパッケージが指定されてimport文でインポートすることはできない。別のパッケージからメソッドを呼び出す場合は「所属パッケージ名.クラス名.メソッド名」と書く = この事をFQCN（完全限定クラス名）という<br>FQCNの入力を省略したい場合はimport文を追加する。基本的にJavaでは一切の宣言をすることなくJVMが扱える全てのクラスを常時使うことが出来る</p>

<p>API（便利な機能）をimportして使うことによって、時間削減して大きなプログラムを作ることが可能。APIリファレンスをサイトで参照できる</p>
Axiosの前処理でAPIレスポンスのスネークケースをキャメルケースに変換する

## はじめに
サーバサイドからのAPIレスポンスが`some_id`のようにスネークケースで定義されていると、JS側で毎回キャメルケースに変換することになりますよね。

```ruby
{
  some_id: 1,
  some_name: "name",
}
```

今回はそんな変換処理をAxiosの共通処理でまとめてみました。


## レスポンスをキャメルケースに変換する

```javascript
import { camelCase, snakeCase } from 'change-case';

const isObject = (target: any): boolean => Object.prototype.toString.call(target).slice(8, -1)
  .toLowerCase() === 'object';

const convertSnakeToCamel = (target: any): void => {
  if (Array.isArray(target)) {
    target.forEach((t) => convertSnakeToCamel(t));
  }
  if (isObject(target)) {
    Object.keys(target).forEach((key) => {
      if (isObject(target[key]) || Array.isArray(target[key])) {
        convertSnakeToCamel(target[key]);
      }
      // スネークケースをキャメルケースに変換する
      if (key.includes('_')) {
        target[camelCase(key)] = target[key];
        delete target[key];
      }
    });
  }
};
```
キャメル変換する部分は`change-case` というライブラリを入れましたが、そこまで複雑ではないので自作でもよさそう

参考：[javascriptでキャメルケースとスネークケースの相互変換
](https://qiita.com/thelarch/items/cc4707e1c7ef0d73ba73)

## Axiosに組み込む

```javascript

import axios, { AxiosInstance } from 'axios';

const Axios: AxiosInstance = axios.create();

Axios.interceptors.request.use((request) => {
  // リクエストの共通処理
  return request;
});

Axios.interceptors.response.use((response) => {
  if (response.data) {
    convertSnakeToCamel(response.data);
  }

  return response;
});

export default Axios;
```

interceptorsを使うことでできました。interceptorsを使いこなせば、他にも、リクエストに共通のヘッダを毎回差し込んだり、レスポンスでエラー処理をしたりと、何かと便利にできそうです。
Gitの基礎１

#Gitって何？#
ファイルの変更履歴を保存することができるもの。
Gitでできること
・過去の状態に戻すことができる
・複数人で共同開発できる

#Gitの基本構成#

インデックス
変更履歴を保存するための対象となるファイルを登録するための場所
↓commit
ローカルレポジトリ
変更履歴を保存する
↓push
リモートリポジトリ
他の人とソースファイルを共有できる

#Gitの基本用語#
クローン
自分のパソコンにリモートリポジトリのコードをコピーする
プルリク
自分のパソコン内で開発したソースコードをプッシュした後に他の人に通知してレビューしてもらう
マージ
他のブランチを合体させる
ブランチ
履歴の流れを分岐させて保存しているもの






ゲームでいう所のセーブポイントって説明が分かりやすかったです。
共同開発に必須のスキルなので、やり慣れておきたいと思います。
UE4によるunlit芸のすすめ

### 前書き
- unlit芸という言葉はこの記事を書いた時点では存在しないようです・・・本職はもっとやばいんだろうなあ
- UE4はデフォルトでフォトリアリスティック用の設定が有効になっているので解除します。
 - 本題とずれるため備考に記載します。

# 目次
- 実装概要
- アンビエントと偽ディフューズの比率を決定
- 偽ディフューズの実装 
- normalマップの実装
- matcapマップの追加
- cubeマップの追加

# 実装概要
まず今回実装するシェーダーの大まかな式を示します。

color = lerp((アンビエント*x + 偽ディフューズ*(1-x) + matcap),cube,y)

# アンビエントと偽ディフューズの比率を決定
合計を1にしたらベース色とぶれなくなります。変数で影のかけ具合を変更出来ます。

# 偽ディフューズの実装 
偽ディフューズ = pow(dot(法線,カメラ方向),ベース色のHSVのV*8+2)*ベース色
常にカメラから見て角度が90°のところが暗くなるタイプのなんちゃってシェーディングです

色が0.1,0,0の場合
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198123/913649c6-9474-6b18-203e-c83f6e7a176d.png)

色が1,1,1の場合
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198123/9a978973-994d-be80-223b-75b5d8c771a7.png)

# normalマップの実装

normalマップをいい感じにしてくれる関数があるのでそのまま利用します。(normalmapMltは凹凸の具合の調整用)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198123/8bc9f87c-3ead-8d5c-4ddd-608f769e18a7.png)

# matcapマップの追加

普通にmatcapです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198123/10cc462d-b539-93f5-f708-332a86d62fdb.png)
このソースは以下のアセットに同梱されてます（爆）
https://www.unrealengine.com/marketplace/ja/slug/knobby-s-matcaps?lang=ja

# cubeマップの追加

こんな感じですが補正で20%程縮めています
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198123/1b6f79f7-ac1e-18ab-57a3-fc89fd1f94e1.png)

## 実装サンプル

https://twitter.com/vak_DJregion/status/1195453585904943104
steamでプレイできるのでよろしくね（ダイマ）

### 備考

- 露光を無効にする
おそらくこれで補正がかからなくなるはず(シーン全体なので残した方が良さそうだが)
エディタ限定だったらごめん
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198123/73c8e94e-4661-ddf7-869b-1b0efb593538.png)