OmniAICreator/Qiita-1.07M huggingface dataset:
G検定 学習のメモ

##### G検定の公式テキストを読んでいて気になったところをまとめておきます。


## 既存のNNにおける問題
- ネットワークを深くする(隠れ層を増やす)と、誤差が最後まで正しく反映されない。（誤差逆伝播法がうまくいかない）
- なぜ、隠れ層を増やすと誤差の伝搬がうまくいかないのか？
    - 理由の１つ、**シグモイド関数の特性**がある
    
## シグモイドの特性

誤差は、ネットワークを逆向きに順々に伝搬する。その過程で、数式上では、もともとの誤差にいくつかの項が掛け合わせる。その項の一つに活性化関数の微分があ理、そこに問題があった。

### NNの活性化関数としてシグモイド関数が使われると何が起こるか？
 - 問題は、`シグモイド関数の微分の最大値が0.25にしかならない`
 - 隠れ層を遡るごとに、伝搬していく誤差はどんどん小さくなる
 - これを*勾配消失問題*(gradient vanishing problem)と呼ぶ
 

####  +α
- 隠れ層では、任意の実数を（非線形に）変換することができる関数であれば、特にどんな関数であろうと問題はない。
- ReLUでは、xが０以下の場合は微分値も０になるから、学習がうまくいかない場合もある。


## 勾配降下法

勾配降下法は、**「見せかけの最適解」であるかどうかを見抜くことができない**。

- 局所最適解 -> 見せかけの解
- 大域最適解 -> 本当の最適解

point: 特に何も工夫しないと、勾配降下法は局所最適解に陥ってしまう可能性が高い。

#### じゃどうする？局所最適解を防ぐ方法は？

<font color="Red">Answer</font> : **学習率の値を大きく設定！！**

- ただし、学習率が大きいままだと、最適解を飛び越えて探索を続ける可能性ある。
- 適切なタイミングで学習率の値を小さくする

<font color="Red">鞍点</font>とは、 ある次元から見れば極小であるけど、別の次元から見ると極大
- 鞍点は一般的に勾配の小さな平坦な地点に囲まれていることが多いので、一度鞍点付近に陥ると、そこから抜け出すのが困難(こうした停留状態を<font color="Red">プラトー</font>という)


#### 鞍点を回避するには？

<font color="Red">Answer</font> : **どの方向に沿って勾配を進んでいるときに学習率を調整するかを考える**
→　モーメンタムの利用


## データの正規化・重みの初期化

<font color="Red">正規化</font> : データ全体を調整する処理

機械学習の手法は、「入力のそれぞれの特徴量がどう動いたら、出力がどう動くか」を見ている
→　各特徴量の分散を揃えて置くことで、**それぞれの特徴量の動きに対する感度を平等に見ることができる**

#### データの標準化の効果がDNNでは薄くなる理由は？

<font color="Red">Answer</font> : 何かしらの活性化関数がかかっていると、せっかく正規化したデータなのに、層を伝搬するにしたがって分布が徐々に崩れる。データの偏りが発生すると、勾配消失が起きやすい。

解決策は？？
→　<font color="Red">重みの初期化を工夫する</font>

勾配降下法の探索は初期値に依存するので、重みの初期値の設定は重要。
シグモイド関数には、Xavierの初期値
ReLU関数には、Heの初期値
## 参考文献

- [デープラーニングG検定公式テキスト](https://www.amazon.co.jp/%E6%B7%B1%E5%B1%A4%E5%AD%A6%E7%BF%92%E6%95%99%E7%A7%91%E6%9B%B8-%E3%83%87%E3%82%A3%E3%83%BC%E3%83%97%E3%83%A9%E3%83%BC%E3%83%8B%E3%83%B3%E3%82%B0-G%E6%A4%9C%E5%AE%9A-%E3%82%B8%E3%82%A7%E3%83%8D%E3%83%A9%E3%83%AA%E3%82%B9%E3%83%88-%E5%85%AC%E5%BC%8F%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88/dp/4798157554/ref=sr_1_1?adgrpid=70452547884&gclid=Cj0KCQiA-4nuBRCnARIsAHwyuPptp4jeCxwx1_mLdNz5f6C3rPrAC2tbcrwgOwJqAxMHIr8I1VMl7FAaAk9cEALw_wcB&hvadid=341446693622&hvdev=c&hvlocphy=1009149&hvnetw=g&hvpos=1t1&hvqmt=e&hvrand=9387859080533775886&hvtargid=kwd-675311731598&hydadcr=4103_9442129&jp-ad-ap=0&keywords=%E3%83%87%E3%82%A3%E3%83%BC%E3%83%97%E3%83%A9%E3%83%BC%E3%83%8B%E3%83%B3%E3%82%B0+g%E6%A4%9C%E5%AE%9A+%E5%85%AC%E5%BC%8F%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88&qid=1573038401&sr=8-1)


## 終わりに
今回は、メモ程度に書きました。
随時、更新していきたいと思います。
ArrayFormulaとGASで作った独自関数を組み合わせるときの注意

image関数で動的に画像を表示させる。
https://qiita.com/tame39/items/b447fa4758c3a9625acb

に関して。

GASの実行タイミングを以下のようにしておくとリアルタイムで更新がかかる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264901/04492d3e-a60c-4295-940f-b141f8b1f07e.png)
cssで四隅にだけ囲み枠をつける方法

「四つ角」というワードで検索するとなかなか情報が出てこない。
毎度忘れて検索しがちなので備忘録のためにまとめておく。
[DEMO（codepen.io）](https://codepen.io/riijon/pen/xxxWQWZ)

---
borderを擬似要素で隠すイメージ
![スクリーンショット 2019-11-06 19.52.50.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115548/d176f60b-c283-9329-18c3-e29182429db1.jpeg)


```html:index.html
<div class="wrapper">
  <span>wrapper</span>
</div>
```

```css:style.css

.wrapper {
  text-align: center;
  width: 100px;
  position: relative;
  border: solid 1px black;
  background-color: #fff;
}

.wrapper::before,
.wrapper::after {
  position: absolute;
  content: "";
  display: block;
  background-color: #fff;
}

.wrapper::before {
  top: -1px;
  bottom: -1px;
  left: 5px;
  right: 5px;
}

.wrapper::after {
  top: 5px;
  bottom: 5px;
  left: -1px;
  right: -1px;
}

.wrapper span {
  position: relative;
  z-index: 1;
}

```

参考：[3 CSS techniques for border only in corners](https://codepen.io/ThiemelJiri/post/3-css-border-in-corners-techniques)
今日学んだ事(自分用)

##HTML

```
<tr></tr>
#テーブルの横一行を定義する。
```

##js
○テンプレート文字列

```.script.js
`
<div class="cdontent-name">
  <%= user.name%>
</div>
`
```
``で囲めば複数行文字列や文字列内挿機能を挿入できる

○new FormData()

```.js
var 任意の変数名 = new FormData()
```
このメソッドを使えば、htmlの入力フォームから入力された値を取得できる。

○ajaxの流れ(非同期)

```.js
//１.イベント発火(入力とか、クリックとか)
//2.ajaxで送るパスを取得する
//3.ajaxで送る値を取得する
//4.ajaxでcontrollerへ送る(正確にはルーティングにパスをだす)
記述
    $.ajax({
      url: api_url,       // リクエストのパス。ここでは'/groups/23/messages'
      type: 'POST',       // HTTPメソッド
      data: formdata,     // リクエストと一緒に送るdata
      contentType: false, // リクエストに含まれているdataの型はこれですよ〜の記述（リクエストヘッダにあるらしい）を変更しないよ
      processData: false, // リクエストに含まれているdataの実際の型を変更しないための記述出そうだ
      dataType: 'json',   //JSON形式でリクエスト送るよ
//上記にあったパスでcontrollerへ繋がる。
//POSTのパスが/groups/:group_id/messagesだと、message#createとなりmessageコントローラのcreateアクションへ飛ぶ。

//5.controllerでrespond_to do |format| を記述しjson型で取得るるようにしてjbuilderへデータを送る。
//6.jbuilderでハッシュの形でデータが生成され再び、jsへ戻ってくる
//7.jsでデータの取得が成功した時done(function())と、失敗した時.fail(function())の両方を記述する

```
AWS CLI でテキスト出力する際に確実に改行させる

# これはなんですか

- AWS CLI で `--output text` 指定するときに出力を改行表示させる方法です。
- AWS CLI の出力を xargs で渡すときにこけたのでメモとして書きます。

# 結論

以下例のように `--query` オプションで `[]` を使って明示的にリストとして出力すれば良い。

```bash:WAFのWebACL一覧を取得する例
$ aws waf list-web-acls --query "WebACLs[*].[WebACLId]" --output text
```

# 詳細

たとえばCLIでWAFのWebACL ID一覧を取得することを考える。何も考えずに以下のコマンドを実行すると、IDがタブ区切りで出力される: 

```bash:タブ区切りになる
$ aws waf list-web-acls --query "WebACLs[*].WebACLId" --output text
xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx    xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx    xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx    xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx    xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx    xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx    ...
```

これを改行区切りで出力するためには、次のようにクエリ内で明示的に `[]` を使ってリストとして結果を得ればよい。

```bash:改行になる
$ aws waf list-web-acls --query "WebACLs[*].[WebACLId]" --output text
xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
...
```

改行なしの出力を xargs に渡す場合は後者の方法を取ると良い。改行なしの場合は `-n 1` で逃げられるが、うまく聞かない環境もあるので個人的にはオススメしない。

ちなみに、 `--output table` とすると、どちらの場合も同じ出力が得られる。

```bash
$ aws waf list-web-acls --query "WebACLs[*].WebACLId" --output table
------------------------------------------
|               ListWebACLs              |
+----------------------------------------+
|  xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx  |
|  xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx  |
|  xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx  |
|  xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx  |
|  xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx  |
|  xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx  |
|                 ...                    |
+----------------------------------------+
```


# 参考

- [AWS CLIドキュメント](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-usage-output.html)
RxSwift + SPM + XCode11.2 + iOS 環境でビルドすると実行時にクラッシュする(していた）


##XCode11.3 では下記の問題は解消してます

##何があったのか
表題の通りの内容です。XCode11からSwift Package Managerが統合されたので、Carthageから乗り換えていたのですが、先日リリースされたXCode11.2 で地雷を踏みました。

私の環境 : Xcode 11.2 final, Catalina 10.15.1, iOS 13.2

https://bugs.swift.org/browse/SR-11564?focusedCommentId=51285&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#comment-51285

SPMに関連する処理の部分で、linkerがmoduleを最適化するところにバグがあるみたいです。
ですので、RxSwift以外でもSPMをつかってると広く影響があるようですね。

一応回避策として、DEAD_CODE_STRIPPING = NO とオプションをつければいける様なのですが、私はひとまず、Xcode 11.1 を入れ直して対応しています。ふぅ。。
CLI の愚痴投稿ツールを作ってみた

※ 現在TLS証明書切れで動きません

# 愚痴投稿 CLI ツール guchi を作成しました
CLI から愚痴を吐くツールを作りました。ここ最近ストレス溜まってたのでね。。なお、愚痴は私が用意している以下ページ (というかただのテキスト) に吐かれます。もちろん CLI コマンドでも取得可能。
https://guchis.site/guchis

リポジトリは以下です。舐め腐ったツールですがよかったら使ってみてください。
https://github.com/daiching/guchi

動作確認は WSL (Ubuntu) と CentOS7 で実施しています。残念ながら Mac はわかりません (もし試した方がいて、動作報告していただけたら大変有り難いです！)

取得方法としては、以下でイケるはずです。

```bash
# 実行バイナリのみ
$ wget https://github.com/daiching/guchi/raw/master/guchi
$ sudo chmod +x ./guchi
$ ./guchi

# go get する場合
$ go get github.com/daiching/guchi
$ guchi
```

なお、操作感は以下の感じです。

```bash
# 投稿された愚痴を 10 件取得
$ guchi

# 投稿された愚痴を X 件取得
$ guchi -n X

# 愚痴を投稿する (何も指定しない場合、名前は Nanashi になります。)
$ guchi <guchi>

# 愚痴を投稿者名指定で投稿する
$ guchi -u <name> <guchi>
```

あとは config ファイルも設定できます

``` [~/.guchi]
# ~ ディレクトリ配下に .guchi ファイルを作ることでいつも使う名前が指定できます
Name=daiching
```

Go で CLI ツール作るの楽しいですねぇ。
サーバーサイドがちょっとあれなので、そのうちそっちもオープンにできたらいいと思います。
ソフトウェアテスト・QA勉強会【（仮）テスト自動化の光と闇（1年間の苦労話）】 を聞いて

#はじめに
テスト自動化に関して「【増席】ソフトウェアテスト・QA勉強会【（仮）テスト自動化の光と闇（1年間の苦労話）】 」というセミナーを聞いてみた。
https://d-cube.connpass.com/event/149831/

光と闇とかいているけど、発表タイトルに闇がやたらと多いｗｗｗ


|タイトル|発表資料|
|---|---|
|テスト自動化の光と闇|(未公開)|
|クロスブラウザテストの闇と闇と闇|https://qiita.com/emurin/items/e5f4f1552cab203f777f|
|自動化立ち上げからの苦労話（闇）|https://speakerdeck.com/tsuemura/kurosuburauzatesutofalsean-toan-toan|
|しくじり先生～アジャイルテスト自動化立ち上げ迷走記～|https://speakerdeck.com/pineapplecandy/failure-teaches-success-in-automated-testing-development|

アルアルとか思いながら闇な話を聞いていたけど。


# 自動化の8原則
自動化する前に、まずは8原則をしっかりと理解する必要がある。

* 手動テストはなくならない
* 手動でおこなって効果のないテストを自動化しても無駄である
* 自動テストは書いたことしかテストしない
* テスト自動化の効用はコスト削減だけではない
* 自動テストシステムの開発は継続的におこなうものである
* 自動化検討はプロジェクト初期から
* 自動テストで新種のバグが見つかることは稀である
* テスト結果分析という新たなタスクが生まれる

ひとつずつの詳細はまた調べて自分なりの解釈を考えていこうと思うが、これを知らないで自動化すると確実に失敗する。

#テスト自動化への挑戦と失敗

何回かテストの自動化をしようと試みたが、途中で立ち消え自然消滅した経験がある。理由は以下のような様々な要因があったと思う。

* リグレッションテストがほぼない
* 新しい機能のテストが中心
* 環境の追加のテストは数年に一回
* （マイクロアーキテクチャではなく）モノシステム
* テスト技術、知識レベルの低さ
* 異動
* テストに対する低い文化度
* 。。。。などなど

そもそも自動化するメリットがないじゃないのっていうことが目白押しである。


# 自動化の目的
そもそも、自動化する目的はなんだろう。。。ということを考えてみた。

個人的には、毎回やらないといけないが、眠たくなるような単純作業(セミナーでは修行な作業と言っていたかな？)を自動化するべきだと思っている。

人の手作業でやっていたら、当然ミスもするしばらつきも出る。
機械的にやらせたほうがばらつきはなくなるので単純作業であれば、断然自動化すべきと考えている。

また、千手観音みたいに手がいっぱいないと同時に実行できないとか（人が1000人いればできるけど）現実的に人間が実施することが困難なものについては自動化せざるを得ない。


そういうことで、1回テストしたら、ほぼ再利用せずバグが出たときに過去のテストの履歴を見るだけなどであれば、はっきり言ってテストの自動化する意味もない。

セミナーでも言っていたが、目的もなく作業が楽になるからという思いで単純に自動化すると失敗することになる。

自分たちのテストや開発工程で、自動化すべき（自動化でないと実行できない）作業をよく考えてから自動化に取り組むべきだということをセミナーで再確認した


# できるところから
自動化はできるところから実施していくことが大事だと思う。

例えば、以下のようなことからスクリプトなどを作って自動化していくことが大事だし、立派な自動化と考えている。

* 大量のテストデータを作らないといけない
* 様々なテスト環境が必要
* 同じようなデータを何回も送信しなければならない
* 永遠とボタンを押し続けなければいけない
* テスト結果などのデータ（ファイル）比較や差分

テスト自体（とくにE2Eなどの）自動化は無理でも、少しずつでもテストの自動化をしていけばいいんじゃないかと思うテスターでした


<font color="Red">**この作業、ほんと、めんどくせーなーっと思った時が自動化しどきですよ**</font>
【CSS】すべての要素に対してスタイルを反映する

## はじめに
それぞれの要素に対して`text-align:center`のようにスタイルを設定しなくても、があるので紹介する。

## やり方
*（アスタリスク）を用いる。
例以下に示す。

```css

* {
　text-align: center;
}

```

## おわりに
[こちら](http://www.yoshikiminatoya.com/lab/csslab/4264.html)を参考。
DockerfileのRUNでyum書いたらインストールされなかった話

# 目的
AmazonLinux2ベースのdokcerコンテナでunzipコマンドをインストールする。

# 解決したコード
`RUN yum -y install unzip`

# 間違っていたコード
`RUN yum install unzip`

# 問題と解決までの経緯
-yオプションを付与していなかった。

dockerのビルドは通ったので立ち上げてコンテナの中に入って`unzip -h`したら、そんなコマンドは存在しないとな。
そのままコンテナ内で`yum install unzip`を実行してみたら「これらをインストールしますか？[y/n]」的なメッセージが出てきてようやく理解。

# まとめ
DockerfileでyumをRUNとかCMDする場合は-yオプション付与の検討をおすすめします。
常識なのかな？これに気づくまでにdockerイメージ再ビルドしたり消したりして、30分以上かかった、、、
AmazonEchoとRS-WFIREX4で家電を操作する-（１）

# はじめに
- Alexaで家電を操作したかった。
- Alexa対応の家電を買うわけにはいかない。

ちなみに、Alexaは起動ワードなだけで正式名称はAmazon Echoのようです。

# 必要なもの
- Amazon Echo
- [ラトックシステムのRS-WFIREX4](https://iot.ratocsystems.com/products/rs-wfirex4/)
- [家電リモコンアプリ](https://apps.apple.com/jp/app/スマート家電コントローラ/id1063944197)
- 操作したい家電（TV、エアコン、照明）とそのリモコン

# 設定
アプリをインストールしてRS-WFIREX4を設定します。

## 家電リモコンアプリのインストール
[家電リモコンアプリ](https://apps.apple.com/jp/app/スマート家電コントローラ/id1063944197)をインストールしてきます。

<img width="375" alt="IMG_65BCC99465C9-1.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405675/5066e08d-325b-0f87-71d4-fc6c7c4da63e.jpeg">

## 家電リモコンアプリとRS-WFIREX4を接続

![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f3430353637352f30313630333164372d663533352d386533312d386363632d6465373537333461303333342e706e67.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405675/23808391-e4c4-4622-bc20-697af94e3dc2.png)

## とりあえず...
<img width="375" alt="IMG_2629.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405675/f3caaa94-6ca9-172a-a9cf-214508d9a341.png">
ここまでの設定で、スマホの家電リモコンアプリとRS-WFIREX4が連携できるようになっているかと思います。
続きは次回にでも。。。

## ちなみに
家電リモコンの電源投入直後30分間はRS-WFIREX4に内蔵されているセンサー（温度、湿度）は利用できないようです。（そんなメッセージがアプリ上に表示されます）
最初だけなんで待つのみですね。
シークレットモードではキャッシュクリアされないよという話

## はじめに
同名のイメージファイルを差し替えたのですが、なぜか元のファイルが表示されていました。
Chromeのシークレットモードで見ているのになんで!?と思い、調べて見るとなんとシークレットモードではキャッシュクリアされないことを知りました。。。（俺の2時間）

## なぜキャッシュクリアされないのか
シークレットモードは閉じればキャッシュは残りませんが、閉じなければキャッシュは残り続けます。
注意が必要なのはすでにシークレットモードを一つ立ち上げていて、その状態で新しいシークレットモードを立ち上げた時。
この状態だとキャッシュやCookieはシークレットモードで共有されます。（自分はこのパターンだった）
シークレットモードを使うときは一旦全てのシークレットモードを閉じてから使いましょう！（当たり前） 

## 参考記事
[「シークレット モード」でもキャッシュは残る](https://spc-jpn.co.jp/blog/10141/)
MVCモデルの解説

#MVCモデルとは何か解説できますか？

MVCモデルとは何か？と聞かれて何も見ずに解説出来るでしょうか？
私は出来ませんでした（汗）なので、この記事ではMVCのなんたるやを、解説します！


#MVCとは何か？大雑把に解説

MVCとは何かを知る前に、そもそも何故モデルに分割されるのか、知っておくと良いでしょう。
分割される理由は簡単で、
１、開発する際の担当を分ける事が出来るから。
２、実装における機能を十分に分割しておかないと後々改修作業が大変な事になる為。
となっています。

そして肝心なMVCモデルの解説。
**MVCモデルとは、ソフトウェアの開発をする際の考え方（デザインパターン）です。過去のソフトウェア開発者たちが築き上げた開発ノウハウを濃縮したものの１つが、このMVCモデルなのです。**
Model/View/Controllerの3つの観点から、システムを創り上げる事を指しています。

#M(model)
**「Model」**は、システム内の様々な処理(ビジネスロジック)を記述する部分。いわゆるプログラミングの”ソースコード”はここに記述される。
オブジェクトの設計を行う部分の担当と言い換えてもいいでしょう。

#V(view)
**「view」**は、表示部分を担当してくれるもの。ユーザーが見てくれる部分はここで一括的に担当する。
HTMLの生成、グラフや図の表現などを行いたい場合は、このviewを使う事になるだろう。

#C(controller)
**「controller」**は、ユーザーからの入力の処理を担当する。例えばユーザーがテキストフォームに何かを入力して、それを送信した場合の処置がこのコントローラーである。
クライアント(サービス利用者)側の指令を受け取り、それをModelや、Viewに流す役割です。

※以下laravelに関する余談※
ここにビジネスロジック(本来ならmodelで書くべき)を書いたり、見た目(viewで書くべき)を書く事も出来るが、なるべくは避けると良いでしょう。
逆に言えば、ルーティング(web.phpと書かれた入力されたURLを仕分けるアレです！)と、controllerさえあれば、modelやviewは無くてもwebアプリを構築出来てしまう訳です。
【Rails】find, find_byの違い

# find, find_byの違い

## find
主キー`(:id)`に一致するオブジェクトを取り出す

``` ruby:find.rb
user = User.find(id: 1)
# => #<Client id: 1, name: "Qiita">
```

複数の主キーを渡すと，配列で返す

``` ruby:find_array.rb
users = User.find(id: 1, 2)
# => {
# <Client id: 1, name: "Qiita">,
# <Client id: 2, name: "Micheal">
# }
```

## find_by
与えられた条件に一致するオブジェクトを取り出す

``` ruby:find_by.rb
user = User.find_by(name: "Micheal")
# => <Client id: 2, name: "Micheal">
user = User.find_by(id: 1)
# => <Client id: 1, name: "Qiita">
```

## 参考リンク
[Active Record クエリインターフェイス - Rails ガイド] (https://railsguides.jp/active_record_querying.html)
Gitコマンド 逆引き

Gitの用語もよくわからんという人は[こちら](https://qiita.com/HyunwookPark/items/48920fa582d852e44289)。


## リモートリポジトリからリポジトリを取得

```
git clone <repo-url>
```

例)

```
git clone git@github.com:team-name/reponame.git
```

## リモートリポジトリを作成

ディレクトリを作成してそのディレクトリ内でgit init --bareする。

```
mkdir <repo-name>.git
cd <repo-name>.git
git init --bare
```

## リモートリポジトリの URL を確認

```
git remote -v
```

## ログ表示

```
git log
```
### ログ 1行表示

```
git log --oneline
git log --pretty='format:%C(yellow)%h %C(green)%cd %C(reset)%s %C(red)%d %C(cyan)[%an]' --date=iso
```
### ログ グラフ表示

```
git log --graph
```

## 編集中のファイルを元に戻す

```
git checkout -- <file>
```
## addしていないファイルをすべて元に戻す

```
git checkout .
```

## git rebaseで混乱時にrebase中止する

```
git rebase --abort
```

## git mergeで混乱時にmerge中止する

```
git merge --abort
```

※git pull時もマージに失敗すると中断したくなるのでこれを使う

## fetch

### リモートブランチを他の人に消してもらってもローカルに残っている場合

```
git fetch --prune
git fetch -p
```
## push

### タグを全部一気にpush

```
git push origin --tags
```

### 強制push

```
git push --force origin master
git push -f origin master
```

--forceは-fでもいい

## reset

### 1つ前のコミットを取り消す

```
git reset --soft HEAD^
```
### addしてものをまるっと取り消し(※HEAD省略可能)

```
git reset HEAD
git reset
```
## diff

### ステージングしたファイルとの差分確認

```
git diff --staged
```
### 新規ファイルを含めて差分確認

```
git add .
git diff --staged --stat
```
### 新規ファイルを削除

```
git reset .
rm <file>
```
### 差分をファイル名のみ確認

```
git diff --name-only
```
### 直近のcommitの差分ファイル一覧(前のが過去)

```
git diff --stat HEAD~ HEAD
git diff --stat --name-only HEAD~ HEAD
```
## branch

### branch作成

```
git branch <branchname>
```
### branch削除

マージ済みのブランチを削除する場合に使う。
マージしていないブランチは削除できない。

```
git branch -d <branchname>
git branch --delete <branchname>
```

どんなブランチでも削除できるのはこちら

```
git branch -D <branchname>
```

### branchリスト

```
git branch -a
```
## rm

### ファイル自体を削除

```
git rm <filename>
```
### ディレクトリまるごと削除(再帰的に)

```
git rm -r
```
### ファイルは残してgit管理対象から削除

```
git rm --cached <filename>
```
### git管理対象をあとから.gitignore設定した場合(一度すべて管理対象から消して改めてすべてstaging)

```
git rm -r --cached .
git add .
```
## config

### .gitconfigの確認

```
git config --list
```
pythonとは

#はじめに
こんにちは。qiita初投稿のPyLocです。
今回は、pythonが何かについて書きます。
#参考にさせて頂いたサイト様
https://www.sejuku.net/blog/7720
[Wikipedia](https://ja.wikipedia.org/wiki/Python)
https://qiita.com/maximum80/items/4116985b7276fdb45576
https://qiita.com/funa-tk/items/c4a239423eea018adea1
https://eng-entrance.com/java-hello-world
http://www.tohoho-web.com/js/start.htm
https://www.shido.info/py/tkinter1.html
#pythonってなんだ?
![スクリーンショット (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/524477/33639e8f-3517-fe0b-d4fe-7ca70fd169e9.png)
##pythonとは
pythonは英語で「ニシキヘビ」という意味で、グイド・ヴァンロッサムさんが開発した、インタプリタ言語です。
Wikipediaによると、
>Python（パイソン）は、汎用のプログラミング言語である。コードがシンプルで扱いやすく設計されており、C言語などに比べて、さまざまなプログラムを分かりやすく、少ないコード行数で書けるといった特徴がある。

と書いてあります。
##挫折しない?
pythonは構文がわかりやすく、IDLEではエラー箇所を教えてくれます。つまり、挫折しにくいです。
例えば、

```python
print("Hello!!World!!")
```
というプログラムがあるとしましょう。しかし、間違えて

```
pront("Hello!!World!!")
```
と打ってしまった場合、IDLEでは次のように表示してくれます。
![スクリーンショット (4).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/524477/ed88c63a-609e-731e-df84-df08b2533b73.png)
#pythonはシンプル
pythonはとてもシンプルな言語です。その証明に、「hello」と表示するプログラムを他の言語と並べて見てみましょう。
pythonの場合

```python
from tkinter import *
window = Tk()
la = Tk.Label(None, text='Hello World!', font=('Times', '18'))
la.pack()
la.mainloop()
```
C言語の場合

```c
#include <stdio.h>

int main(int argc, char *args[])
{
    printf("hello\n");
    return 0;
}
```
Javaの場合

```java

public class hello{
   public static void main(String[] args){
     System.out.println("hello");
   }
}
```
JavaScriptの場合

```javascript
<!DOCTYPE html>
<html>
<head>
<title>hello</title>
</head>
<body>
<script>
document.write("hello");
</script>
</body>
</html>
```
Swiftの場合

```swift
import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        println("hello")
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}
```
#python環境のインストール
この記事を読んでpythonをやりたくなった人のためにリンクを貼ります。
IDLEをインストールします。(私はIDLEを使用しています。)
##IDLE
IDLEはIntegrated DeveLopment Environmentの略です。
[python.org](https://docs.python.org/ja/3/library/idle.html)によると、
>IDLE は Python の統合開発環境で、学習用環境です。
IDLE は次のような特徴があります:
tkinter GUIツールキットを使って、100% ピュア Python でコーディングされています
クロスプラットホーム: Windows, Unix, macOS で動作します
コード入力、出力、エラーメッセージの色付け機能を持った Python shell (対話的インタプリタ) ウィンドウ
多段 Undo、 Python 対応の色づけ、自動的な字下げ、呼び出し情報の表示、自動補完、他たくさんの機能をもつマルチウィンドウ・テキストエディタ
任意のウィンドウ内での検索、エディタウィンドウ内での置換、複数ファイルを跨いだ検索 (grep)
永続的なブレイクポイント、ステップ実行、グローバルとローカル名前空間の視覚化機能を持ったデバッガ
設定、ブラウザ群、ほかダイアログ群

[https://github.com/python/cpython/tree/3.8/Lib/idlelib/](https://github.com/python/cpython/tree/3.8/Lib/idlelib/)でダウンロードできます。
[windowsとmacユーザーの方はこちらのサイト様](https://gammasoft.jp/blog/python-install-and-code-run/)、Ubuntuユーザーの方はソフトウェアセンターからインストールしてください。(CentOSの方は`yum install python3`で入ります。)
[AWS]CloudWatch Logsの配信タイミングはいつなのか@2019.11

# 概要
EC2やコンテナ内をステートレスに保つため、ログファイルをCloudWatch Logsに出力することがよくあると思います。
出力させる手順は公式・非公式問わずたくさんありますが、
最新のCloudWatchエージェントにおいて、実際OSがハングアップしたらどこまでログが残るのか、どの程度の間隔でフラッシュされているのか知りたかったので調べてみました。
私は <b>”最新のCloudWatchエージェント”</b> について知りたかったです。（大事なこと）

# 結論
CloudWatchエージェント設定ファイル内のlogsセッション  <b>「force_flush_interval」 </b> に <b>秒単位</b> で設定する。デフォルトは5秒。
また、この設定にかかわらずバッファ内のログサイズが1MBに達するとフラッシュされる。
詳細は、[こちら](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch-Agent-Configuration-File-Details.html#CloudWatch-Agent-Configuration-File-Logssection)の公式ドキュメントを参照。

# 実験
結論は出ていますが、念の為「force_flush_interval」を1秒に設定して実験しました。
実験方法としては、あるインスタンスのあるログファイルをCloudWatch Logsで収集するよう設定し、
このログファイルに0.1秒ごとに現在時刻を出力するシェルスクリプトを作成しました。
シェルスクリプト実行中に、該当インスタンスを強制的にシャットダウンさせ、
インスタンスのターミナルに表示された最終実行時刻と、CloudWatch Logs内の最終収集時刻を見比べることでその差を調査しました。

# 結果
![result.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/358513/74dca781-6d5d-afa6-41cc-bf2c941e91f0.png)
（実験用スクリプトが雑なので）おおむね1秒以内に出力されていますね。（アンダースコア以降はミリ秒）
絶対安心とは言えませんが、5秒よりはマシなので気になる方は変更してみるとよいかもしれません。

# その他
旧版のCloudWatch Logsエージェントではバッファサイズを変更できました。（[公式ドキュメント](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/AgentReference.html#agent-configuration-file)）
「buffer_duration」がフラッシュするまでの時間（デフォルト5秒）
「batch_size」がバッファサイズ（デフォルト10MB）
「batch_count」がバッファに入れるイベント数（デフォルト1万件）
しかし、新版では上記の通り時間しか変更できないようです。

あと、これはただの愚痴なんですが、投稿日現在だとCloudWatchエージェントが新旧2種併存しているため、
公式ドキュメントを探しても非常にややこしかったです。
下位互換のために旧版があるのは理解できますが、もう少しわかりやすい名前にしてほしいです…
LINE Messaging APIの改行について

LINE Messaging APIの改行について

```"改行前\n　改行後の文字列 "```

で改行できました。

ポイントとしては、"（ダブルフォーテーション）でくくること。

![LINEキャプチャ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/175837/3979d46c-ae08-e133-c7c4-575dd5bdf1ad.png)
チャンク転送でMiniMagickの画像アップロード速度が劇的に改善した。

個人開発したRailsアプリでMiniMagickを使っているのですが、画像のアップロードに2分以上かかっていました。

nginxでチャンク転送の設定をしたら、10秒ほどに短縮することができました。

自分用の学習記録ですが、少しでも役に立てれば嬉しいです。

また、画像データのアップローと表示速度はもっと上げたいので、他にいい方法があれば教えていただけるとありがたいです。

##チャンク転送

チャンク転送とは簡単に言うと、データをチャンクと言う単位に分割して転送することだそうです。

通常、動的に画像を生成するような場合、ファイルのサイズがわかるまでレスポンスが返せないため、サーバーの応答性能が低下してしまいます。
チャンク転送を使うことで、最終的なサイズがわからないボディを少しずつ転送できます。

HTTPのヘッダで設定を行います。

```
Transfer-Encoding:chunked
```

##nginxでチャンク転送設定

Webサーバーにnginxを使っているので、nginxでチャンク転送の設置を行います。

confファイルのserverディレクティブに以下を追加。

```/etc/nginx/conf.d/hoge_app.conf
chunked_transfer_encoding on;
```

設定を反映させるためのnginx再起動。

```
$ sudo systemctl restart nginx
```

これだけです。

チャンク転送の設定が完了しました。

これで画像のアップロード速度が改善されるはずです。

されてなかったら、お力になれずすみません。

##補足

nginxの[公式サイト](http://nginx.org/en/docs/http/ngx_http_core_module.html#chunked_transfer_encoding)を確認すると、チャンク転送はどうやらデフォルトでonになっているようです。

なので、実際どこまで効果があるのかはわかりませんが、僕の場合は一行追加することで画像のアップロード速度が劇的に改善しました。

なので、よかったら試してみてください。
UITableViewやUICollectionViewでreloadData直後にそれを前提とした処理を行いたい場合

メモです。
UITableViewやUICollectionViewでreloadData直後にそれを前提とした処理を行いたい場合は以下のようにする。

```Swift:
tableView.reloadData()
tableView.layoutIfNeeded()
// 何か処理
```
動的に行の和を計算する。

こんな感じのGASと
function GetLastRow() {
  
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('商品テーブル');
  var last_row = sheet.getLastRow()
  return last_row
  
}

関数で
=ArrayFormula(MMULT(N(INDIRECT("I2:K"&GetLastRow())),N(TRANSPOSE(COLUMN(INDIRECT("I2:K"&GetLastRow()))^0))))

動的に行（I：K）の和を計算する。
親要素の幅を超えたときのいろいろ

#通常時

通常時は以下のように子要素の幅が親要素を超えた場合は文字が折り返される。

```html
<body>
  <div class="box">
    <p>あああああああああああああ</p>
  </div>
</body>
```
```css
.box {
  border: 1px solid red;
  height: 100px;
  width: 100px;
}
```
<img width="98" alt="スクリーンショット 2019-11-06 18.31.54.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/496792/6ef42abc-f1c0-32d0-2ddb-eebdf200d4c6.png">


#折り返しを禁止する
```css
.box {
  border: 1px solid red;
  height: 100px;
  width: 100px;
  white-space: nowrap;
}
```

`white-space: nowrap;`とすることで、折り返しを禁止する。

<img width="145" alt="スクリーンショット 2019-11-06 18.34.52.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/496792/8680809c-1e68-724d-0609-98860fb19f29.png">


#はみ出した文字を非表示にする

```css

.box {
  border: 1px solid red;
  height: 100px;
  width: 100px;
  white-space: nowrap;
  overflow: hidden;
}
```

`white-space: nowrap;`と`overflow: hidden;`を組み合わせることで実現

<img width="136" alt="スクリーンショット 2019-11-06 18.38.24.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/496792/5f91299f-148b-41e8-d93a-88fc1b32c4ad.png">
KubernetesのSecretsから特定の値が入っている場所を探す

```bash
export VALUE=hoge
kubectl get secret --all-namespaces -o json | \
jq '
.
| [
    .
    | .items[]
    | {
        key: "\(.metadata.namespace)/\(.metadata.name)",
        value: [
          .
          | (.data // {})
          | to_entries[]
          | select(.value | @base64d | contains($ENV.VALUE))
          | .key
        ]
      }
    | select(.value | length > 0)
  ]
| from_entries
'
```
Why Invest in Social Network Development

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/425411/8b8f4162-767b-ec5a-0475-c86baebf21bd.png)
The number of active users of social networks websites has already surpassed 3.499 billion. This huge number shows that social network web development is a worthy investment at present.

Here are the advantages of building a social network from scratch:

- reach a larger number of users
- give users access to a network platform from their laptop or PC
- easily scale networking web site as the number of users grows
- provide an exceptional user experience and allow them to use it from the device of their choice

How to Build а Social Network From Scratch: Decide on the Type

Social media networks are built for different purposes: interaction, providing useful information and uniting users based on their interests. Knowing the needs of your target users will help you decide how to make a social media website interesting for them.

The main types of social network services are:

- Media sharing websites
- Business and professional sites
- Informational sites
- Educational websites
- Hobby networks
- Academic websites
- Social networks
- Dating platforms

More details about why it is worth investing in social network development can be found [here](https://mlsdev.com/blog/how-to-build-a-social-network-website-from-scratch)
大事なブランチをローカルからもリモートからも消したけど元に戻せた

# ブランチを消したときの対処法

### 現状
悲惨なことに大事なブランチをremoteからもlocalからも消し去ってしまいました

### 手順

```
$ git reflog
```

まずはこちらのコマンドを叩く↑
するとコミット履歴が出てくる↓

```
96f72ec7 (HEAD -> develop, origin/develop, origin/HEAD) HEAD@{0}: checkout: moving from deleted-branch to develop
5480e0d9 HEAD@{1}: commit: adjust
cab12ab2 HEAD@{2}: commit: response data debug
9b7873cf HEAD@{3}: commit: debug log modify
c506e1f5 HEAD@{4}: commit: apiUrl = null
b1c620b4 HEAD@{5}: commit: debug comment
e7df592a HEAD@{6}: commit: debug comment
8e3473d3 HEAD@{7}: commit: comment out
....
```

ちょうど一番上のところに大事なブランチを消し去った痕跡が残っていますね。
**消したブランチで作業してたときの最新の状態** に戻したいので
上から二行目の

```
5480e0d9 HEAD@{1}: commit: adjust
```

このコミットをしたときの状態に戻したいです。

そこでこのコマンドを叩く↓

```
$ git branch new-branch HEAD@{1}
```

分かるかと思いますが少し解説・・・・

```
$ git branch つけたいブランチ名 HEAD@{戻したいコミットのHEAD番号}
```

そしてこのままgit push!!
(intelliJなら`Ctrl + Shift + k`でgit push できます)

そうすると先ほどのコマンドを叩くときに指定したブランチ名で復活します。
めでたしめでたし・・・・・

備忘録
Bitnami RedmineのphpMyadminを使えるようにする

# 前提

- Debian10
- Bitnami Redmine
- httpPort 81

## phpMyadminの設定

- ログインしてからrootを取得
- httpd-app.confを変更
- apacheをリスタート

```shell:command
user@debian:~# su -
user@debian:~# (password)
root@debian:~# nano /opt/redmine/apps/phpmyadmin/conf/httpd-app.conf
```

```text:httpd-app.conf
#Allow from 127.0.0.1
Allow from all

#Require local
Require all granted
```

- apacheを再起動

```shell:command
/opt/[redmine]/ctlscript.sh restart apache
```
haml で書く時の注意（form_withで遷移しません編）

haml で書く時に苦手意識を持っている初学者で
まずHTMLを書いて、webサービスで html -> haml にて書いている方がいると思います。
そういう方にありがちな落とし穴に一緒にハマったので、備忘録として残します。

# haml で最初から書く人　
``` aaa.html.haml
 = form_with url: xxx_path
```

```aaa.html
<form action="/xxx" method="get">
```
 上記の用にヘルパーメソッドを用いる際に何がHTMLとして出力されるのか意識して書いてる

# html -> haml の人
``` aaa.html
<form action="/xxx" method="get">
```
上記のようなhtml を haml に変換してからヘルパーメソッドを追記するので以下のようなhamlになる

``` aaa.html.haml
%form action = "/yyy" method="get"
  = form_with url: xxx_path
```

そして以下のような結果になる

```aaa.html
<form action="/yyy" method="get">
  <form action="/yyy" method="get">
  </form>
</form>
```
そして記載変更時にform_withのURLだけ変更して（上記の場合、二段目のaction部分が変わる）、
「xxx_pathに飛ばないんです〜」と悩む

# 結論
何が出力されるのか考えてからヘルパーメソッドは使おう！
上記の用にピックアップされるとわかりやすいですが、長々と記載がされている一部分になってしまうと発見に時間がかかります。（ました）
【Kubernetes】CronJobの動作確認をするkubectlコマンド集

# はじめに
[【Kubernetes】CronJobのmanifest作成とメモ](https://qiita.com/boutan/items/cc107fdeabc48821cfc6) の続きです。
CronJobの確認に必要そうなコマンドを集めてみました。
上から順にやっていけば、ひととおり見わたせます。慣れてきたら必要なコマンドだけチョイスしてください。

# 前提
Kubernetesの動作環境が揃っていること。
ローカル環境で開発する場合は、MinikubeやDocker for Macなどで構築しておいてください。

# コマンド集

例として、以下を当てはめたコマンドを使用しています。こちらは状況により変更してください。
[context name] : minikube
[file name] : cronjob.yml
[cronjob name] : my-cronjob
[job name] : my-cronjob-1571993880
[pod_name] : my-cronjob-1571993880-hr59x

## コンテキスト一覧を取得
コンテキストとは、クラスタへアクセスするための情報が含まれた定義のことです。

```shell:
$ kubectl config get-contexts
```

## コンテキストの切替え
どのクラスタに接続したいかで、必要によって切り替えてください。

```shell:
ex) kubectl config use-context [context name]
$ kubectl config use-context minikube
```

## 現在のコンテキストを取得
この確認を行うことで、うっかり違う環境に作っちゃった・・！ってことがなくなりますね。

```shell:
$ kubectl config current-context
```

## ジョブを新規作成
Manifestファイルを指定して、 jobをcreateで新規作成します。
新規以外のときは、`kubectl apply`を使用すると何かと便利です。

```shell:
ex) kubectl create -f [file name]
$ kubectl create -f ./cronjob.yml
cronjob.batch/my-cronjob created
```

## CronJob一覧を取得
ジョブが動作するとLAST SCHEDULEが更新されます。

```shell:
$ kubectl get cronjob
NAME         SCHEDULE      SUSPEND   ACTIVE   LAST SCHEDULE   AGE
my-cronjob   */1 * * * *   False     0        25s             14s
```

## CronJob詳細を取得

```shell:
ex) kubectl describe cronjob [cronjob name]
 $ kubectl describe cronjob my-cronjob
```

## ジョブ一覧を取得
動いた履歴があると表示されます。

```shell:
$ kubectl get job
NAME                       COMPLETIONS   DURATION   AGE
my-cronjob-1571993880      1/1           4s         42s
```

## ジョブ詳細を取得

```shell:
ex) kubectl describe job [job name]
$ kubectl describe job my-cronjob-1571993880
```

## ポッド一覧を取得

```shell:
$ kubectl get pod
NAME                                READY   STATUS      RESTARTS   AGE
my-cronjob-1571993880-hr59x         0/1     Completed   0          58s
```

## ポッド詳細を取得

```shell:
ex) kubectl describe pod [pod_name]
$ kubectl describe pod my-cronjob-1571993880-hr59x
```

## ポッドのログを取得

```shell:
ex) kubectl logs  -f [pod_name]
$ kubectl logs -f my-cronjob-1571993880-hr59x
```

## ジョブを停止
必要なくなったら、消しておきましょう。

```shell:
ex) kubectl delete cronjob [cronjob name]
$ kubectl delete cronjob my-cronjob
cronjob.batch "my-cronjob" deleted
```
extensions/v1beta1の廃止

EKS 1.14 を利用しており、ELBの設定は、alb-ingress-controllerに頼っている。

Podのdeployをし直していたら、alb-ingress-controllerのpodから「最新バージョンを適用してください」といったエラーがでた。


> kubebuilder/controller "msg"="Reconciler error" "error"="failed to reconcile targetGroups due to failed to load ingressAnnotation due to no object matching key \"XXXXX/ingress\" in local store"  "Controller"="alb-ingress-controller" "Request"={"Namespace":"XXXXX","Name":"ingress"}


公式のdocumentを見たらapiVersionの記述が違う。
「**extensions/v1beta1**」は**廃止予定**であり、1.14から新しい記述が使える。
Qiita記事や日本語ブログの方を参考に構築していた為、この記述が古いままだった。

もう廃止されたのか、alb-ingress-controllerがチェックしてくれたのかは不明なのだが。。。
最近投稿されているkubernetesの記事にも「 extensions/v1beta1」の記載がちらほら見られるので、書いときます。

Qiitaに廃止予定のものに関して記載してくれている記事がありました。
Deploymentで使っていた「**apps/v1beta1**」等も**非推奨**ですので、書き換えましょう。
[Kubernetes 1.16: 廃止予定と削除されたもの](https://qiita.com/tkusumi/items/4ea3ad66e5817aa7c015)

変更点に関してまとめてくれている記事もありました。
[Kubernetes 1.16: 変更点まとめ(What's new!)](https://qiita.com/uesyn/items/0246346d8958318fa1d4#_reference-63cca07251963f2ba68f)


```
# 今までの指定
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: "ingress"
```
```
# 今後の指定
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: "ingress"
```
リリースノートは自分でもチェックするようにしましょう。します。
https://kubernetes.io/docs/setup/release/notes/

>Continued deprecation of extensions/v1beta1, apps/v1beta1, and apps/v1beta2 APIs; these extensions will be retired in 1.16!

EKSの1.16はまだ？
Django勉強記録用1（公式マニュアル）

この記事は自分が学習した内容を記録するために作成したものです。
理解するためのメモとして利用しているので、わかりにくい所があるのをご了承ください。

学習はDjangoの公式ドキュメントをメインに進める。
https://docs.djangoproject.com/ja/2.0/intro/

今日は、「はじめての Django アプリ作成、その 2」の途中まで学習をおこなったので、個人的なメモを以下に載せる。

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

**初めてのDjangoアプリ作成、その1**


Djangoの最初に行うセットアップ。プロジェクトを作成する。

```
$ django-admin startproject mysite
```




Django開発サーバーの起動

```
$ python manage.py runserver
```



　　
pollsという名前のアプリを作成。

```
$ python manage.py startapp polls
```

rootにアプリケーションpollsのURLを反映させる。include()は他のURLconfへ参照が可能となる。
path関数では、root, view,(kwargs),(name)の4つの引数を受け取る。
初期ソースコードの変更部分だけ以下に載せる。

```mysite/urls.py
from django.urls import include, path

path('polls/', include('polls.urls')),
```


-----

**はじめてのDjangoアプリ作成、その2**



データベースのテーブル作成

```
$ python manage.py migrate
```
---
モデルの作成（データベースのレイアウトと関連するメタデータ）

作成するアプリでは、投票項目(Question)と選択肢(Choice)の二つのモデルを作成する。
Questionには質問事項(question_text)と公開日(pub_data)の情報
Choiceには選択肢のテキストと投票数(vote)の二つのフィールドがあり、
各Choiceは１つのQuestionに関連づけされている。


```polls/models.py
from django.db import models


class Question(models.Model):
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')


class Choice(models.Model):
    question = models.ForeignKey(Question, on_delete=models.CASCADE)
    choice_text = models.CharField(max_length=200)
    votes = models.IntegerField(default=0)
```

補足：
CharFIeld()：文字のフィールド、max_lengthを指定する必要がある。
DataTimeField():日時フィールド

ForeignKey()：インスタンスを保存するフィールドを作成する。そのフィールドと紐づけるモデルを第一引数に指定する。この場合questionはQuestionモデルに紐づく。

on_delete：紐付けされたインスタンスが削除された時の挙動を定義する。
on_delete=model.CASCADE：インスタンスを削除すると、Questionに紐づいたChoiceも削除する。
on_delete=model.PROJECT：インスタンスを削除しようとしても、Questionに紐づいたChoiceが存在する場合は削除をできないようにする。

---
「モデルを有効にする」

makemigrationsはDjangoのモデルに変更がある場合、新しいmigrationの形で保存を行う。
Djangoが行う変更を手動で管理したい場合に使用

```
$ python manage.py makemigrations polls
```

実行結果は以下の通りである。読みやすくするためにフォーマットは整えているので注意。

```
BEGIN;
--
-- Create model Question
--
CREATE TABLE "polls_question" (
　　　"id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, 
　　　"question_text" varchar(200) NOT NULL, "pub_date" datetime NOT NULL
);
--
-- Create model Choice
--
CREATE TABLE "polls_choice" (
　　　"id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, 
　　　"choice_text" varchar(200) NOT NULL, 
　　　"votes" integer NOT NULL, 
　　　"question_id" integer NOT NULL REFERENCES 
　　　"polls_question" ("id") DEFERRABLE INITIALLY DEFERRED
);

CREATE INDEX 
　　　"polls_choice_question_id_c5b4b260" ON "polls_choice" ("question_id");

COMMIT;
```

id：キー
_id：外部キー

モデルの変更手順
① model.pyを変更
②マイグレーションを作成
③データベースに変更を適用

とりあえずここまで、後々更新しています。



##参考文献

Django公式ドキュメント
https://docs.djangoproject.com/ja/2.0/intro/

DjangoBrothers
https://djangobrothers.com
ResNet なんて全く理解していないだけの人生だった(Q)



## 本題
これは、ResNetについて考察した４本立て([序](https://qiita.com/kenmaro/items/008051dae0bf0ad718cb)、[破](https://qiita.com/kenmaro/items/07d72feac966008af034)、[Q](https://qiita.com/kenmaro/items/3792fbe2641003c2fe8a)、[:||](https://qiita.com/kenmaro/items/d096909311aa3b29a31a))の一記事です。


というわけで、[前回](https://qiita.com/kenmaro/items/07d72feac966008af034)の続きなのですが、前回は、
[第一回](https://qiita.com/kenmaro/items/008051dae0bf0ad718cb)で定義した疑問　　
1. 研究者がどうやってこの残差ブロックのアイディアに至ったのか
2. そもそもなぜ残差を学習するのか
3. なぜResNetが（数学的に）高精度を達成できるのか
の２つ目について考えました。加えて、
- [Residual Networks Behave Like Ensembles of Relatively Shallow Networks](https://arxiv.org/pdf/1605.06431.pdf)

の考察を用いて、ResNetとは異なる経路長をもつものを弱学習器単位とした、アンサンブル学習である。　　
という根幹にも迫りました。

![32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519792/8aa5cc9b-912a-62fa-4549-b28714bcce78.png)

今回は、
- [Learning Deep ResNet Blocks Sequentially using Boosting Theory](https://arxiv.org/pdf/1706.04964.pdf)
を読み込んでいきます。
簡単にこの論文の趣旨を説明すると、
「ResNetはアンサンブル学習を行っているようだけど、じゃあアンサンブル学習からResNetって作れるよね？」
ということです。

![33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519792/79276ae5-0955-7998-d89a-c92fb894f5b2.png)
まあでもよく考えると、ResNetがアンサンブル学習っぽいということはわかっても、普通のアンサンブル学習とは違うよね、、ってなります。
なぜかと言うと、　　
普通の残差を学習するアンサンブル学習、勾配ブースティングは弱学習器から得られる推論値をアンサンブルしていたのに対し、　　
ResNetは推測される特徴量表現をアンサンブルしているからです。　　
ここ大事なのでもう一度いいます。　　
ResNetのアンサンブルは、正解ラベルと比べる推論値をアンサンブルするのではなく、（推論途中の）特徴量表現のアンサンブルなのです。　　

ここで、[この論文](https://arxiv.org/pdf/1706.04964.pdf)の著者Huangさんはこうやりました。　　
無理やり途中の特徴量から推論値を吐き出す変換を一個人工的に入れて、それを使って正解ラベルと比べてやろう。　　
ここでは例として回帰問題となっているので、上の(3)のように途中の特徴量表現g_t(x)に人工的に入れたｗ_tを書けてあげることで、
むりやり最後の推論問題まですっ飛ばします。
そして、(4)で定義したすっ飛ばされた推論値と、次の層からすっ飛ばされた推論値の差に対して学習をし、それらを最後アンサンブルとして強学習器を作ったらどうなるんやろ？ってやってみたわけです。

![34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519792/a674075d-60d9-d03b-51c4-6051241b8973.png)
結論から言います。なんと、(5)のこの結果は、ResNetからの出力と、上で作られたアンサンブルモデルの結果が一緒になったのです！！！　　
つまり、やはりResNetはアンサンブル学習であり、残差を学習させるということは、それぞれの弱学習器の途中結果を正解ラベルと比べたときの残差を学習させることと同じことをしている！！
ことがわかったのです。　　

![35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519792/ea2abb09-36c6-31c2-61f1-16c0e4d7bd17.png)
たぶん混乱させてしまったので、もう一度詳しく説明します。
(5)の左辺は、ResNetを普通に学習させたときに出てくる出力です。g_(t+1)(x)がｘを入れたあと、ｔ回残差ブロックをくぐらせたもので、最後のｗは最後に推論させる（例では回帰なので１次元に飛ばす）ための線形変換です。
![36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519792/ff66a183-8bc5-b74f-e43e-12b0599119aa.png)
一方(5)の右辺は、ResNetの途中の層をそれぞれ推論空間にマッピングさせ、残差を学習させたものの和、つまり勾配ブースティングによるアンサンブル学習です。
(5)は、それらの結果が等しくなる！ということを言っているのです！！
すごいよね、。。。。

##Qのまとめ 
今回は比較的短かったですが、まとめです。
ResNetがアンサンブル学習っぽいことはわかっていたが、実際にResNetをブロックごとに残差学習させたものをアンサンブルすると、それはResNetの出力そのものに成るということがわかった。
老体エンジニアまだまだ頑張る開発サイト！！

みんな独学ですが当年69歳まだまだ頑張る開発サイトとして今後も息子（初心者）と投稿しては反省して開発を続けてて行きたいと思っています。
あらためて
https://qiita.com/shinsakujazzbass/items/87a90b46c8da29234bbe
をはじめ色々挑戦してゆきますので、興味のあるかたはご覧ください。
今挑戦しているのは、小規模SNSをWordPress等と組み合わせ構想しています。
これは私共のクライアントの団体組織のコミニケーションツールとして利用可能サイトとそれに連動するアプリとしての構想です。
![system_image001.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101462/cc69b75d-0587-c4ce-4c5f-f9a75b055eaa.jpeg)
このシステム構築にまつわるサーバー再度、とアプリ関連の投稿を行って行きたいとおもいます。
今テストを行なっているXcodeのiphoneアプリのダイアグラム以下のようなものです。
![スクリーンショット 2019-11-06 17.47.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101462/b11312b3-a3ac-158a-d209-a9901b7d3532.png)

2回目につづくhttps://qiita.com/shinsakujazzbass/items/ff000c242585271042b8
Xcode11にてアシスタント・エディタを表示する

Xcode11にしてからアシスタント・エディタが見つからずちょっと困ったので備忘録。
# Assistant Editorの表示
<img width="716" alt="スクリーンショット 2019-11-06 17.24.29.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457333/3ad1ed69-88b0-94cf-3e8f-62d526e4075b.png">

# Assistant Editorを横に表示
デフォルトだと真下に表示されるので今まで通り横に表示したい場合。
「Assistant on Right」に設定。
<img width="647" alt="スクリーンショット 2019-11-06 17.37.39.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457333/52546264-d9b9-852b-b3bd-dd4e0cdf42b0.png">
sedコマンドを初めて見て、意味不明だったので読解したメモ

ある記事を見ているときに、下記のようなコマンドが出現  

```
$ sed -i.bak s@xxx@$HOME/test@ a.txt
```

## sed ってなに
なるほど、文字列の置き換えコマンドなのか、、

参考:
[【Linuxコマンド】sedで文字列を置換する方法](https://www.sejuku.net/blog/54595)

## -i.bakはなに
-i は直接編集して内容を上書きですぜってわかりましたが
`.bak` はおそらくその際に.bakファイルを作ってくれるのかな？

## @はなにもの

>パスなどを全置換する際にスラッシュをエスケープするのが面倒な場合 2013/06/18
s/.../..../g の記法のスラッシュは記号なら比較的なんでもよくて、3つ同じ記号を使っていることに意味があるので、s@...@...@g のようにも書ける。
例

```
cat ファイル名 | sed -e 's@/etc/foo/bar@/home/my/etc/foo/bar@g'
```

参考&引用元:
[sedコマンド](https://hydrocul.github.io/wiki/commands/sed.html)

/で区切って **置き換えたい文字** / **置き換える文字** って書いてない！？
@って何！？ってなりました。当然のごとく。
awscli のクレデンシャル関係コマンドの備忘録

MFA 必須のマルチアカウント構成で AWS を利用する場合に必要なコマンドの備忘録です。

# トークンの取得

~~~text:.aws/config
[profile project-profile]
region=ap-northeast-1
mfa_serial = arn:aws:iam::000000000000:mfa/your-iam-user-name
role_arn = arn:aws:iam::111111111111:role/OrganizationAccountAccessRole
source_profile = master-profile
~~~

~~~sh:command
aws --profile project-profile sts get-caller-identity
~~~

キャッシュされたクレデンシャルのクリア

~~~sh:command
rm -r ~/.aws/cli/cache
~~~

# CodeCommit 用 Credential Helper

~~~sh:command
aws --profile project-profile codecommit credential-helper $@
~~~

~~~conf:.git/config
[credential]
        helper = !aws --profile project-profile sts get-caller-identity >&2 && aws --profile project-profile codecommit credential-helper
        UseHttpPath = true
~~~

# Reference
+ [ステップ 3: 認証情報ヘルパーを設定する](https://docs.aws.amazon.com/ja_jp/codecommit/latest/userguide/setting-up-https-unixes.html#setting-up-https-unixes-credential-helper)
+ [7.14 Git のさまざまなツール - 認証情報の保存](https://git-scm.com/book/ja/v2/Git-%E3%81%AE%E3%81%95%E3%81%BE%E3%81%96%E3%81%BE%E3%81%AA%E3%83%84%E3%83%BC%E3%83%AB-%E8%AA%8D%E8%A8%BC%E6%83%85%E5%A0%B1%E3%81%AE%E4%BF%9D%E5%AD%98)
クラス･メソッド･インスタンスの名前を統一してしまうと､インスタンス生成時にメソッドが実行されてしまうバグを、異世界転生モノっぽく説明してみた。

### はじめに
クラス構文の動作確認のため、あまりにも適当なテストコードを書いた際に、
とある小さなバグ(?)を発見した。

（くだらない話なので、異世界転生モノ風に語ってみようと思う。）

### プロローグ
ボクはどこにでもいる普通の男子高校生。
ある日、道端の猫がトラックに轢かれそうになっていたので身を挺して助けたのだが、
不運にもトラックを避けきれずボクは死んでしまった。猫は逃げた。

気がつくと目の前には女神様がいて、ボクは「ニホン」という異世界を救うために転生させられた。
ニホンは、「ピーエイチピー」と呼ばれる魔法文明を気付いていた。
ボクは女神様から「ブラインドタッチ」というチートスキルを授かったため、この世界で最強のピーエイチピー使い「ペチパー」と呼ばれる賢者を目指し、修行をはじめた。

**　(中略)**

### 最終章　バグ(?)との遭遇
ピーエイチピーには「クラス」と呼ばれる強力な魔法があると聞いて、さっそくボクは修行をはじめた。
命名規則とかめんどくさいし、最初は適当に試してみようっと。

```PHP:PHP
class Hoge {
  private function hoge() {
    echo 'hoge';
  }
}

$hoge = new Hoge();
```
```:実行
PHP Fatal error:  Uncaught Error: Call to private Hoge::hoge() from invalid context in…
```

…あれ？
王立図書館に秘蔵されていた伝説の魔導書「キータ」を参考にして書いてみたのに、なんでうまくいかないんだろう…。
もうちょっと簡単な方法で、試してみるか。

```PHP:PHP
class Hoge {
  function hoge() {
    echo 'hoge';
  }
}

$hoge = new Hoge();
```
```:実行
hoge
```

…ん？
どうして`function hoge()`が発動したんだ？
インスタンスを生成したとき、自動的にメソッドを発動させるには、
「コンストラクタ」と呼ばれる特別な制御魔法を使う必要があるハズなのに…。


*プルルル…*

女神「あ、もしもし少年〜？ どしたの？
え？ クラスの挙動がおかしい？ そんなわけ……… げっ！！
あ、あはは、たしかにちょっぴり個性的な魔法よね！
まあでも、ニホンの常識では、クラスの名前は名詞、メソッドの名前は動詞で名付けるって相場が決まってるから、問題ないでしょ！
応援してるから、頑張って世界を救ってね！ それじゃね〜！」

*ガチャ。　ツー、ツー、ツー…*

おいおい…なんなんだあの女神は？
ちくしょう、結局よくわからないし、ボクは最強のペチパーにはまだまだ程遠いみたいだ。
女神から貰ったブラインドタッチのスキルも、そんなに万能なスキルじゃなさそうだし。これからどうなるんだろう…。
まっ、考えててもしかたないし、もっといっぱい修行して、いつか絶対最強のペチパーになるために頑張るしかないか。

やれやれ。
ボクの異世界生活は、まだまだ先が長そうだ。

**　完**

### 作者からのメッセージ
あわわ、こんな駄作に目を通していただいて、誠にありがとうございますっ！
1行で終わってしまう話を、なんとか皆様に楽しんで読んでいただくために、
稚拙ながら精一杯構成を考えさせていただきました！

私の大好きな「異世界転生」作品を、こんな形で世の中に出せることになるとは、思ってもみませんでした！
これからも、作者として、ひとりの読者として、いっぱいいっぱい頑張らせていただきます！

最後にひとこと…
この記事のことが嫌いでも…Qiitaと、異世界転生モノのことは嫌いにならないでください！！！

### おわりに
**ごめんなさい、ふざけすぎました。**

テストコードを書いていた際の不可解な現象をメンター大先生に相談したところ
「（この現象）多分、誰も知らないっすよｗ」
と、神のようなお言葉をいただいたので、舞い上がって面白記事にしてしまいました。

これからは、真面目にたくさん学習していきたい所存ですので、応援していただければ幸いです。
よろしくお願いいたします。

命名規則はきちんと守りましょうね。
Ice Lakeでレイ・トレーシング

https://qiita.com/shinjiogaki/items/607500269fe6b109dbac
のフォロー・アップです。

第7回目のレイトレ合宿でレイ・トレーシングの速度を競うイベントがありましたが、参加時はAVX2の使用で、AVX512を使うとどうなるか実際のCPUで検証が出来ていませんでした。

エミュレータは以下にありますが、実行に時間がかかるので規模の大きなソフトの開発には向かないように思います。
https://software.intel.com/en-us/articles/intel-software-development-emulator

先日、Ice Lake (i7-1065G7)を入手したので、コードを書き換え簡単なテストを行いました。結果から言うと高速になりました。

今回のテストでは、巷で噂されているように、AVX512を使うとクロックが低下して、逆に遅くなる、といった現象には見舞われませんでした。もちろん、長時間計算させると徐々にクロックが落ちてきますが、それはAVX2でも同じでしょう。

今回使用したシーンはHairballでObject SplittingのBVHが苦手とするものです。
![output.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/56484/663364e5-fff7-6c63-9e46-dbb2b6280081.png)

|  | 8ary BVH | 16ary BVH |
|:-----------:|------------:|------------:|
| 1回目       | 6.81        | 7.95 |
| 2回目       | 6.77        | 7.84 |
| 3回目       | 6.83        | 7.92 |

単位はMrays/secで1秒当たりに計算したレイの本数(百万本)です。

はじめ、単純に8分木から16分木に変えただけでは若干遅くなりましたが、AVX512ではcompressを行う便利な命令が追加されており(https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=compress) トラバーサルのコードでこれを使うことで、速度が向上しました。また、期待されるように、メモリの消費は若干ながら減少しました。

高速化には、より多くの三角形をリーフに詰め込むこんで、ツリーを少し浅くできるという点が大きく貢献していると考えられます。リーフに入れる三角形の数を調整したりすればもう少し高速化できると思われますが、確認ができたので良しとします。
image関数で動的に画像を表示させる。

最終行を取得する為にこんな感じのGASを書く。
function GetLastRow() {
  
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('商品テーブル');
  var last_row = sheet.getLastRow()
  return last_row
  
}


こんな感じの関数をセルに入力
=ArrayFormula(IMAGE(INDIRECT("B2:B"&GetLastRow())))

B列の最終行までの画像URLがプレビューされる。
PowerShell CoreではSystem.Web.Security.Membershipは利用できない

メモ。表題の通りなのだけど、PowerShell CoreではSystem.Web.Security.Membershipは利用できないことを確認した。

# 現象

PowerShellでパスワード文字列生成方法として、Web上ではしばしば次のようなものが紹介されている。

```
PS> Add-type -AssemblyName System.Web
PS> [System.Web.Security.Membership]::GeneratePassword(10,3)
```

PowerShell 5.1.18362.145環境では上記でうまくいったが、PowerShell Core 6.2.3環境でこれを実行したところ、次のようなエラーになった。

```
Unable to find type [System.Web.Security.Membership].
At line:1 char:13
```

# 原因

これはそもそも.NET Coreの非互換によるらしい。

> I would not expect it to work with PowerShell core as it was uses .net framework features that would not be included in core.
> （[Not compatible with PowerShell Core · Issue #23 · davotronic5000/PowerShell_Credential_Manager](https://github.com/davotronic5000/PowerShell_Credential_Manager/issues/23#issuecomment-499439072)）

# 代替策

Redditの「[Generate good password : PowerShell](https://www.reddit.com/r/PowerShell/comments/al2v1z/generate_good_password/)」で、以下のようにアッセンブリに頼らずPowerShellでランダム文字列を生成する代替策が提案されている。

```
$length = 15

$letters = "abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ".ToCharArray()
$uppers = "ABCDEFGHJKLMNPQRSTUVWXYZ".ToCharArray()
$lowers = "abcdefghijkmnopqrstuvwxyz".ToCharArray()
$digits = "23456789".ToCharArray()
$symbols = "_-+=@$%".ToCharArray()

$chars = "abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789_-+=@$%".ToCharArray()

do {
	$pwdChars = "".ToCharArray()
	$goodPassword = $false
	$hasDigit = $false
	$hasSymbol = $false
	$pwdChars += (Get-Random -InputObject $uppers -Count 1)
	for ($i=1; $i -lt $length; $i++) {
		$char = Get-Random -InputObject $chars -Count 1
		if ($digits -contains $char) { $hasDigit = $true }
		if ($symbols -contains $char) { $hasSymbol = $true }
		$pwdChars += $char
	}
	$pwdChars += (Get-Random -InputObject $lowers -Count 1)
	$password = $pwdChars -join ""
	$goodPassword = $hasDigit -and $hasSymbol
} until ($goodPassword)

Set-Clipboard $password
```

PowerShellではなくなるけど、「[asp.net - Alternative to System.Web.Security.Membership.GeneratePassword in aspnetcore (netcoreapp1.0) - Stack Overflow](https://stackoverflow.com/questions/38995379/alternative-to-system-web-security-membership-generatepassword-in-aspnetcore-ne)」ではSystem.Web.Security.Membership.GeneratePasswordのコードを元にした代替コードが示されている。

# 参照

* [Windowsでpowershellを使用しランダムなパスワードを生成する - conf t](https://monaski.hatenablog.com/entry/2015/09/29/202421)
* [PowerShellでサクッとパスワード生成 - Qiita](https://qiita.com/mkht/items/be5adfc639077953b303)
* [Not compatible with PowerShell Core · Issue #23 · davotronic5000/PowerShell_Credential_Manager](https://github.com/davotronic5000/PowerShell_Credential_Manager/issues/23#issuecomment-499439072)
* [Generate good password : PowerShell](https://www.reddit.com/r/PowerShell/comments/al2v1z/generate_good_password/)
* [asp.net - Alternative to System.Web.Security.Membership.GeneratePassword in aspnetcore (netcoreapp1.0) - Stack Overflow](https://stackoverflow.com/questions/38995379/alternative-to-system-web-security-membership-generatepassword-in-aspnetcore-ne)
PHP7.1からprivate constが書ける

タイトル落ちですが、以下のような実装でお悩みの方の助けになればと思います。
外部から参照されることなく、またイミュータブルなものがほしいとき、

```php
class Something {
    private $age = '永遠の17歳';

    public function changeAge(): void
    {
        $this->age = '30歳';
    }
}
```
外部からは参照できませんが内部から変更可能なので実装次第では変化してしまう可能性があります。

```php
class Something {
    private function age(): string
    {
        return '永遠の17歳';
    }
}
```
`private function`が値を返すことでイミュータブルが守られますが、個人的に好きではない。

### っていうかそれ定数

```php
class Something {
    private const AGE = '永遠の17歳';
}
```
PHP7.1からは`const`のアクセス修飾子に`private`が書けるようになっていたので無事**外部から参照されることなく、またイミュータブルなもの**が実現できました。
https://www.php.net/manual/ja/language.oop5.constants.php#language.oop5.basic.class.this
What's "jade" ?

よく使い方を忘れるので、必要な時にサッと読み返せるように超完結にまとめておきます。

>勉強中の関連記事まとめ
>[自分用の勉強記事をまとめた目次　~擬似知識体系~](https://qiita.com/oekaki-hoho-ron/items/3194f560efc461ec03b0)

#jadeとは

Java Agent Development Frameworkの略。
作業の高速化 alias編


# 作業を高速化
 **alias** という便利なものを使っていく
自分で設定した名前のコマンドを作成することができる。

## 使用例
ファイルを作成する時
 
```:terminal
$ touch index.html
```
ってやりますよね？
**alias**を使ってコマンドを作成すると

```:terminal
$ html
```
とするだけでindex.htmlが作成できます。

#どうやるか
ホームディレクトリに *.bash_profile* ファイルを作成する。(*.bashrc*でも可)

```:terminal
$ touch .bash_profile
```
下のように記述

```javascript:.bash_profile
 alias html="touch index.html"
```

sourceコマンドで変更を反映させる

```:teminal
$ source .bash_profile
```
これで作成した**html**コマンドが使用できる
試しにやってみてください。

```:terminal
$ html
```
ファイルを確認すると新たに追加されているはずです。


#終わり
*ls* とか間違えて slってしちゃう時ありますよね。

```javascript:.bash_profile
alias ls="ls -G"
alias sl="ls -G"
alias ld="ls -G"
alias ks="ls -G"
alias kd="ls -G"
alias s="ls -G"
alias l="ls -G"
```

私はこんなせっかちなことしてます。
他にも *npm install*を「*n*」 、*git pull*とかを「*gp*」とかにしてます。

PK_FIREとかにすると楽しくなるかも(ならない)