OmniAICreator/Qiita-1.07M huggingface dataset:
ノスタルジアpc-9801 その6

#概要

整理していたら、フロッピーディスクが出てきた。
せっかくなので、エミュで動かしてみた。

#環境

- windows vista
- t98-next
- disk explorer

#dbaseⅡに、データをアペンドする。

##データを準備

csvファイル。

```
名前,性別,年齢,血液型
牧 ひかり,女,73,AB型
小堀 たまき,女,80,AB型
脇田 遥,女,68,AB型
長崎 真一,男,45,A型
向井 サンタマリア,女,65,A型
出口 雄太,男,30,O型
野村 かおり,女,58,AB型
三宅 千夏,女,51,AB型
長島 理紗,女,50,O型
小泉 くるみ,女,28,B型
```

##createして、データベースを作る。

![d1.jpg](https://qiita-image-store.s3.amazonaws.com/0/18104/0cfea1d7-2cae-8b21-3d5f-f479af80c287.jpeg)

name 項目名
tepy　タイプ　Cは、文字　Nは、数値
width　列幅
dec　　小数点


##csvファイルを固定長ファイルにする。

siftjis crlf


```
牧 ひかり           女   73AB型  
小堀 たまき         女   80AB型  
脇田 遥             女   68AB型  
長崎 真一           男   45A型   
向井 サンタマリア   女   65A型   
出口 雄太           男   30O型   
野村 かおり         女   58AB型  
三宅 千夏           女   51AB型  
長島 理紗           女   50O型   
小泉 くるみ         女   28B型   
```

##appendで、読み込む。



![d0.jpg](https://qiita-image-store.s3.amazonaws.com/0/18104/6c7de791-780e-ba3c-8d58-4bcfba3d797d.jpeg)


以上。
Git,GitHub基礎

Git,GitHubの基礎を備忘録的にまとめてみました。

#環境
virtualbox 5.2.26
vagrant 2.1.2
mac 10.14.2

#Gitとは
###バージョン管理システム
システム開発での区切りを記録して管理出来るもの。
誰がどのような意図で、どのような変更をしたかなどが明確に分かる。
Gitを導入する事で以下のメリットが生まれる。

・コードとコメントを分けられて、履歴が分かりやすく管理出来る。
・任意のバージョンを指定でき、即座にバージョンを切り替えられる。
・ローカルとリモートで管理する事で複数人での開発に役立つ。








#Gitを使った開発Flow



####ローカルリポジトリ作成

```
# 任意のディレクトリで
git init
```

####リモートリポジトリをclone or pull

```
cd [ローカルリポジトリ]
git clone [リモートリポジトリのパス]

or

cd [ローカルリポジトリ]
git pull [リモートリポジトリのパス]
```

####ローカルに開発用ブランチを追加して、チェックアウト

```
git checkout -b [開発用ブランチ名]
```

####開発してadd〜commit

```
# ファイルをインデックスに追加
git add [file_name or dir_name]


# コミット
git commit -m "comment"
```

####ローカルの開発用リポジトリをリモートの開発用リポジトリにプッシュ

```
# originという名前でリモートリポジトリを追加
git remote add origin [リモートリポジトリの開発用ブランチのパス]

# 登録したリモートリポジトリにローカルリポジトリをプッシュ
git push origin [開発用ブランチ名]


# git push -u origin [開発用ブランチ名] で次からブランチ名省略可
# git remote rm origin で登録されているリモートリポジトリを削除
```

####プルリクエストを送る→マージorボツ
githubだとメニューからプルリクエスト選択して、リクエストを送る。
OKならマージし、新バージョン。

####リモートをローカルリポジトリのマスターにプル

```
git pull [リモートリポジトリのパス]
```






#基本コマンド



###初期設定


####ユーザー名、メールアドレス登録
```
git config --global user.name [ユーザー名]
git config --global user.email [メールアドレス]
```

####エイリアス登録

コマンドからも出来るが.gitconfigを弄ったほうが楽。

```txt:.gitconfig
[user]
	name = [name]
	email = [email]
[alias]
	co = checkout
	br = branch
	st = status
	cm = commit
	sh = show
	cp = cherry-pick
	ad = add
	lo = log
```




##履歴関連

####変更の履歴を表示

```
git status [オプション]
#オプションにディレクトリ等を指定でそのディレクトリ内の変更表示
```

####コミットの履歴を表示
```
git log [オプション]
```
```
# オプション
--numstat    # ファイル毎の追加削除行数を表示
--since="[日数] days ago" --until="[年/月/日]"   # 日付指定
--graph   # 見やすく表示
--merges   # マージのみ
--all    # 全ブランチ
```



##ブランチ関連


####ブランチ表示
```
git branch
```

####ブランチ切り替え
```
git checkout [ブランチ名]
```

####ブランチ作成と共にチェックアウト
```
git checkout -b [ブランチ名]
```

####ブランチ削除
```
# HEADにマージしたブランチ削除
git branch --delete [ブランチ名]


# マージしたかを問わずに削除
git branch -D [ブランチ名]
```


##タグ関連

####タグ表示
```
# タグ一覧表示
git tag


# 注釈も表示
git tag -n
```

####タグ追加
```
git tag [タグ名]
```

####注釈付きタグ追加
```
git tag -a [タグ名] -m "コメント"


# 以前のコミットにタグを付ける。
git tag -a [タグ名] -m "コメント" [コミット]
```

####タグ削除
```
git tag -d [タグ名]
```

####タグをプッシュ
タグはブランチをプッシュした時に反映されないため、別でプッシュする。

```
tag push origin --tags
```




#GitHubとSSH接続

SSH (Secure Shell) プロトコルを利用してターミナルから安全にGitHubに接続する。
SSHは秘密鍵・公開鍵を使用した鍵認証によって、
クライアントとリモートマシンの通信を暗号化し安全にコマンドを実行できる。

まず、簡単なコマンドから2つの鍵を作る。

```
# sshのディレクトリに移動
cd ~/.ssh

# 鍵を作成 ssh-keygen [オプション]
ssh-keygen -t rsa -b 4096


-t rsa = 鍵の種類。他より強固。
-b 4096 = 鍵の長さ。rsaは4096bit
```


鍵名とパスフレーズを入力し、鍵が作成される。



##GitHubに公開鍵をアップする
https://github.com/settings/keys
からGitHub上に、公開鍵をアップする。



##configファイルに鍵情報を登録

sshディレクトリ内のコンフィグファイルに鍵情報を記載する。
※configファイルが無ければ作る。

```txt:config
Host github github.com
 HostName github.com
 User git
 IdentityFile ~/.ssh/[鍵の名前]
```

これで、下記コマンドでGitHubとの接続を出来る。

```
ssh -T github
```

パスフレーズを入力し、

```
Hi [ユーザー名]! You've successfully authenticated, but GitHub does not provide shell access.
```
と表示されればOK!

これで、ターミナルからGitHubにSSH接続出来る。
FormikでFastFieldを使うとレンダリングが減る件

# 背景
FormikにはFastFieldって便利なコンポーネントがあったことを最近知った。
（何故か公式ドキュメントを数ヶ月前から眺めていたのに気づかなかった）


# Formikとは

```
Build forms in React, without tears.
```

「Reactでのフォーム作成にもう悩まない！」
的なニュアンスですかね？？

Reactでのフォーム作成を手伝ってくれるコンポーネントです。

https://jaredpalmer.com/formik/


# FastFieldは何が便利なのか

### Fieldの場合
例としてFormikのFieldに自作したコンポーネントを渡してやるとします


```html
<Field component={TextInput} name="firstName" />
```

おそらくこうやって自作したコンポーネントを使うことが多いかと思います

で、その中身にはこんな感じでレンダリング判定してチューニングしてたりすることが多いかと思います
下はstateが変更した時のみレンダリングが走るように判定をさせてます

```tsx:TextInput.tsx
    /**
     * コンポーネントを際描写する必要があるかを判定
     *
     * @param {ITextInputProps} nextProps
     * @param {ITextInputState} nextState
     * @returns {boolean}
     */
    public shouldComponentUpdate( nextProps: ITextInputProps, nextState: ITextInputState)
    {
        return this.state.value !== nextState.value
    }
```

ちなみにこういった判定しないと、Form内の別パーツの変更でレンダリング走り、
結果一カ所いじるだけでアホみたいな数のレンダリングが発生しますので
Fieldを使うならば判定した方が良いです


# FastFieldの場合

```html
<FastField component={TextInput} name="firstName" />
```

FastFieldに変えただけですね。
これだけshouldComponentUpdateの記述はなくともshallow比較でレンダリング判定をしてくれます。


公式にも以下のように書いてありますね。

```
Changes to values.firstName, errors.firstName, touched.firstName, 
or isSubmitting. This is determined by shallow comparison. Note: dotpaths are supported.
```

# 最後に
その他apiについて細かくは、[公式](https://jaredpalmer.com/formik/docs/api/fastfield)をみてください

これで基本的に`shouldComponentUpdate`はわざわざ記述しなくてもよくなりますが、
公式メッセージにも書いてありますが、特定のstateでは判定自体されないので、
自分で追加したstateなどについてもレンダリング判定に含めたい、などの時は
やっぱりshouldComponentUpdateが必要になってきます

まあ使えるとこは使った方がシンプルですよ、って感じです。
Python 日時系備忘録

#やること
限られた機能しか使わないため、
備忘録として、Pythonのdatetimeモジュール系で出来る事を簡単にまとめ。

#環境
virtualbox 5.2.26
vagrant 2.1.2
python 3.5.2
mac 10.14.2





#日時取得

```python:input.py
from datetime import datetime

now = datetime.now()
print(now.year, '/', now.month, '/', now.day, ' ', now.hour, ':', now.minute, ':', now.second, sep='')
```

```python:output.py
2019/2/26 12:00:00
```

####時刻がずれていた場合手動で設定
```
$ sudo date -s "2019/02/26 13:00:00"
```
※仮想マシンを落とすと同期する設定にしてても時間がズレるため手動で設定。
Vagrantfile弄ったり、Vboxmanage,vboxadd-serviceなどのコマンド色々試したがズレる・・。
解決策探してます。。




#日時作成して文字列で表示

```python:input.py
from datetime import datetime 

day = datetime(1853, 6, 3, 13, 00, 00)
str_day = day.strftime('%Y年%m月%d日 %H時%M分%S秒')
print(str_day)
```

```python:output.py
1853年06月03日 13時00分00秒
```



#文字列を日時に変換

```python:input.py
from datetime import datetime

str_day = '1853/6/3 12:00:00'

day = datetime.strptime(str_day, '%Y/%m/%d %H:%M:%S')
# 指定フォーマットは同じにする。 
print(day)
```

```python:output.py
1853-06-03 12:00:00
```



#日時の差を求める

```python:input
2019 2 27
```

```python:input.py
from datetime import datetime
from datetime import timedelta

day = input().strip().replace(' ', '/')

base = datetime.strptime(day, '%Y/%m/%d')
result = base - timedelta(days=10000)
# 入力された日にちから1万日前を求める。

str_result = result.strftime('%Y年%m月%d日')
print(str_result)
```

```python:output
1991年10月12日
```

とりあえず、基本的な機能だけ。
VSCode でマークダウンのプレビューを右側に出す

## 結論

.md ファイルを開いている状態で、「**Command + K**」を押してから、一度手を離して、「**V**」を押すと、いい感じに右側にマークダウンのプレビューが出ます。

## 説明

.md ファイルを開いているときに、「**Command + Shift + P**」を押して、上のコマンドパレットに 「**Markdown: Open Preview to the Side**」と入力し選択すると、右側にマークダウンのプレビューを表示することができます。

![スクリーンショット 2019-02-28 20.20.23.png](https://qiita-image-store.s3.amazonaws.com/0/164793/0649731b-55ad-ee8f-bd54-70a60ebf7065.png)


また、これをショートカットキーを使用して「**Command + K**」を押してから、一度手を離して、「**V**」を押すことでも、同じように右側にマークダウンのプレビューを表示できます。

## まとめ

Qiita の記事や README などを VSCode で書くとき、プレビューが右側にあるととても便利なので、積極的に使っていきたいです。
softmax関数の処理を今まで勘違いしていた話

もしかしたら同じ勘違いをしている人がいるかもしれないという事で、記事にしておきます。

sofmaxと言えば、分類問題などで使われる関数であり、以下のような特徴がある。
1.総和を1にする。
2.数値の大小は変わらない。

これは、深層学習を勉強した人なら、多くの人がお世話になったであろう「ゼロから作るdeep learning」の70ページ目にも書かれている。
しかしひょんな事から、**その2の特徴は正確ではない**という事に気が付いた。

最初から総和が1の配列をsoftmaxに通してみる。

```python

def softmax(x):
    if x.ndim == 2:
        x = x.T
        x = x - np.max(x, axis=0)
        y = np.exp(x) / np.sum(np.exp(x), axis=0)
        return y.T

    x = x - np.max(x) # オーバーフロー対策
    return np.exp(x) / np.sum(np.exp(x))
x = np.array([0.7, 0.2, 0.1])
print(softmax(x))
```

```test.py
[0.46396343 0.28140804 0.25462853]
```

総和が1である配列をsoftmaxに通したら同じ値のまま返ってくるという認識だったのだがそうではなかった。

次にsoftmaxの出力を再度softmaxに通す...という処理をしてみる。

```python

import numpy as np

def softmax(x):
    if x.ndim == 2:
        x = x.T
        x = x - np.max(x, axis=0)
        y = np.exp(x) / np.sum(np.exp(x), axis=0)
        return y.T

    x = x - np.max(x) # オーバーフロー対策
    return np.exp(x) / np.sum(np.exp(x))

x = np.array([0.7, 0.2, 0.1])

for _ in range(100):
    x = softmax(x)
print(x)
```

```test.py
[0.33333333 0.33333333 0.33333333]
```
最終的には、値が均一になる事がわかった。
この事から、softmaxに通した値の大小は変わらないというのは間違いである。
Circle CI 上での jest テストが not enough memory となる場合の対処

Circle CI の上で Jest による JS のテストを実行するケースがあるがそこそこの量のテストをかくと、メモリ容量が枯渇してしまう場合がある。
ローカルでは発生しない問題なので少し調査しました。

これは Jest が 子プロセスをそれぞれのテストに対して立ち上げすぎていて、メモリを食いつぶしていることが原因だと考えられます。

Node.js のドキュメントにも起動時間のオーバーヘッドとメモリをそこそこ占有するので多数立ち上げすぎるのは推奨しないと書いてありますね。

- [Node.js child_process](
https://nodejs.org/api/child_process.html#child_process_child_process_fork_modulepath_args_options
)

解決策としては `jest --runInBand` のオプションを使うことで 子プロセスをたちあげないようにするのが適当そうです。

- [Jest option --runInband](https://jestjs.io/docs/ja/cli#runinband)

子プロセスを立ち上げる行為は並列実行を意図したものなので最近 Node.js に入った [worker_thread](https://nodejs.org/api/worker_threads.html) などの仕組みを利用するのが最適なのかもしれませんね。

以上
ただのドキュメントの参照で恐縮ですが「 Circle CI, Jest, not enough memory」 でランディングした方参考にしてみてください。
JavaScript オブジェクトの分割代入　オブジェクトの異なる名前のプロパティへ代入する

オブジェクトの分割代入で名前を変えて変数に代入できるが、
オブジェクトのプロパティに名前を変えて代入できるのだろうか。

変数に代入はもちろんできる。

```javascript
var o = {p: 42, q: true, r: 'hoge'};

var {p: foo, q: bar, r: baz} = o; 
console.log(foo); // 42 
console.log(bar); // true  
console.log(baz); // 'hoge'  
```


オブジェクトの名前の違うプロパティに代入はどうだ。

```javascript

var o = {p: 42, q: true, r: 'hoge'};

var o2 = {};
({p: o2.pp, q: o2.qq, r: o2.rr} = o);
console.log(o2); // {pp: 42, qq: true, rr: "hoge"}
```

できた！
けど、1つずつ代入する方が読みすい、かな。

```js
var o2 = {};
o2.pp = o.p;
o2.qq = o.q;
o2.rr = o.r;
```

参考
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment
住所に含まれる色んな横棒をぜんぶ半角ハイフンに変える

最近グーグルスプレッドシートで住所一覧を渡されてごちゃごちゃ何かすることが多いのですが、書き方が統一されていないのでいつもキレ気味の私です。

この「住所のフォーマットを統一する」シリーズは数回続く予定です。

特に難しいことはしません。

``` yokobou2hyphen.js
// 横棒っぽいものを全てハイフンに置き換える
function yokobou(str){
  //-－‐―ーｰ─━ ← 横棒の例

  // 横棒のリスト
  var list = ["\uFF0D","\uFE63","\u2212","\u2010",
              "\u2043","\u2011","\u2012","\u2013","\u2014",
              "\ufe58","\u2015","\u23AF","\u23E4","\ux2D7",
              "\u2796","\u208B","\u30FC","\uFF70"];

  for(var i=0;i<list.length;i++){
    // 数字と数字に挟まれた横棒を探す
    var reg = new RegExp("\\d" + list[i] + "\\d","g"); // reg = /\dー\d/g
    var match = str.match(reg);
    if(match){
      for(var j=0;j<match.length;j++){
        var oldStr = match[j]; // ex) 5ー2
        var newStr = match[j].replace(list[i],"-"); // ex) 5-2
        str = str.replace(oldStr,newStr); // 該当箇所を置き換える
      }
    }
  }
  return str;
}

// 実行例
  var add = "宮城県仙台市横浜区1ー2―3—405";
  var add2 = yokobou(add);
  // add2 = "宮城県仙台市横浜区1-2-3-405";

```

list で挙げたすべての横棒について、「数字（横棒）数字」という並びを正規表現で探し、「数字（ハイフン）数字」に置き換えています。
正規表現のところで g オプションを付けているので、該当する箇所全てが配列で返ってきます。

横棒のリストはこちらのサイト
http://www13.plala.or.jp/bigdata/yokobou.html
を参考にしました。
他にも思いついたら list に適宜付け加えてください。
例えば、listに"の"を追加すると、「1の2」→「1-2」ができます。


しかしもっと頭の良い根本的な解決方法は、**ハイフン以外の横棒は使用禁止**という規則を周知することじゃないかなと思います（怒）

（つづく）

（追記）
@luna-mrst さんから後半のfor文は正規表現にて簡略化できるとご指摘いただきました。
ありがとうございます。来週からの業務が捗ります（大袈裟でなく）。

以下コメント引用です。

```yokobou2hyphen.js
function yokobou(str) {
  const list = ["\uFF0D","\uFE63","\u2212","\u2010",
              "\u2043","\u2011","\u2012","\u2013","\u2014",
              "\ufe58","\u2015","\u23AF","\u23E4","\u02D7",
              "\u2796","\u208B","\u30FC","\uFF70"];  

  const reg = new RegExp(`(?<=\\d)[${list.join('')}](?=\\d)`, 'g');
  return str.replace(reg, '-');
}
```

（追記ここまで）

（追記2）2019/3/22
すみませんでした。再訂正です。
どうもGASの環境では**①後読みが使えない**ことがわかりました。また、**②arr.join("")をしたときに一部の横棒が文字化けしてうまく正規表現に組み込まれない**ようでした。この2点を踏まえて結局、以下のように改良しました。

```yokobou2hyphen_new.js
function yokobou(str){
  //-－‐―ーｰ─━ ← 横棒の例

  // 横棒のリスト
  var list = ["\uFF0D","\uFE63","\u2212","\u2010",
              "\u2043","\u2011","\u2012","\u2013","\u2014",
              "\ufe58","\u2015","\u23AF","\u23E4","\ux2D7",
              "\u2796","\u208B","\u30FC","\uFF70"];

  for(var i=0;i<list.length;i++){
    // 数字と数字に挟まれた横棒を探す
    var reg = new RegExp("\\d" + list[i] + "(?=\\d)","g");
    var match = str.match(reg);
    if(match){
      for(var j=0;j<match.length;j++){
        var oldStr = match[j]; // ex) 5ー
        var newStr = match[j].replace(list[i],"-"); // ex) 5-
        str = str.replace(oldStr,newStr); // 該当箇所を置き換える
      }
    }
  }
  return str;
}
```

（追記2ここまで）
ソートしたクエリ同士をUnionしたくて泥沼だった話

条件１でソートしたものと、条件２でソートしたものをユニオンで結合しようとしたらソートが効かずにどっぷりハマりました。

結論から書きますが、<font color="Red">ユニオンは内部でソートしても効きません</font>

しかし裏技がありました。


まずは想定ですが、人気の野球選手ベスト三位と、人気のサッカー選手ベスト三位をくっつけたテーブルを取得したいとします。


まずダメな例から書きます.


```sql
(select * from baseball_player order by vote DESC limit 3)
union
(select * from soccer_player order by vote DESC limit 3)
```

まんまとハマったやつです。
上のクエリも下のクエリも独立でなら正しい結果を吐きますが、ユニオン内部だとソートが効かないので、無意味です。

そこで裏技！！
結構よくあることなのですが、””テーブルに包む””とうまく行ったりします。
何を言ってるのかわからないと思うが俺にも（ry

```sql
select * from ((select * from baseball_player order by vote DESC limit 3)) tbl1
union
select * from ((select * from soccer_player order by vote DESC limit 3)) tbl2
```

なぜかこうするとユニオン内にも関わらずソートが効きます。

おそらく、テーブルに直すことで先にその中のクエリを作ってくれるんだと思います。
4 - 2 * 5 = -6
を
(4 - 2) * 5 = 10
に直すようなイメージで、ときどきこうしてテーブルに直すことがあります。

SQLの不具合基準ってよくわからないものが多いですよね。
KubernetesのConfigMapを使ってWordpressのphp.iniを書き換える

ローカル環境でWordpressをkubernetes(Docker for Mac)を使って開発しています。
php.iniをimage側で書き換えたものを使って対応していたんですが良い方法を見つけたのでメモ

## ConfigMapを使って設定を書き換える

https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/

必要な部分だけ抜粋。

```yaml

apiVersion: v1
kind: ConfigMap
metadata:
  name: wordpress-php-config
data:
  wordpress-custom.ini: |-
    upload_max_filesize = 50M
    post_max_size = 50M
```

↑コレでmountできるディレクトリを作成され、wordpress-custom.iniが作られる。
実際の設定ファイルからもConfigMapを作成できる。

```yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  ...
spec:
  ...
  template:
    spec:
      containers:
        - image: wordpress:5.0.3-php7.1-apache
          ...
          volumeMounts:
            ...
            - name: php-config
              mountPath: /usr/local/etc/php/conf.d/wordpress-custom.ini
              subPath: wordpress-custom.ini

      volumes:
        ...
        - name: php-config
          configMap:
            name: wordpress-php-config
            items:
              - key: wordpress-custom.ini
                path: wordpress-custom.ini
```

itemsを指定してconfigMapからiniファイルだけを参照できるようにする。
subPathを指定しないでphp-configをMountするとdirectoryとしてマウントされる。
Luckyフレームワークを0.12.0から0.13.2にアップグレードした

# lucky v0.13.2がリリースされた
https://github.com/luckyframework/lucky/releases

ので、既存プロジェクトのluckyを早速アップグレード
当然動かない

lucky initで新たにプロジェクトを作ったものとファイル比較したり、luckyのコード読んだりして動くようにしたまとめ

---
2019/3/1追記
UPGRADE_NOTESが公開されてた
https://github.com/luckyframework/lucky/blob/master/UPGRADE_NOTES.md#upgrading-from-012-to-013

---

## 修正した箇所
### lucky_recordがavramになってる
https://github.com/luckyframework/lucky_record
が
https://github.com/luckyframework/avram
にリネームされてる
src/dependencies.cr 内の
```require "lucky_record"```
を
```require "avram"```
に変更

プロジェクトのファイルの「LuckyRecord」と書かれている部分を全部「Avram」に修正

### loggerの変更
Lucky::LogHandlerがなくなり、Dexter::Loggerになった
config/log_handler.cr
を削除
config/logger.cr
を作成し、以下内容を書いとく

```ruby:config/logger.cr
require "file_utils"

logger =
  if Lucky::Env.test?
    # Logs to `tmp/test.log` so you can see what's happening without having
    # a bunch of log output in your specs results.
    FileUtils.mkdir("tmp")
    Dexter::Logger.new(
      io: File.new("tmp/test.log", mode: "w"),
      level: Logger::Severity::DEBUG,
      log_formatter: Lucky::PrettyLogFormatter
    )
  elsif Lucky::Env.production?
    # This sets the log formatter to JSON so you can parse the logs with
    # services like Logentries or Logstash.
    #
    # If you want logs like in develpoment use `Lucky::PrettyLogFormatter`.
    Dexter::Logger.new(
      io: STDOUT,
      level: Logger::Severity::INFO,
      log_formatter: Dexter::Formatters::JsonLogFormatter
    )
  else
    # For development, log everything to STDOUT with the pretty formatter.
    Dexter::Logger.new(
      io: STDOUT,
      level: Logger::Severity::DEBUG,
      log_formatter: Lucky::PrettyLogFormatter
    )
  end

Lucky.configure do |settings|
  settings.logger = logger
end

Avram::Repo.configure do |settings|
  settings.logger = logger
end
```

### specのログが出力される
`crystal spec` すると /tmp ディレクトリが作成され、test.log にログ出力される。
再度 `crystal spec` すると既にtmpディレクトリがあるためエラーが発生して落ちる
tmpディレクトリあったらそのまま使ってくれよ、、、、
config/logger.crの中身の冒頭に

```ruby
  if Lucky::Env.test?
    # Logs to `tmp/test.log` so you can see what's happening without having
    # a bunch of log output in your specs results.
    FileUtils.mkdir("tmp")
    Dexter::Logger.new(
      io: File.new("tmp/test.log", mode: "w"),
      level: Logger::Severity::DEBUG,
      log_formatter: Lucky::PrettyLogFormatter
    )
```
の記述があってここでtmpディレクトリ作られてるのでここをよしなに書き換える。
「/tmp」を`.gitignore`に追加

### belongs_toの関係性のテーブルのQueryのpreload()が使えなくなってる
preloadメソッドなんてないよ！って怒られる

https://github.com/luckyframework/avram/blob/master/src/avram/associations.cr#L137
```def preload_{{ assoc_name }}(preload_query : {{ model }}::BaseQuery)```
メソッドがあるので、

`.preload(UserQuery.new.name("bob"))`
と書いていた部分を

`.preload_user(UserQuery.new.name("bob"))`
に書き換えて解決

### Queryでis_notが使えなくなった

` .id.is_not(user_id).email `
と書いてたものが動かなくなったので
` .id.not.eq(user_id).email `
に書き換えて解決

### Taskのbannerがdepricatedだからsummary使ってね！
taskの説明文
`banner "my task"`
を
`summary "my task"`
に書き換えて解決

### /bin/setup が /script/setupに移動

### /binの中にいっぱいバイナリファイルが作られるようになった
「/bin」を`.gitignore`に追加

---
他にも何かあったら追記していきます
Webサーバ起動

よく使うものでよく忘れるのでメモ

#### 起動
httpd,mysql[mysqld]などを行う

■CentOS７以上
``systemctl start サービス名.service``
■CentOS７以下
``service サービス名 start``



#### 停止
■CentOS７以上
``systemctl stop サービス名.service``
■CentOS７以下
``service サービス名 stop``


#### 再起動
■CentOS７以上
``systemctl restart サービス名.service``
■CentOS７以下
``service サービス名 restart``


#### 

#### その他
service httpd restart
または
/etc/init.d/httpd restart

再起動コマンドが効かない場合、以下のコマンドである可能性があります。(CentOSのバージョンの違いなど)
apachectl restart
apache2ctl restart

### AmazonLinux2　php.iniが反映されない

https://ikatakos.com/pot/programming/web_development/server/aws/php_fpm

```
# php-fpmの再起動
$ sudo systemctl restart php-fpm.service

# Apache再起動
$ sudo service httpd restart
```
Debian, Ubuntuへapt(-get)でAdoptOpenJDKをインストールする方法

## はじめに

Oracle JDK 8のサポート終了や、Oracle JDKの有償化に伴い、AdoptOpenJDKが注目を浴びています。例えば、豪Atlassian社のJiraやConfluence等は、AdoptOpenJDKをサポートしています。

AdoptOpenJDKのインストールは、AdoptOpenJDKのサイトからtar+gz形式のアーカイブファイルをダウンロードして展開し、適当なディレクトリへ配置し、パスを通すというのが標準的な方法になりますが、せっかくUbuntuやDebianを使っているのであれば、どうせならapt(-get)で管理したくなります。

ということで、apt(-get)からのAdoptOpenJDKのインストール方法になります。

## 手順
OpenJDK 8 をインストールする場合
（内容は、後述の参考情報と同じです）

### Ubuntu

```
sudo add-apt-repository --yes ppa:rpardini/adoptopenjdk
sudo apt-get update
sudo apt-get install adoptopenjdk-8-installer 
```

### Debian

```
[[ ! -f /usr/lib/apt/methods/https ]] && sudo apt-get update && sudo apt-get install apt-transport-https
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys A66C5D02
echo 'deb https://rpardini.github.io/adoptopenjdk-deb-installer stable main' > /etc/apt/sources.list.d/rpardini-aoj.list 
sudo apt-get update 
sudo apt-get install adoptopenjdk-8-installer
```

## 参考情報

- Debian/Ubuntu installer packages for AdoptOpenJDK
 - https://github.com/rpardini/adoptopenjdk-deb-installer
- AdoptOpenJDK
 - https://adoptopenjdk.net/
情報処理安全確保支援士 平成29年度春 午後1 問1

下記の問題集を参考させていただいでおります。
[午後(I・II)に集中！情報処理安全確保支援士精選17問](https://www.amazon.co.jp/%E5%8D%88%E5%BE%8C-I%E3%83%BBII-%E3%81%AB%E9%9B%86%E4%B8%AD%EF%BC%81%E6%83%85%E5%A0%B1%E5%87%A6%E7%90%86%E5%AE%89%E5%85%A8%E7%A2%BA%E4%BF%9D%E6%94%AF%E6%8F%B4%E5%A3%AB%E7%B2%BE%E9%81%B817%E5%95%8F-%E6%9E%97%E7%A7%80%E6%A8%B9-ebook/dp/B07B7LHCVN/ref=sr_1_21?s=books&ie=UTF8&qid=1551168594&sr=1-21&keywords=%E6%83%85%E5%A0%B1%E5%87%A6%E7%90%86%E5%AE%89%E5%85%A8%E7%A2%BA%E4%BF%9D%E6%94%AF%E6%8F%B4%E5%A3%AB)

#設問1
**(1) a：カ b：オ c：エ**
感染したAさんのPCからARPポイズニングが行われたことにより管理用PC、FWのARPテーブルが書き換えられてしまった問題です。
管理用PCが何らかのタイミングでFW向けのARP要求をブロードキャストする。しかし、AさんのPCがFWより先にARP応答返すことに成功することで管理用PCのARPテーブルが書き換わってしまいます。(FWも同様な動きで書き換わる)
このことからARPポイズニングが成功すると「中間者攻撃」が成功したことを意味し、本来「管理用PC→FW(サーバ向け)」の通信が「管理用PC→AさんのPC→FW(サーバ向け)」の通信になってしまいます。(戻りの通信も同様にAさんのPCを経由する)
このことから、表3のFW向けのMACアドレスはAさんのMACアドレスになり(a)、AさんのARPテーブルは通信を中継(盗聴)するのでIPアドレスとMACアドレスの組み合わせに変更はありません。

**(2) d：5**
管理用PCのIPアドレスを総当たりで推測することを考えた場合の問題です。
今回の問題だと192.168.0.1～192.168.0.254までのIPアドレスを送信元として、サーバセグメントに接続を試みる、ということを言っているのだと思います。
管理用PC及びPCはPCセグメントに設置されており、そこからサーバセグメント(LDAPサーバ及びCRMサーバ)への通信行われた場合、FWのフィルタリングルール項番5に該当します。

**(3) 送信元：ケ 宛先：カ サービス：キ**
IPアドレスの総当たり攻撃ではなく、盗聴によりIPアドレスが特定されてしまいました。
設問1(1)の通り、管理用PCからサーバ向けの通信は盗聴されているため、送信元は管理用PC、宛先は、まず認証の通信を盗聴したいためLDAPサーバ、サービスはSSHになります。
表1.4の通信を盗聴する感じです。
また、CRMサーバへの通信は表1のFWフィルタリングルールによりHTTPSが利用されるため通信の内容(今回だと利用者ID、パスワード)が暗号化されているため盗聴ができません。

#設問2
**攻撃名：中間者攻撃**
Aさん以外のPCとCRMサーバとの間の通信に割り込み、自身の通信とすりかえる攻撃を**中間者攻撃**と言います。
中間者攻撃の対策はサーバ証明書です。
また、詐称される機器は通信をする相手である**CRMサーバ**です。

#設問3
**(1) PCセグメント内に管理用PCとサーバ間の通信が流れなくなるから**
不正侵入の対策としてPCセグメントとサーバ管理セグメントに分けました。
こうすることで管理用PCとサーバ間の通信はPCセグメントを通らなくなり、盗聴の危険性がなくなります。

**(2) SYN (C)→(A)**
**　　SYN-ACK (A)→(B)**
セグメントを分けることで管理用PCのIPアドレス取得に成功した場合でも、TCPコネクション確立を防ぐことが可能になります。
管理用PCになりすましたAさんのPCがLDAPサーバ向けにSYNパケットを送ります。(C→A)
しかし、実際管理用PCはサーバ管理セグメントにいるためSYN-ACKパケットはLDAPから管理用PC(サーバセグメント→サーバ管理セグメント)へ向かうため、SYN-ACKパケットは拒否されます。(A→B)
Wordpress ACFの設定をfunctions.phpにコードで書く

カスタムフィールドといえば定番のACF。すごく便利です。
https://www.advancedcustomfields.com/

毎回管理画面から設定していくのが面倒くさいのでfunctins.phpで書いてみました。

## コードで書くと良いところ

- 画面をポチポチと押していかないで済む。特に繰り返しのグループとか作っていると混乱する。
- ローカルの環境(Docker) → テスト環境 → 本番環境 って構成の場合にテーマファイルのアップロードで済む。


## 書き方

以下にドキュメントがあります。コレ見れば大体わかります。
https://www.advancedcustomfields.com/resources/register-fields-via-php/

### 基本的な書き方

```php
// 基本。phpのarray in arrayってすごく読みづらい。。

acf_add_local_field_group(array(
  array(
    "key" => "field_unique_id",  // WPでユニーク?
    "label" => "ラベル", // 表示ラベル
    "name" => "var_name", // テンプレート側で探す時の変数名
    "type" => "text", // 入力タイプ
  ),
));
```

なぜかタイプ一覧がドキュメントにないので察する（調べ方は下に書きます）
だいたいタイトルになっている`XXXX FIELD SETTINGS`のXXXXの部分がタイプ名。

### グループとか繰り返しとか

ここら辺はドキュメントにサンプルが書いていない。
ので色々調べた結果以下。

```php

acf_add_local_field_group(array(
  // グループ ----------------------------------------
  array(
    "key" => "field_group",
    "label" => "グループ",
    "name" => "group_name",
    "type": => "group",
    "sub_fields" => array(
        arary(
          "type" => "text",
          "key" => "field_group_key_text",
          "label" => "グループ>テキスト",
          "name" => "group_text"
        ),
        arary(
          "type" => "number",
          "key" => "field_group_key_number",
          "label" => "グループ>数字",
          "name" => "group_number"
        ),
    ),
  // 繰り返し -----------------------------------------
  array(
    "key" => "field_repeat",
    "label" => "繰り返し",
    "name" => "group_repeat",
    "type": => "repeater",
    "button_label"=> "追加",
    "sub_fields" => array(
        arary(
          "type" => "image",
          "key" => "field_repeat_image",
          "label" => "画像",
          "name" => "repeat_image"
        ),
    ) 
  ),
));
```

## 書き方の調べ方

管理画面 ＞ カスタムフィールド ＞ Tools　にGenerate PHPがあるのでここでPHPのコードをかき出してくれます（色々調べてから見つけた。。。）
作りたいUIを画面で作成してかき出してみればタイプ名や設定値などが全て分かりました。
Windows10のisoファイルをダウンロードする

# Windows10のブラウザではisoファイルをダウンロードできない
MacやLinuxではisoファイルを直接ダウンロードするようになっていますが、Windowsではmedia creation toolをダウンロードし、インストール用のUSBメモリかisoファイルを作成するようになっています。
インストール用のUSBメモリーを作成できる機能は便利ですが、USBではVirtualBoxで使えないのと、ファイルとして保存できません。また、ツールを利用してisoファイルをダウンロードする場合、PCにツールというごみが残されてしまいます。わたしはPCに少しでもごみを残したくないと思っています。
Windows10のブラウザからでも、Mac等と同様に直接ダウンロードする方法のメモです。

# 実際の方法
ブラウザは、今回はGoogleChromeを使います。
まずは、"windows10"と検索します。"Windows 10 のディスク イメージ (ISO ファイル) のダウンロード"と書いてあるリンクを開きます。すると、"Windows 10 のダウンロード"というページにリダイレクトされます。
[Windows 10 のダウンロード](https://www.microsoft.com/ja-jp/software-download/windows10)
[Windows 10 のディスク イメージ (ISO ファイル) のダウンロード](https://www.microsoft.com/ja-jp/software-download/windows10ISO)
![google検索](https://qiita-image-store.s3.amazonaws.com/0/369431/6f084cd5-81e9-0ea3-2612-8eab450fc23f.png)

サイトが読み込まれたら、「F12」キーを押すか、「Ctrl」＋「Shift」＋「I」キーを同時に押してデベロッパーツール(開発者ツール)を起動します。Chrome画面右上のハンバーガーメニューから開くことも可能です。
![デベロッパーツールを起動する](https://qiita-image-store.s3.amazonaws.com/0/369431/122d8166-8488-207b-bc60-1155d5875cab.png)
次に、開いたデベロッパーツールの左上のほうにあるデバイスのマークをクリックします。水色になるとモバイル表示が有効になります。上のほうにデバイスの種類を選択するところがあります。iPad ProやGalaxyなどを選択してから再読み込みをします。
![img02.png](https://qiita-image-store.s3.amazonaws.com/0/369431/60afae44-12f0-3af1-8caa-e68578112752.png)
"Windows 10 のディスク イメージ (ISO ファイル) のダウンロード"にリダイレクトされたら、エディションと言語を選択します。エディションを選択後に確認ボタンを押さないと言語を選択できません。
![img03.png](https://qiita-image-store.s3.amazonaws.com/0/369431/c4173a09-5699-5af7-e153-6acbac4a8d24.png)
言語を選択して、確認ボタンを押すとダウンロードボタンが2つでてきます。32-bitと64-bitがあります。ボタンをクリックするとすぐにダウンロードが始まります。Google Chromeではダウンロードは下のバーに表示されます。

![img05.png](https://qiita-image-store.s3.amazonaws.com/0/369431/62139f94-8d55-495d-4e9e-33f6e64bef90.png)
今回は、Windows 10 October 2018 Update、日本語、64bitをダウンロードしました。
容量は4.67GBでした。自宅のインターネット回線で、ダウンロードには25分くらいかかりました。

# Microsoft Edgeを使う場合
ブラウザにMicrosoft Edgeを使う場合も、Google Chromeとほぼ同じです。
F12キーを押して開発者ツールを開き、開発者ツールの上のほうにあるメニューからエミュレーションをクリックします。開いたタブの中にあるモードにブラウザープロファイルをWindows Phoneにします。すると、すぐに画面が切り替わります。
![img09_edge.png](https://qiita-image-store.s3.amazonaws.com/0/369431/8f3c4b2a-66d2-107b-e297-6ccaa2384ba6.png)
![img10_edge.png](https://qiita-image-store.s3.amazonaws.com/0/369431/a1cc51be-3fd7-8ae3-5dc9-437604b01c90.png)
![img11_edge.png](https://qiita-image-store.s3.amazonaws.com/0/369431/231ea7f3-e749-6d91-c96e-aa6ea8e57c9f.png)

# 参考
Google Chromeのデベロッパーツールでスマホサイトの表示をチェックする方法 : ビジネスとIT活用に役立つ情報
https://www.asobou.co.jp/blog/web/gcd-check
Windows10のISOをダウンロードする方法、インストールDVD/USBを作成する方法 - ぼくんちのTV 別館
https://freesoft.tvbok.com/win10/installation/download_iso.html
Division by zero


José Manuel Rodríguez Caballero
Added an answer
In the proof assistant Isabelle/HOL we have x/0 = 0 for each number x. This is advantageous in order to simplify the proofs. You can download this proof assistant here: https://isabelle.in.tum.de/

Close the mysterious and long history of division by zero and open the new world since Aristotelēs-Euclid:　1/0=0/0=z/0= \tan (\pi/2)=0.
 
Sangaku Journal of Mathematics (SJM) c ⃝SJMISSN 2534-9562 Volume 2 (2018), pp. 57-73 Received 20 November 2018. Published on-line 29 November 2018 web: http://www.sangaku-journal.eu/ c ⃝The Author(s) This article is published with open access1.
Wasan Geometry and Division by Zero Calculus
∗Hiroshi Okumura and ∗∗Saburou Saitoh
gdbでC/C++のデバッグ

# `Segmentation fault (コアダンプ)` の発生
CやC++を書いていると必ずといっていいほど悩まされるこのメッセージ
エラーの原因がterminalに直接出力されないので、初心者が躓きやすい所の1つです。

## コアダンプの発生
```
Lambda:11	Em:1.01	ARI:0
Lambda:11	Em:1.02	ARI:0.290903
Segmentation fault (コアダンプ)
```

C++で書かれた[クラスタリング(教師なし機械学習)を行うプログラム](https://github.com/aqua-ix/clustering)を実行中に`Segmentation fault(コアダンプ)`が発生。突如プログラムが停止してしまいました。
この原因箇所を突き止めるのに`gdb`というツールを使おうと思います。

# gdbとは
https://ja.wikipedia.org/wiki/GNU%E3%83%87%E3%83%90%E3%83%83%E3%82%AC
>GNUデバッガ（単にGDBとも）は、GNUソフトウェア・システムで動く標準のデバッガである。 これは、多くのUnix系システムで動作可能な移植性の高いデバッガであり、Ada、C言語、C++、FORTRAN、FreeBASICといったプログラミング言語に対応している。 

gdbはUnixの標準的なCUIデバッガです。
eclipseやVisual StudioなどのIDEでは標準でGUIデバッガが使えるようになっていますが、目的はそれらのものと同様です。

# 使用方法

まずコンパイルオプションに「-g」を付けてコンパイルします。

```　　
g++ [ファイル名] -g -o
```

多くのLinuxディストリビューションではデフォルトでCoreDump機能が無効になっているため、有効にします。

```
ulimit -c unlimited
```
このコマンドの意味は`生成するCoreのサイズを制限しない`ということです。

プログラムを実行します。

```
./a.out
...
(省略)
...
Lambda:11	Em:1.01	ARI:0
Lambda:11	Em:1.02	ARI:0.290903
Segmentation fault (コアダンプ)
```

ここでカレントディレクトリを見ると、「core」と名のついたファイルが生成されているはずです。
このcoreをGDBでデバッグしてみます。

```
gdb ./a.out core

GNU gdb (Ubuntu 8.1-0ubuntu3) 8.1.0.20180409-git
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./a.out...done.
[New LWP 10366]
Core was generated by `./a.out'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x00005599dc02eccb in Hcm::set_crispMembership (this=0x7ffcf0375ea0) at hcm.cxx:159
159	    CrispMembership[max_index][k]=1.0;
```

ここで一番下に原因となっている関数名が書かれています。

もっと詳しく見てみたいのでbacktraceします。

```
(gdb) backtrace
#0  0x00005599dc02eccb in Hcm::set_crispMembership (this=0x7ffcf0375ea0) at hcm.cxx:159
#1  0x00005599dc03c300 in main () at qfcma_main_user_knowledge.cxx:112
```

main関数の原因箇所を詳しく見たいので#1を指定します。

```
(gdb) frame 1
112	      test.set_crispMembership();
```

これでコアダンプの原因となった関数が特定できました。

必要に応じて原因箇所のコードを表示したり、ローカル変数を表示したりもできます。
詳しくは下記の記事を参照してください。

# gdbについてのさらに詳しい記事
https://qiita.com/ShikiSumiya/items/a08363db88f21c81d351

# 追記
今回のコアダンプの原因は、double型変数の計算限界によりNaNが発生し、配列に格納されたNaNを参照しようとした結果として配列外参照が起こっていたためでした。
Django + sqlite3 のテスト環境で、Database is lockedエラーでハマった話

メモ書きに近い内容で恐縮ですが、同様のエラーが発生した方は参考にしてみてください。  

# 対象の読者
* Djangoでサーバサイドプログラミングを実施する方。
* テスト環境でデータベースにsqlite3を用いている方。
* 自動テストなどで、sqlite3に並行負荷をかける可能性のある方。

# 前提条件
* Python: 3.6.3
* Django: 2.1.3
* TestCafe: 0.23.3
* TestCafe Studio: 0.4.1

# 今回対象とする問題
`OperationalError: database is locked`  

* 画面操作の自動テスト時に、たまにテストが失敗する。(Django側でクラッシュする)  
* 用いるテストツールやタイミングによって、大丈夫な時とそうでない時がある。
* 上記のエラーメッセージが、Djangoの標準エラー出力に出力される。

# 結論 (忙しい人はここまで)
* Django + sqlite3の組み合わせで、設定で ATOMIC_REQUESTS = Trueを有効化している場合、ほぼ同時に更新リクエストが来た際、クラッシュする。

# 回避方法
* settings.pyのsqliteに、ATOMIC_REQUESTSオプションがあれば、削除する。  
  
```settings.py
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
        # 'ATOMIC_REQUESTS': True # この行を無効化
    }
}
```
* デフォルトではこのオプションは設定されていないため、設定済の方のみが今回の対象となります。 
* なお、公式のドキュメントにある[タイムアウト値を大きくする対処法](https://docs.djangoproject.com/en/2.1/ref/databases/#database-is-locked-errors)を実施しても効果がありませんでしたが、ATOMIC_REQUESTSが無効でこのエラーが起きている場合は、試してみる価値はありそうです。

# この回避方法について
* あくまで、テスト環境向けの対処法であり、本番環境では非推奨です。
  * (そもそもsqlite3を使わないので、この問題自体が発生しない可能性あり)

# 備考
* TestCafeのGUI版 (TestCafe Studio)で、たまたま、Javascriptが(通常のブラウザやCUI版 TestCafeと違い)多重実行されるバグ(?)に遭遇し、TestCafe Studioが管理するブラウザからDjango側にほぼ同時に２つの更新リクエストが発生していた。
* 2個目の更新リクエストがエラーになり、E2Eテストが失敗扱いになった。

# 原因をどう発見したか
* Djangoのエラーメッセージがトランザクションの衝突を示唆していたため、トランザクションおよびデータベースに関する設定を調べ、試行錯誤的に設定を変え発見した。

# まとめ
* テスト用ならsqlite3でも大丈夫と思っていると、思わぬ落とし穴にはまることがあります！ 

* 皆様もお気をつけくださいm(_ _)m
プログラミング学習記録12〜Atomの「不可視文字を表示」がいい〜

##今日やったこと
- Udemy「Web開発入門完全攻略コース - プログラミングをはじめて学び創れる人へ！未経験から現場で使える開発スキルを習得！」セクション3の10~18

以下、セクション・パートごとにとったメモです。

###セクション３HTML入門
####10.イントロダクション-HTML入門-
セクション３でやることの確認。

####11.HTMLの歴史
HTMLの歴史とW3Cについての動画。
HTML5が2014年から使われたことを知り、意外と最近できたものなんだなと思いました。

####12.HTMLの基本構文
開始タグと終了タグで囲ってコードを書く、というHTMLの基本について確認。
ここは特に問題なしという感じです。

####13.MDN
HTML、CSS、JavaScript、HTTPなどのプログラミング言語やWeb技術に関する説明書のようなサイト。
調べたいことがあれば、MDNを使っても調べられるそうです。
例えば、HTMLのaタグについて調べたかったら、「MDN HTML a」とグーグル検索をかける、という感じです。

####14.HTML文書の基本構造
HTMLの基本ついて確認。
Progateをやった人にとっては常識なので、さらっと流し見で大丈夫です。

####15.はじめてのHTML
Atomエディタの背景色をSettings→thema→UI themaから変更できます。白色に変更できるみたいです。
でも、黒の方がかっこいいですね。

####16.補足：日本語が文字化けする場合
```html
<meta charset="utf-8"/>
```
で文字コードをutf-8にすることで日本語の文字化けを防ぎます。

####17.HTMLの雛形（テンプレート）
必ず記述する必要のある部分（DOCTYPE宣言や文字コード指定など）がすでに記述されたファイルが添付されています。

####18.Atomの設定　不可視文字
Atomの設定で「不可視文字を表示」にチェックをすると、インデントの文字数がわかりやすくなります。

<img width="1434" alt="スクリーンショット 2019-02-28 13.46.00.png" src="https://qiita-image-store.s3.amazonaws.com/0/323324/f06e86b9-c1c3-4a94-ae2f-f4565b011707.png">


<img width="266" alt="スクリーンショット 2019-02-28 13.46.08.png" src="https://qiita-image-store.s3.amazonaws.com/0/323324/76bfa19d-2ca1-d593-92a0-a771a81ca20d.png">

背景が黒なのでわかりづらいですが、インデントの空白の部分に文字数の分だけ点があるのと、終了タグの後ろに改行を表すマークが出てます。

これにより、インデントの空白がわかりやすくなるので、「不可視文字を表示」の設定で使っていこうと思います。

今、受けているUdemyのレッスンは281パートまであり、まだまだ先は長いですが、一歩ずつ確実に進んでいきたいと思います。

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

おわり
Androidアプリの GPGSはストア経由じゃないと動作しない？

# 環境
Unity2018.2.17f1
GooglePlayGamesPlugin-0.9.61

# はじめに
GPGS(GooglePlayGamesServices)の機能でリーダーボード(ランキング)を実装しようと
いろいろと調べて作成しました。

主にこちらのブログを参考にして
https://indie-du.com/entry/2017/02/13/070000

認証つまずくも、試行錯誤の末できたはずが・・
apkを作成して、端末にインストール

```
Social.ShowLeaderboardUI();
```

でリーダーボードが表示された。
おお！
では、スコアを登録

```
Social.ReportScore(mScore, nLeaderboard[mPlayMode], (bool success) => {
       // handle success or failure
       isFinished = true;
       if (!success){
           isError = true;
       }
});

```
できたようだ。

再び、スコアボードの表示を行うと、対象のボードを表示するとエラーが

<b>Playゲームで問題が発生しました</b>
のエラーが表示されてランキング表示されない。
スコアを登録するとこの現象が発生し、未登録の場合は

このゲームではまだハイスコアが公開されていません。

のメッセージ・・

調査した結果
Unityや、adb.exe 経由でinstallしたアプリだと、GPGSの動作に影響がでるようで意図した動作にならなかった。
logcat で確認したところ、それっぽい警告が出ていたのですが、保存してなかったのと
再現ができなくてちょっと確信がもてないけど・・

ストア経由で同じapkを入れたところ問題なく動作ができた。

エビデンスがちゃんと取れていないので、個人的な備忘録です。

# 追記

https://qiita.com/ukn/items/3ae4af0aefb3eeac0214

こちらで書かれている現象のようでした。

# さらに追記

https://cloud.google.com/docs/authentication/api-keys?hl=ja&visit_id=636951691606170376-4146174355&rd=1

本番環境では、APIキーに制限がついていないと動作しないようです。
ある特定のタイミングから厳密になったのか、公開後しばらくは動作していたので問題無いと思っていました。
これが原因とは・・
APIに、Androidアプリのみの制限をつけて
パッケージ名と、SHA-1 署名証明書フィンガープリントを追加したことろ
リーダーボードと実績の表示、GPGSのサインインが動作しました。
SlackでDMを使わない方がいい理由をGIFにして説明してみた

# 概要
最近「DMは業務効率をさげるのでよくない。パブリックチャンネルで会話しよう」というのをよく聞きます。
そこで、なぜDMを使用しないほうがいいのか、具体例をGIFにしてまとめてみました。
※DM=ダイレクトメッセージ
※ここでいうDMとは、1対1のことを指しています

# 1. 前提条件
誤解を招かないよう、先に前提条件を2つ挙げておきます。
この前提条件の中で、DMを使わなくても仕事は回ると考えています。

## 1.1. 全くDMを使うなと言っているわけではない
業務上、どうしてもDMを使わざるを得ないことはあると思います。例えば、個人情報/採用情報/パスワード等のシークレットな情報を含むやり取りなど。
また、サシで飲み行きたいときにDMをすることもありますよね（笑）
こういったやりとりはDMでもいいと思います。

## 1.2. DMってオフィスで対面で話したり、音声通話で話すのと同じでは？
もしかしたらこういったご意見もいただくかもしれないので、あえて2つめの前提条件として挙げておきます。
私のいうDMとはあくまでもテキストベースでのコミュニケーションについて、です。
直接の対話や通話に関しては、そのほうがやりとりが早く済む場合もあるのでいいと思います。しいて言うのであれば、対面でやりとりした内容もwikiなどにまとめて皆に共有できるといいですね。

# 2. 本題
では、なぜDMをすると業務効率が悪くなるのかを、いくつかのパターンに分けてGIFを用いて説明をしていきます。
と言ってもGIFなので、ほとんどQiita上に文字は記載されていません笑
GIFの黒い画面が始まりと終わりの境目を表しています。
ケース1つに対して、DMバージョンとChannelバージョンが1ずつあります。DMバージョンだとこういう問題が発生するが、Channelバージョンだと問題が発生しにくいよっと言った感じで、流れています。

## 2.1. 同じような質問による受け手側の疲弊
### DMの場合
![1dm.gif](https://qiita-image-store.s3.amazonaws.com/0/104056/3bd71451-f75d-03ef-5543-de1797dbf435.gif)

### Channelの場合
![1channel.gif](https://qiita-image-store.s3.amazonaws.com/0/104056/4cf07f45-03ec-593c-c7ea-8e2429cb7cc0.gif)

## 2.2. 手戻り
※GIF上に出てくる「出戻り」は「手戻り」の間違いです

### DMの場合
![2dm.gif](https://qiita-image-store.s3.amazonaws.com/0/104056/16e9a861-270f-a92c-610d-a11c55d0ec18.gif)

### Channelの場合
![2channel.gif](https://qiita-image-store.s3.amazonaws.com/0/104056/afeb87c5-1aa9-34f5-4ad7-ac450754271e.gif)

## 2.3. 作業が止まる
### DMの場合
![3dm.gif](https://qiita-image-store.s3.amazonaws.com/0/104056/9e1c4ee7-5034-00df-b3b7-756cf8aee63a.gif)

### Channelの場合
![3channel.gif](https://qiita-image-store.s3.amazonaws.com/0/104056/c54d9ec7-89e9-b60d-4b3c-5e6ff4c20abd.gif)

## 2.4. 別々の回答
### DMの場合
![4dm.gif](https://qiita-image-store.s3.amazonaws.com/0/104056/e2629a1f-a1b4-c51c-d346-0b538ac2b824.gif)

### Channelの場合
![4channel.gif](https://qiita-image-store.s3.amazonaws.com/0/104056/24b2aa92-4eff-fceb-c23c-a55f73182427.gif)

## 2.5. DM文化の蔓延
### DMの場合
![5dm.gif](https://qiita-image-store.s3.amazonaws.com/0/104056/f29e2760-b6d2-f401-00dc-f6a939e36986.gif)

### Channelの場合
ここは、Channelを使ってはいませんが、Channelを使うように仕向けましょう、という意味でver Channelとしています。

![5channel.gif](https://qiita-image-store.s3.amazonaws.com/0/104056/57f98323-acd8-6542-04bf-674a7cd128ad.gif)

# 3. まとめ
計5つのケースをGIF形式で説明してみましたが、共感していただける部分はありましたでしょうか。業務効率が下がるからDMはダメって言うだけではやはり説得力にかけると思ったので、この記事を書いてみました。
もちろん、他にもいくつかのケースはあるとは思いますが、上記だけでも想像していただければ十分ではないでしょうか。
Redmineの注記にテンプレートを入れる（手抜き版）


ViewCustomizePluginを使います。

Path pattern: /issues/[0-9]+$
Type: JavaScript

```javascript
$(function(){
  // テンプレートの文言設定
  let template = "１行目：テンプレート付きで注記を入れる\n２行目：改行する";
  template = encodeURIComponent(template);

  // とりあえず上のメニューにだけ追加する
  let elementReference = document.getElementById( "content" ).firstElementChild;

  // Aタグを追加
  let anchor = document.createElement("a");
  anchor.href = location.pathname + "/edit?issue[notes]=" + template;

  let str = document.createTextNode("テンプレート付き注記");
  anchor.appendChild(str);

  elementReference.insertBefore(anchor, elementReference.firstChild);
});
```

こんな感じになります。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/63464/d35d83a9-ebc9-8349-2525-a3384a3eabef.png)

リンククリックで編集
![image.png](https://qiita-image-store.s3.amazonaws.com/0/63464/63593b35-abfd-b7f9-e4a3-092318284541.png)
2.5 コスト関数と勾配降下法について


## コスト関数とは

どのぐらい学習が正確に駅ているかを判断する指標となる。**誤差関数**や狭義ではあるが**目的関数**とも呼ばれる。

## アルゴリズムの評価

下図のようなデータを適当に作って、直線で近似することを想定する。

横軸を$x$(入力値)、縦軸を$y$(出力値)とする。
<img width="825" alt="スクリーンショット 2019-02-28 14.19.58.png" src="https://qiita-image-store.s3.amazonaws.com/0/326888/37d31309-0a5d-98bf-83d7-baa09b34cc07.png">
今回はものすごく単純化するためにユニット数1で1層のADALINEで考える。
<img width="836" alt="IMG_6504.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/326888/d0907231-19f2-8e03-1abc-dbadcf85bba6.jpeg">
$w$を重み、$x$を入力値とすると、そう総入力関数は

$
f(x) = wx 
$

のようにただの実数の積となる(ユニット数1のため)。この$f(x)$とデータの真値$y$を比較すると、
その差(**誤差**)$d$は次のようになる

$
d = |y - f(x)|
$

最小二乗法をここで用いるためこの誤差$d$を二乗し、またサンプル数$n$だけすべて足すと

$
J(w) = \sum_{i = 0}^{n}(y_n-f(x_n))^2
$

この$J(w)$を**コスト関数**といい、予測がどれだけ真値に近いかを示すものになる。$w$が変化すると$f(x_n)$が変化するので、**誤差(誤差平方和)**が大きくなったり小さくなったりする。
通常は上の式に$\frac{1}{2}$をかけて

$
J(w) = \frac{1}{2}\sum_{i = 0}^{n}(y_n-f(x_n))^2
$

とすることが多いらしい。

## 誤差を最小化したい

最終目標はこのコスト関数の値(誤差平方和)を小さくすること

### 例:w=5のとき
```python
df = pd.read_csv('2.5_test.csv',header=None,names=['x', 'y'])
x = df['x']
y = df['y']

def gosagosa(a,b):
    return (a-b)*(a-b)/2

w = 5
fx = w*x
J = 0
for i in range(0,20):
    J += gosagosa(fx[i],y[i])
print("w = {0} : J = {1}".format(w,J))


```
誤差の二乗をすべて足した値Jは

**w = 5 : J = 1653.5**

となった

### wがほかの値のときは?


```python
import numpy as np 
import pandas as pd 
import matplotlib.pyplot as plt 

df = pd.read_csv('2.5_test.csv',header=None,names=['x', 'y'])
x = df['x']
y = df['y']


#誤差の二乗を計算する関数
def gosagosa(a,b):
    return (a-b)*(a-b)/2

# w = 0.0-10.0まで0.1刻みで誤差平方和を計算する
for j in range(0,100):
    w = j/10.0
    fx = w*x
    J = 0
    for i in range(0,20):
        J += gosagosa(fx[i],y[i])
    print("w = {0} : J = {1}".format(w,J))
    plt.plot(w,J,marker="+")


plt.show()

```
<img width="752" alt="スクリーンショット 2019-02-28 17.22.44.png" src="https://qiita-image-store.s3.amazonaws.com/0/326888/5476c1de-6466-2ea8-2f52-746c4a3956d1.png">
誤差の二乗をすべて足した値Jは

**w = 0.0 : J = 22538.5<br>
w = 0.1 : J = 21417.65<br>
w = 0.2 : J = 20325.5<br>
w = 0.3 : J = 19262.05<br>
w = 0.4 : J = 18227.3<br>
w = 0.5 : J = 17221.25<br>
...**

となり、plotしてみると$w = 4$あたりで最小値となるすることがわかる。つまり今回は重み$w = 4$で最高の精度が現れるということが理解できる。
また、関数は二次曲線を描くため、微分で傾きを求めて最小化の方向へ持っていくことができる。
## w = 5
$f(x) = wx$ より、$f(x) = 5x$
<img width="752" alt="スクリーンショット 2019-02-28 17.46.06.png" src="https://qiita-image-store.s3.amazonaws.com/0/326888/e1d90089-4456-31f0-3f8c-937c9960978c.png">
## ｗ = 4
$f(x) = wx$ より、$f(x) = 4x$
<img width="752" alt="スクリーンショット 2019-02-28 17.45.50.png" src="https://qiita-image-store.s3.amazonaws.com/0/326888/807cb239-f2eb-2b4a-4252-4bcb762ee2dc.png">





##
【静的サイト】AWS独自ドメインでhttpsにするやり方

#目的
独自ドメインにてhttpsにする。

#使う機能
ASWの以下サービスを使います。
S3
AWS Certificate Manager(ACM)
CloudFront
Route 53

#前提
S3にてアップ済み。
独自ドメインを取得している。

#やり方
##①AWS Certificate Manager(ACM)にてSSL/TLSの証明書を取得する。
(1)AWSのサービス検索でcmと打ったら出てきます。
(2)ACMの中に入ったら、必ず、リージョンを米国東部（バージニア北部）に変更しましょう。
　かなり重要です。私もここでハマりました。。
(3)パブリック証明書のリクエストを選択して、「証明書のリクエスト」をクリック
(4)ドメイン名の空欄に独自ドメインを入れましょう。
　例）*.example.com
　米印をつけて入れると、ワイルドカードになります。
　「次へ」をクリック
(5)「DNSの検証」を選択して、「確認」をクリックし、「確定とリクエスト」をクリック。
(6)すると、証明書の画面になり、状況が保留になっていると思います。
　　名前のところをクリックすると広がり、「route53でのレコードの作成」があると思いますので、クリックします。
　　route53以外で、独自ドメインを取得された方は、別の方法でレコードを作成する必要があります。
(7）しばらく待つ（長いと１時間以上）と状況が「発行済み」に変わります。

##②CloudFrontの設定をする。
(1)AWSのCloudFrontへアクセスして、「create distribution」をクリックします。
(2)「Get Started」をクリックします。
(3)「Origin Domain Name」の空欄をクリックすると、S3のドメインが上がってくるので、選択します。
(4)Alternate Domain Names(CNAMEs)に独自ドメイン（サブ）を記載します。
　（例）www.example.com
(5)SSL Certificate
 Custom SSL Certificate (example.com)を選択します。
　空欄をクリックすると先ほど登録した証明書が出てくると思いますので、選択します。
　この時、もしリージョンを東京で登録した場合は、出てきません。。
他は全てデフォルトのままで問題ないです。「create distribution」をクリックします。
(6)暫く待ち、Statusが『In Progress』から『Deployed』になれば完了です。

##③route53の設定をする。
サブドメインのレコードセットでtypeAでAlias「yes」ですると、
『Alias Target』には作成したCloudFrontディストリビューションが選択できるようになっているので、
選択します。
これで、完了です。
Validation failed: モデル must existエラー

ユーザーがつぶやきを投稿できるTweetみたいなサイトを作成中

今回やりたいこと
formから投稿（post）を送ってDBに保存（ユーザーに紐づいた）してviewに表示させる

苦戦した内容
投稿するもDBに保存されない

調べた内容
bindinng.pryでparamsが送られているかストロングパラメーターがtrueか調べるも問題はなし

@post.save！と記述すると下記のエラーが出たので検索

ActiveRecord::RecordInvalid: Validation failed: Genre must exist

要約するとgenreモデルに値が入ってなくてバリデーションで弾かれていたみたい

解決策
optional: trueを記載

```ruby:post.rb
class Post < ApplicationRecord
belongs_to :user
belongs_to :genre, optional: true
end
```

optional: trueとはなにか？

[Railsのbelongs_toに指定できるoptional: trueとは？](https://blog.ryskit.com/entry/2018/01/27/195442)
belongs_toの外部キーのnilを許可するというもの



参考

モデル

```ruby:post.rb
class Post < ApplicationRecord
belongs_to :user
belongs_to :genre
end
```

```ruby:user.rb
class User < ApplicationRecord
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable
  # validates :username, presence: true
  has_many :posts, dependent: :destroy
end
```

```ruby:genre.rb
class Genre < ApplicationRecord
has_many :posts
end
```

コントローラー

```ruby:posts_controller.rb
class PostsController < ApplicationController

# before_action :authenticated_user!

  def title

  end

  def index
    @post = Post.all
  end

  def new
    @post = Post.new
    # binding.pry
  end

 def show
  @post = Post.limit(6)
 end

def create
  @post = Post.new(posts_params)
  @post.save
  binding.pry
  redirect_to posts_path(@post)

end

def edit
 @post = Post.find(params[:id])
end


def update
  post = Post.find(params[:id])
  post.update(text: posts_params[:text])
 redirect_to action: "index"
end

def destroy
  post = Post.find(params[:id])
  post.destroy
  redirect_to action: "index"
end

  private
    def posts_params
      # binding.pry
    params.require(:post).permit(:text).merge(user_id: current_user.id)
  end

end


end
```
ラズパイにWindows 

# 背景
Rasberry Pi 3 B+にWindows IoTを入れた記憶。

# その0. まずやっちゃダメなやつ。

##やっちゃダメな奴。

### その0の1. NOOBSインスト－ラを用意する
https://www.raspberrypi.org/downloads/noobs/
-> 今のWindowsでは使えません

### その0の2. 「Windows 10 IoT Core Dashboard」をデフォで使う
https://docs.microsoft.com/ja-jp/windows/iot-core/downloads
から「Windows 10 IoT Core Dashboard」をダウンロードしてWindows 10にインストールしてそのまま使う
-> B+では使えないというかSDカードをNTFSでフォーマットして読めなくします。

# 概要。

## Windows Insider Programに参加します。Webから。
## Additional Insider Preview downloadsからRaspberryPi 3B+ Technical Preview Build 17661 をダウンロードしてイメージと見せかけつつインストーラを走らせ展開されたファイルを使います。
## 展開したファイルをWindows 10 IoT Core Dashboardで指定してインストールします…まじか。

# その1. SDにパーティションを用意

SDが何に使われてたかわからないし、フォーマットによってはMBRの書き換えがうまくない…という事で下記を適宜実施。

## 1. 「スタート」メニューのサーチボックスで、diskpartと入力して、Enter。

## 2. ディスク一覧表示。 list disk 
## 3. ディスク選択 select disk X (Xは数字)
## 4 パーティション一覧表示 list partition
## 5. パーティション選択 select partition Y (Yは数字)
## 6 選択したパーティションの削除 delete partition
## 7. 5.～6.の繰り返して不要なパーティションが消えるまで。
## 8. clean
## 9. convert gpt
## 10. create partition primary
## 11. format fs=fat32 すごく気長に待つ。
## 12. assign
## 13. exit

# その2. SDのパーティションをフォーマットする。

Windows付属のフォーマットじゃダメみたい。下記にアクセスしてダウンロード。ダウンロードするのはSD Foundationのアプリで怪しくないです。・
https://www.sdcard.org/downloads/formatter_4/eula_windows/

SD Card Formatter
起動して "上書き" フォーマット 。
すごく気長に待ちます。

# その3. Windows IoT バイナリダウンロード

https://www.microsoft.com/en-us/software-download/windowsiot
Additional Insider Preview downloads
RaspberryPi 3B+ Technical Preview Build 17661 
選びます。

ダウンロードしたら、Win10の機能であるExplorerの管理->ディスクイメージツールでマウント、すると.msiが現れるのでインストール。

終わると、
C:\Program Files (x86)\Microsoft IoT\FFU\RaspberryPi2
に「flash.ff」ができる筈、で
ファイルの存在を確認。

# その4 OSインストール

https://docs.microsoft.com/ja-jp/windows/iot-core/downloads
から「Windows 10 IoT Core Dashboard」をダウンロードしてWindows 10にインストール

IoT Dashboardが起動するので、
「新しい」デバイスのセットアップ」ぽち。

Microsoftアカウントでサインイン。

Broadcomm [Rasberry Pi 2&3]
Custom
C:\Program Files (x86)\Microsoft IoT\FFU\RaspberryPi2
を指定。

同意して「ダウンロードとインストール」ぽち。
Provided bucket:""does not match the Storage bucket of the current instance:""


#StorageInstance
firebaseを導入する際に`FirebaseApp.configure()`メソッドでインスタンス化されるバケット名はfirebaseProjectのstorageで初めに取得されるバケットになる。ここからバケットのlocationなやバケット名を変更したい場合は別のstorageバケットを作成する必要があり、新しいバケットをインスタンス化しようとしたら`Provided bucket:""does not match the Storage bucket of the current instance:""`というエラーが。インスタンスはAPIによってデフォルトのバケットで必ず行われるらしいので。`storage()`を変更するとうまくいく。
#記述

```swift
let storageRef = Storage.storage(url: "bucketName").reference()
```

#最後に
エラー吐き出し口がこんな感じで、デフォルトがない場合storageクラスがstandardになってるものがインスタンス化される、クラスはgoogleCloudで簡単に変更可能。

```swift:FIRStorage.m
+ (instancetype)storageForApp:(FIRApp *)app {
  if (app.options.storageBucket) {
    NSString *url = [app.options.storageBucket isEqualToString:@""]
                        ? @""
                        : [@"gs://" stringByAppendingString:app.options.storageBucket];
    return [self storageForApp:app URL:url];
  } else {
    NSString *const kAppNotConfiguredMessage =
        @"No default Storage bucket found. Did you configure Firebase Storage properly?";
    [NSException raise:NSInvalidArgumentException format:kAppNotConfiguredMessage];
    return nil;
  }
}
```
RailsのMVCってなに？ 

フレームワークの構造についてメモ｡

Railsに限らず他のフレームワークも､MVCの構造になっています｡
この仕組を少し理解してからのほうが､一連の流れを理解しやすいかと思います｡

M:Model
V:View
C:Controller

---

- M データベースからデータを引っ張ってきます｡
- V  pe+tab で <%=  >が補完｡これを使うことでHTMLをブラウザに表示させることが出来ます｡  
 つまり ERB {enbedded(埋め込み) Ruby} 出来ます｡ファイル拡張子も .erb になってることが多いですが､ERBと繋がりますね！
- C 管制！というイメージです｡MとVに指示を出します｡



下記サイトがとても噛み砕いて説明してあり分かりやすかったです｡
(参考https://www.yuta-u.com/programing/rails_mvc)