OmniAICreator/Qiita-1.07M huggingface dataset:
【VSCode・MacOS Catalina】Can not add index to parent of type array

ショートカットキーを打つとタイトルのようなエラーが発生する。

VSCodeの、コードの補完情報(snippet)を格納しているディレクトリを削除した後、再起動をかけることで直った。

```bash
$ rm -rf ~/Library/Application\ Support/Code
```

ちなみに中国語のブログから解決策を見つけてきた。

- https://blog.csdn.net/weixin_45761659/article/details/105452270
- http://blog.sina.com.cn/s/blog_15ab3a6e00102yecz.html
- https://github.com/microsoft/vscode/issues/103943
- https://qiita.com/y-vectorfield/items/f9df044981ef29083318


======2020.12.16追記======

↓もしかするとこれでもいけた？

```
$ code --disable-extensions
$ code --verbose
```

この後VSCodeをリロード。
CircleCIでGolangのテストカバレッジを確認できるようにする

[GameWith Advent Calendar 2020](https://qiita.com/advent-calendar/2020/gamewith) の記事になります！

# 概要
CircleCIでGolangのテストカバレッジを簡易的に確認できるようにします。
Golang純正のテスト機能とカバレッジ出力機能を利用して、CircleCIのArtifactsに保存して見れるようにします。

# 設定
**※通常CIに入れるような処理は省いて、テストカバレッジを保持する部分のみを記載します。**

## Makefileでのコマンド設定

```bash:Makefile
# テストを行い、テストカバレッジレポートファイルを出力する
test-coverage:
	@if [ ! -e ./coverage ]; then mkdir ./coverage; fi
	@go test -v -coverprofile=./coverage/gotest.profile ./... 2>&1 | tee ./coverage/gotest.log
	@go tool cover -html=./coverage/gotest.profile -o ./coverage/index.html
```

## gitignoreでテストカバレッジレポートフォルダを無視する

以下の設定を追加します。

```:.gitignore
coverage/*
```

## CircleCIのJobに組み込む

以下のようなCircleCIのjobを作成し(ビルドやリントなどのついでに実施でも良い)、

```yaml:.circleci/config.yml
jobs:
  test-coverage:
    executor: default
    steps:
      - checkout
　　　 # テストを行いカバレッジレポートファイルを出力します
      - run:
          name: make test coverage file
          command: make test-coverage
      # レポートファイルを Artifacts として保持させます
      - store_artifacts:
          path: coverage
      - store_test_results:
          path: coverage
```

# 結果

CircleCIのワークフローのページから、テストカバレッジレポートファイルをArtifactsに保存したJobを開き、
「ARTIFACTS」タブから、 `coverage/index.html` をクリックすると、カバレッジレポートを見ることができます。

![スクリーンショット 2020-12-14 12.55.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44933/a95cae41-8720-f069-59de-37334f556366.png)

1ファイルずつセレクトボックスから選択して、カバレッジが何%かどうかや、実際のコードからテストが通っていない箇所が赤く表示され確認できます。

![スクリーンショット 2020-12-14 12.57.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44933/5740b7c5-56d0-93d2-2456-46e8f081525c.png)
freebsd-updateにミスった話（手順ミス）

FreeBSD12.2がリリースされたので下記の手順FreeBSDで構築したサーバを更新してました

```
$ sudo freebsd-update upgrade -r 12.2-RELEASE
$ sudo freebsd-update install
$ sudo reboot
$ sudo freebsd-update install
# 更新系ファイルを削除（更新に必須ではない。ただの容量節約）
$ sudo rm -rf /var/db/freebsd-update/files
```

更新するサーバは複数台あったのでパラレルで手作業してたところ、
そのうちの1台のサーバで手順をミスり1回目の```sudo freebsd-update install```を行った後に
```sudo rm -rf /var/db/freebsd-update/files```を行ってしまいました。

あせって下記のrollbackやfetchなどを再実行しても、手遅れでどうしようもない状態になってしまいました。
(更新系ファイルを消してしまったので当然ですが...）

```
$ sudo freebsd-update rollback
$ sudo freebsd-update fetch
$ sudo freebsd-update upgrade -r 12.2-RELEASE
```

結果的にカーネルが12.2でユーザランドが12.1の状態になってしまいました。
この状態でもサーバで使用していたプログラムは動きましたが気持ち悪いので、
サーバごと削除し他VMからコピーして復旧しました。

もし、他VMからコピーできるような状況ではなかったらどうしようかなと考えていたら、
freebsd-updateのマニュアルに```--currently-running```というオプションがあるのを発見。
下記のコマンドを実行すればさきほどの状況でも更新できたかもしれません。
機会があったらやってみようと思います。

```
$ sudo freebsd-update upgrade -r 12.2-RELEASE --currently-running 12.1-RELEASE
```
Unity ShaderGraph レシピ #4 水玉模様

#水玉模様（ドット柄）
![スクリーンショット 2020-12-11 1.55.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198311/535a239b-b16b-7ec3-ca3d-6bb584b3a4a8.png)


#作り方
水玉模様はマル○の形のテクスチャを任意の回数繰り返して作成します。

### 1.RoundedRectangle
マルを作るにはRoundedRectangleノードを使います。
RoundRectangleノードは丸角の四角形を作るノードですが係数を1にすることできれいな円形になります。
![スクリーンショット 2020-12-11 1.40.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198311/37949012-64e7-56a4-5050-5393d258e06c.png)

![スクリーンショット 2020-12-11 1.40.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198311/fc556d05-d561-7f30-9239-e846120595fb.png)

### 2.TilingAndOffset & Fraction

○型のテクスチャができたので、あとはTilingAndOffsetノードとFractionノードでUVの繰り返しを作ってRoundedRectangleノードのUV値とします。
![スクリーンショット 2020-12-11 1.51.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198311/b94dea09-6d60-d816-f135-898fa544bf54.png)

TilingAndOffsetノードのTilingの値が繰り返し回数（水玉の縦横方向の個数）になります。

### 3. Color & Multiply
最後に水玉の色を決定します。
Colorノードで指定した色を水玉テクスチャと掛け合わせることで白い部分に色を乗せます。
![スクリーンショット 2020-12-11 2.03.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198311/77c5b3cc-3e7d-94d4-754e-185d865880a0.png)

###完成！
![スクリーンショット 2020-12-11 1.55.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198311/535a239b-b16b-7ec3-ca3d-6bb584b3a4a8.png)

---
その他のレシピは[ShaderGraphレシピ一覧](https://qiita.com/Teppy/items/73fc6141751a62f5265d)にまとまっています
anacondaでyamlファイルから仮想環境が作れない場合の対処法

## 環境
- macOS Catalina
- MacBook Pro (13-inch, 2018)

## エラー内容

```shell
$ conda env export > env.yml
$ conda env create --file env.yaml

Collecting package metadata (repodata.json): done
Solving environment: failed

ResolvePackageNotFound: 
  - ipykernel==5.3.4=py37h888b3d9_1
  ...
  ...
```

## 解決策

```shell
$ conda env export --no-builds > env.yml
$ conda env create --file env.yaml
```




## 参考

- https://github.com/ContinuumIO/anaconda-issues/issues/9480#issuecomment-601130732
【C#】Reflection_Methodの取得方法

.netでは開発したモジュールを参照することで、他の応用プログラムに含まれている関数を使うことが可能です。
しかし、参照するモジュールが何だかの理由で、参照できない場合があります。その時はreflectionを使い、使用したい関数をモジュールから持ってくることが可能です。

```
string modulePath = String.Format(@"{0}\TestModule.exe", "D:\Project\bin" );

if(File.Exists(modulePath) == true)
{
    Assembly assy = Assembly.LoadFile(modulePath);
    Type type = assy.GetType("TestModule"); //Class name
    
    if(type != null)
    {
        MethodInfo method = type.GetMethod("TestMethod", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
　　　　　
　　　　 //関数実行
        if (method != null)
        {
            method.Invoke(null, new object[] { param1, param2 });
        }
    }
}

```

※reflectionはカプセル化を反しますので、できるだけ使用を制限してください。
【備忘録】Swift 実践入門について　第11章

Swift 実践入門のまとめ。
分からない部分の抜粋も記載し、解決できたら随時更新していきます。
なお、ここに記載している以外でも「わけわからん…」となっている部分も多々ありますが、
今は必要ない、と言い聞かせて飛ばしています。

第11章
モジュール　作成したプログラムを別のプログラムでも使えるもの
理解度：50％くらいか


要は部品。その部品単体でも機能するし、他のモジュール(部品)と組み合わせて使うこともできる。
モジュールにアクセスできるレベル設定や、そのモジュールの中身をぱっと見て取れる
モジュールヘッダなどもある。

11-2
Package()というPackage型の引数にdependenciesを記述する。
let package = Package(name : “Example”, dependencies : [～])
AWS batchでdocker loginしてジョブを実行する方法

# 背景
「そんなのECRにイメージおけばいいじゃない？」なんですが、すでにDockerHubでレポジトリを管理するように全体設計してしまった私のような人がいると思ったので。
もしくは、自前でdockerレポジトリを管理している人がいるのだろうと思い。

# 前提条件
・DockerHubなりの認証が必要な場所にdockerのイメージが登録されている
・EC2でAmazon Linuxのインスタンスが起動している
・AWSのbatchを使ってジョブが起動出来る

# 手順
## EC2のインスタンスでECSの要件を満たす

batchから起動できるAMIには下記の必要条件（[マニュアルはこちら](https://docs.aws.amazon.com/batch/latest/userguide/compute_resource_AMIs.html#batch-ami-spec)）を満たしている必要があります。

 * ECSコンテナエージェントが起動していること
 * CloudWatchにログが出力できること
 * dockerが使えること

なので、起動しているEC2インスタンスにsshでアクセスして作業します。

```Bash
$ ssh -i ec2.key ec2-user@[EC2のIPアドレス]
# ECSコンテナエージェントをインストールします。
$ sudo amazon-linux-extras install -y ecs; sudo systemctl enable --now ecs
#dockerをインストールします。
$ yum install -y docker
```

これで要件をみたしました。

## DockerHubの認証をしたAMIを作成する

次にDockerHubの認証をして、batchで起動した時にその認証情報が使えるようにします。

```Bash
# DockerHubにログイン
$ docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don’t have a Docker ID, head over to https://hub.docker.com to create one.
Username: xxxxxxxxx
Password:
Login Succeeded
```

ログインをすると、「~/.docker/config.json」に下記のようなログイン情報が生成されます。
下記はDockerHubにログインした場合です。
（[他のレポジトリや複数のレポジトリを使う場合の記述方法](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/private-auth-container-instances.html#docker-auth-formats)）

```
{
  "auths": {
    "https://index.docker.io/v1/": {
      "auth": "zq212MzEXAMPLE7o6T25Dk0i"
    }
  }
}
```

これを下記のようにbatchがEC2を起動させる時に読み込む設定ファイルに記述します。

```bash
$ sudo vi /etc/ecs/ecs.config
# 下記を記入
ECS_ENGINE_AUTH_TYPE=dockercfg
ECS_ENGINE_AUTH_DATA={"https://index.docker.io/v1/":{"auth":"zq212MzEXAMPLE7o6T25Dk0i","email":"email@example.com"}}
```

ここまで出来たらEC2のコンソール画面から設定をしたEC2にチェックを入れて「アクション」→「イメージとテンプレート」→「イメージを作成」と選択し、イメージ名を指定してAMIを作成します。

## AMIを指定してジョブの登録

AMIの登録が完了したらAMIを使ってジョブを起動できるようにします。
まずはAWS Batchのコンソール画面で「コンピューティング環境」→「作成」と進みます。
そして、画面下の「追加設定：テンプレート、ユーザ指定のAMIを起動」を開いて、「ユーザ指定のAMI ID」の「有効化」にチェックを入れます。
すると、下記画像のようにAMI IDを入力するテキストボックスが表示されるので、先ほど登録したAMIのIDを貼り付けます。

![スクリーンショット 2020-12-14 12.47.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/118515/375cab8b-fab9-d023-3826-303312dd1dfb.png)

その他の必要項目を設定したら、「コンピューティング環境の作成」をクリックし、コンピューティング環境を登録します。
次に「ジョブキュー」→「作成」と進んで先ほど登録したコンピューティング環境を使ったジョブキューを登録します。

![スクリーンショット 2020-12-14 12.53.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/118515/4b3f2b0a-f72e-2a29-d0e3-ac082a0a39b7.png)

必須項目を入力して「作成」をクリックし、ジョブキューの登録は完了です。
最後に、ジョブ定義で利用したいプライベートレポジトリのイメージを指定します。

![スクリーンショット 2020-12-14 12.56.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/118515/6b78ffb0-33f5-a035-6157-745fc9c40831.png)

必須項目を入力して「作成」をクリックし、ジョブ定義の登録も完了です。

あとはジョブキューとジョブ定義を使って新たにジョブを登録すれば、プライベートレポジトリのイメージを使ったdockerコンテナでジョブ定義のコマンドを実施できます。


# 参考URL
https://docs.aws.amazon.com/batch/latest/userguide/compute_resource_AMIs.html#batch-ami-spec
https://docs.aws.amazon.com/AmazonECS/latest/developerguide/private-auth-container-instances.html#docker-auth-formats
https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-agent-config.html
複数の表が含まれている Excel シートから表を取り出す

　これは[ちゅらデータアドベントカレンダー](https://qiita.com/advent-calendar/2020/churadata) 14日目の記事です。[6日目](https://qiita.com/kueda_cs/items/4592cc064c6ef97835c5)ではゴリゴリ数学の記事だったので、軽いものを書きます。

　以下のように、Excel ファイルに複数の表が含まれている場合にひとつひとつ表を切り出す関数を書いたのでメモしておきます。パワータイプの実装なのであんまし綺麗じゃないかもですが、ご参考までに。
![表.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679145/ee83a34b-4519-03e6-1093-3bbd3f31799c.png)

```python
def cut_sheet(df, s, search_column=False):
    """
    シートから特定の文字列で始まる表を取得
    :param DataFrame df: 複数の表を含んだデータフレーム
    :param str s: 表の左上端に位置する文字列
    :param bool search_column: s が column 行にあるか
    :return DataFrame df_cut: 切り取った表のデータフレーム
    """
    # s のいる位置を特定
    stacked_df = df.stack()
    location = stacked_df[stacked_df == s].index.to_list()[0]
    # s を左上端とした表を切り出す
    start_index = df.index.to_list().index(location[0]) + 1 -int(search_column)
    start_column = df.columns.to_list().index(location[1])
    df_cut_ = df.iloc[start_index+1:, start_column:].reset_index(drop=True)
    columns = df.iloc[start_index, start_column:]
    if (columns[0] != columns[0]):
        columns[0] = s
    df_cut_.columns = [
        int(column)
        if ((type(column) is float) & (column == column))
        else column
        for column
        in columns
    ]
    df_cut_.set_index(columns[0], inplace=True)

    # 行の終わりを探す
    exists_indexes = df_cut_.iloc[:,0].isna().to_list()
    if (True in exists_indexes):
        end_index = exists_indexes.index(True)
    # 下端に達する表については下端を終端とする
    else:
        end_index = len(exists_indexes)

    # 列の終わりを探す
    use_columns = [column for column in df_cut_.columns if column == column]
    df_cut = df_cut_.iloc[:int(end_index), :][use_columns]

    return df_cut
```

　少々強引ですが、これで表が取り出せます。

```python
cut_sheet(sheet, '表1', search_column=False)
```

![スクリーンショット 2020-12-14 13.55.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679145/2b1d9188-d31f-03f1-35af-a8acb8058211.png)


```python
cut_sheet(sheet, '表3', search_column=True)
```

![スクリーンショット 2020-12-14 13.53.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679145/cb11d87c-74b0-f881-3a64-ec9737a8082e.png)


　やったね。
GitHubダークモード対応と拡張機能3選


# はじめに
GitHubがDarkModeに対応したというニュースを見かけました(2020/12/08)

https://github.blog/2020-12-08-new-from-universe-2020-dark-mode-github-sponsors-for-companies-and-more/

いままでは、Chromeの拡張をいれるとダークモードにできるものはあったかと思います。

Chromeウェブストア - GitHub Dark Theme

https://chrome.google.com/webstore/detail/github-dark-theme/odkdlljoangmamjilkamahebpkgpeacp

今回、GitHub公式でテーマを決定できるようになりました。

## GitHubダークモードの設定

- 右上のユーザアイコン → Settings → Appearance → Theme (Newという表示でBetaとなっています)

![git1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167772/ef506919-9732-0464-11f0-f553e630a31e.png)

## GitHub関連の便利拡張機能3選

GitHub関連の拡張機能はたくさんあるかと思いますが、これは必須というものを3選でご紹介です。

### ①GitHub Code Tree

GitHubのファイルをツリー表示することが可能。これなしでは操作がキツイです。とても便利な必須機能だと思うので、公式になるのかなぁと思ったりします。

Chromeウェブストア

https://chrome.google.com/webstore/detail/octotree-github-code-tree/bkhaagjahfmjljalopjnoealnfndnagc

![git2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167772/2cce59d7-41dc-f713-4a09-acf46b04f6e9.png)

### ②File Icons for GitHub and GitLab

VS Codeでもそうですが、アイコンがカラフルだと見易さが格段にあがると思います。

Chromeウェブストア

https://chrome.google.com/webstore/detail/file-icons-for-github-and/ficfmibkjjnpogdcfhfokmihanoldbfe

![git3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167772/b2af94c0-f706-4961-2ffd-3b4275e0f0e5.png)

### ③Gitpod - Dev Environments in a Browser Tab

Gitpodを使用している場合は、この拡張は必須かと思います。

Chromeウェブストア

https://chrome.google.com/webstore/detail/gitpod-dev-environments-i/dodmmooeoklaejobgleioelladacbeki

![git4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167772/f826ddcb-3c7e-41ea-9010-fef4275d3469.png)

## おまけ：Windows TerminalにGitBashを追加する

Windowsを使用している場合は、Window terminalにGitBashを追加するととても便利です。
設定方法は、以下のURLを参照すると、文字化けにも対応できます（感謝）

参考URL：Windows Terminal で Git Bash を表示する

https://qiita.com/yokra9/items/bdd0882268b308cf22ca

![git5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167772/d39da987-7641-6b8f-464d-6c6aee80976b.png)
MacにHomebrewをインストールしていくつかパッケージを入れる

# Homebrewをインストールする準備
## Command Line Tools for Xcode

====== 2022/12/15 追記 ======
M2 MBA macOS Ventura 13.0
iterm2を初回起動したら，command line toosのインストールが促されて，クリックしたらインストールされた
====== ====== ====== ======



Homebrewのインストールには`Command Line Tools for Xcode`が必要．インストールする方法はいくつかある．

1. gitなどの`Command Line Tools for Xcode`に入ってるコマンドを実行しようとすると自動的にインストールを促される．
2. Appleのウェブサイトからダウンロード
3. Xcode（容量大きい）をApp Storeからインストール
4. 下記コマンドでインストール

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

## Rosetta2を利用

====== 2022/12/16 追記 ======
もうrosettaで入れなくても良さそう
====== ====== ====== ======

現在（2020年12月）のところ，Armで動くHomebrewは公開されているもののまだ非推奨．まだArmに対応していないパケージなども色々あるので，当面はRosetta2を利用して今までと同じインテル用のものをインストールする．

Finderでアプリケーションディレクトリを開き，利用するターミナルアプリを右クリックして`情報を見る`．`Rosettaを使用して開く`にチェックを入れておく．

その後ターミナルを起動するとRosetta2を使用した状態になる．ターミナルを開いて`uname -m`と打ち込んで`x86_64`と表示されればOK．

``` zsh
$ uname -m
x86_64
```


# Homebrewのインストール
ターミナルから下記コマンドを実行するだけ．
 
```
$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
```

ターミナルを新しく起動し直すとpathが自動的に通っているはず．

====== 2022/12/16 追記 ======
Arm版ではpathの設定が必要．インストールが終わると
```
==> Next steps:
- Run these three commands in your terminal to add Homebrew to your PATH:
    echo '# Set PATH, MANPATH, etc., for Homebrew.' >> /Users/yamashita06/.zprofile
    echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> /Users/yamashita06/.zprofile
    eval "$(/opt/homebrew/bin/brew shellenv)"

```
と表示されるので，上記3つを実行するだけ
====== ====== ====== ======


# zshのエラー
Homebrewを入れたらターミナルを起動したログイン時に下記のエラーが出るようになった．

```
zsh compinit: insecure directories, run compaudit for list.
Ignore insecure directories and continue [y] or abort compinit [n]?
```
セキュアじゃないディレクトリがあるらしい．言われた通りに`compaudit`コマンドを実行してみる．

``` zsh
$ compaudit
There are insecure directories:
/usr/local/share/zsh/site-functions
/usr/local/share/zsh
```

ググってみるとここに解決方法が載っていた．
[macでzshでzsh compinit: insecure directoriesの警告が出る問題](https://qiita.com/ayihis@github/items/88f627b2566d6341a741)

上記二つのディレクトリにおいて，自分以外のユーザーも書き込み権限を持ってるのが原因らしい．パーミッションを変更しておく．


# Homebrewを入れたらインストールしておくパッケージ
自分のためのメモ．

- aspell
- cmigemo
- coreutils
- emacs-mac
  + [EmacsをHomebrewでインストールしてMac特有の設定をする](https://qiita.com/TomokiYamashit3/items/915e270b20f9b4e4a1d0)
- imagemagick
- gcc
  + gccを入れるとgfortranも入る
- ghostscript
- git
  + Command Line Toolsのgitはややバージョンが古いのでHomebrewを使う
  + [Git Credential ManagerでGitHubの認証情報をキャッシュする](https://qiita.com/TomokiYamashit3/items/8124534b052f164cc6cb)
- go
- hugo
- peco
- python3
  + python 3.9.1 がインストールされた（2020年12月）
- ricty
  + リポジトリをtapする必要がある．下記参照．
- ripgrep
- ~~rmtrash~~
  + 最近Homebrewから外されてインストールできない（2020年12月）
- trash
  + [Macでrmtrashの代替とLinuxでのrmの置き換え](https://qiita.com/TomokiYamashit3/items/d0e0fbbc736400e0aa39)
- tree
- wget

## Ricty
プログラミングに最適なフォントRictyのインストール

``` zsh
$ brew tap sanemat/font
$ brew install ricty
```

インストールすると最後の方に，

```
To install Ricty:
  $ cp -f /usr/local/opt/ricty/share/fonts/Ricty*.ttf ~/Library/Fonts/
  $ fc-cache -vf
```
と表示されるので，言われた通りにやるとインストールできる．

``` zsh
$ cp -f /usr/local/opt/ricty/share/fonts/Ricty*.ttf ~/Library/Fonts/
$ fc-cache -vf
```
rspecエラー : ActionView::Template::Error:undefined method `name' for nil:NilClass


## 現状
specを流すと
「ActionView::Template::Error:undefined method `name' for nil:NilClass」
というエラーが発生する

```ruby:spec
      it 'ユーザー登録ページが表示されること' do
        get new_admin_staff_path
        expect(response.status).to eq 200
        expect(response).to render_template :new
      end
```

```ruby:factrybot

FactoryBot.define do
  factory :user do
    transient do
      person { Gimei.name }
    end
    association :shop
    sequence(:email) { |i| "admin#{i}@example.com" }
    password { 'abc12345' }
    sequence(:name) { |_i| "#{person.last.kanji} #{person.first.kanji}" }
    shop_id { 1 }
  end
end
```

## 結論
factrybotでは、ID==1のカラムを指定していたが、
idはspecを通す度に発行されており、1というIDは存在していなかった。
なので、引っ張り出す情報が分からずにエラーとなっていた。

そのため、情報の取得をID==1に固定するのではなく、
一番最初のIDを取得する記載にすれば解決した。
**→ shop_id { Shop.first.id  }**

```ruby:factrybot

FactoryBot.define do
  factory :user do
    transient do
      person { Gimei.name }
    end
    association :shop
    sequence(:email) { |i| "admin#{i}@example.com" }
    password { 'abc12345' }
    sequence(:name) { |_i| "#{person.last.kanji} #{person.first.kanji}" }
    shop_id { Shop.first.id  }
  end
end
```
BigQueryのbqコマンドをセットアップする。

# 概要
BigQueryを使用するにあたって、便利なcliツール(bq)が提供されているため、
使用します

SDKのセットアップ方法(gcloudコマンドのセットアップ方法)に関しては、
下記の記事に記載してあります。
https://qiita.com/kaitoland/items/9dada468718ad65dd784

# 手順

```
//　認証する
$ gcloud auth login

// プロジェクトの設定をする
gcloud config set project <project>

// デフォルトの設定
bq list
※どれをデフォルトにするか聞かれるので設定
```
BigQuery からのデータを分割して pandas のデータフレームを作成する

# gbq で BigQuery からデータを読み込む

pandas-gbq を用いると、クエリを与えることでデータフレームを直接作成することができます。

```shell:shell
$ pip install pandas pandas-gbq
```

```python:python
import pandas as pd
from pandas.io import gbq

query = "SELECT id, company, name FROM users"
df = pd.read_gbq(query, "project-id")
```

データが少ない間はこれで良いですが、データが増えた時を考えると、メモリの圧迫や、データフレームに処理を加えるときの動作が重くなることが考えられます。

# 1レコードずつ読み込んで、ある程度の大きさでデータフレームに変換する

上記の問題を解決するための関数を書きました。

```shell:shell
$ pip install pandas google-cloud-bigquery
```

```python:python
import pandas as pd
from google.cloud import bigquery

# job: query job
# columns: カラムのリスト
# group: 指定したカラムは、同一値ならば同一データフレームに保存される
def data_frame_iteration(job, columns, group = None):
    chunk = 100000 # 大体のレコード数
    records = []
    last = None

    # レコードを1件ずつ読み込む
    for record in job:
        item = [record[column] for column in columns]

        if group is None:
            if len(records) >= chunk:
                yield pd.DataFrame(records, columns = columns)
                records = []
        else:
            # 指定したカラムの値が変わったタイミングで、レコードが多ければ (chunkの9割) 一旦保存。
            if record[group] != last and len(records) > chunk * 0.9:
                yield pd.DataFrame(records, columns = columns)
                records = []

        records.append(item)

        if group is not None:
            # 指定したカラムの値を保存しておく
            last = record[group]

    # 残りを保存
    if len(records) > 0:
        yield pd.DataFrame(records, columns = columns)
```

## 関数に group 引数を与えない場合

```python
client = bigquery.Client("project-id")
query = "SELECT id, company, name FROM users"
columns = ["id", "columns", "name"]
job = client.query(query)

for df in data_frame_iteration(job, columns):
    pass
```

各 df に、関数内の chunk 数単位で分割されたレコードが入ります。

## 関数に group 引数を与える場合

同一 company は同一データフレームに入れて操作したいという場合は次のようにします。

```python
client = bigquery.Client("project-id")
query = "SELECT id, company, name FROM users ORDER BY company"
columns = ["id", "columns", "name"]
job = client.query(query)

for df in data_frame_iteration(job, columns, "company"):
    pass
```

クエリ側で、グルーピングしたいカラムでソートしてある点に注意してください。
この場合、例えば company の値がともに 1 であるデータは、同一の df に入ります。複数の df にまたがることはありません。
Google Cloud SDKのセットアップ方法

# 概要
GoogleCloudのcliツール(Google Cloud SDK)を使用するためのセットアップ方法になります。
AWS-Cliみたいなものです

# 手順
## 1,ファイルをダウンロードしてきます。
MacOSの方はこちら。
https://cloud.google.com/sdk/docs/quickstart-macos

他のOS(Windows、Linux)の場合はリンク先に飛んで、
左サイドバーのクイックスタートの箇所から選択してください。
![スクリーンショット 2020-12-14 13.37.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320677/f6b9e008-9b16-b06e-8c97-99be3cc7c426.png)


## 2,ダウンロード後のセットアップ

```
//　ダウンロードしたら展開
$ tar -xzvf Downloads/ダウンロードしたファイル -C $HOME

// インストールする
$ sh $HOME/google-cloud-sdk/install.sh

※AttributeError: module 'importlib' has no attribute 'util'
pythonのバージョンを適切にすることで解消できます。
自分は3.7.6でいけました。

// 動作確認 ターミナルを再起動 or source ~/.bash_profile
$ gcloud version
```

これにて、bqコマンドなどの使用をする事ができるようになります。




引用・参考
https://apps-gcp.com/cloud-sdkinstall-commentary/#Python27
CentOS7.9作ってpacemakerを入れる覚書

# 環境

```
# cat /etc/redhat-release
CentOS Linux release 7.3.1611 (Core) 
```

- 最小限インストールした生まれてたての姿。SSH接続できる準備(IPアドレス付与)だけした。
- 作業内で ``yum -y update`` により以下に変わります。

```
# cat /etc/redhat-release
CentOS Linux release 7.9.2009 (Core)
```

# CentOS7.9化まで

```
# nmcli con mod eth0 connection.autoconnect yes ipv4.method manual ipv4.address "xxx.xxx.xxx.xxx/xx" ipv4.dns 8.8.8.8 ipv4.gateway "xxx.xxx.xxx.xxx"

# systemctl restart network

# yum -y update
# yum -y install vim
```

# Pacemakerインストール

```
# curl -s https://setup.ius.io/ | sudo sh
# yum -y install pacemaker
```

``crm_mon``も使えるし大丈夫そう

# crmコマンドインストール

```
# wget http://download.opensuse.org/repositories/network:/ha-clustering:/Stable/CentOS_CentOS-7/network:ha-clustering:Stable.repo
# mv network\:ha-clustering\:Stable.repo /etc/yum.repos.d/crmsh.repo
# yum -y install crmsh
```
JavaScript5,for文,配列,初心者向け

5,配列とfor文をくみあわせる。

```
const weather = ["晴れ", "曇り", "雨", "雷"]
for (let i = 0; i < weather.length; i++) {
  let li = document.createElement("li");
  li.textContent = i;
  document.getElementById("number").appendChild(li);
  console.log(i);
}
```

旧　for (let i = 0; i < 10; i++) {
新　for (let i = 0; i < weather.length; i++) {

○○.length
が ["晴れ", "曇り", "雨", “雷”]の中の数だけ勝手にやってくれる
Pepper SDK入門(20) PepperにSay(API)でsay(発言機会)を与える

![【Pepper】首だけ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/574697/dd99f04d-bf98-d1e0-0229-005491e0de48.png)
また会いましたね。

#今回の目標
Pepperに喋ってもらいます。

```java
//フレーズを決める
Phrase phrase = new Phrase("Hello");

//アクションをビルドする
Say say = SayBuilder.with(qiContext)
                    .withPhrase(phrase)
                    .build();

//アクションを同期実行する
say.run();

```
**これが今回の学習内容です。**
あらかじめ決めておいたフレーズは絶対的です。**アドリブは出来ません。**

#Pepperのために短い台本を用意しよう
Pepperの発言を決めましょう。helloでもhaloでもharrowでもそれ以外でも、なんでも構いません。

```java
Phrase phrase = new Phrase("はろー");
Say say = SayBuilder.with(qiContext)
                    .withPhrase(phrase)
                    .build();

say.run();

```
Phraseを使ってビルドします。


#Pepperは動（きながら喋る）物である
Pepperはジェスチャーしながらお話をします。
その身振り手振りをキープするのも、[BodyLanguageOption](https://android.aldebaran.com/sdk/doc/javadoc/qisdk/com.aldebaran.qi.sdk.object.conversation/-body-language-option/index.html)で止めるのもユーザーの自由です。
後者を選ぶ場合は前回と前々回に倣い、BodyLanguageOption.DISABLEDを使いましょう。

```java
Say say = SayBuilder.with(qiContext)
                    .withPhrase(phrase)
                    .withBodyLanguageOption(BodyLanguageOption.DISABLED)
                    .build();

say.run();
```
#Pepperはトリリンガルである
前回のListenでそうしたように、Localeで使用言語を変更することが出来ます。今回は英語です。It’s a breeze！

```java
Locale locale = new Locale(Language.ENGLISH, Region.UNITED_STATES);
Say say = SayBuilder.with(qiContext)
                    .withPhrase(phrase)
                    .withLocale(locale)
                    .build();

say.run();
```
#Sayの存在意義を体験しよう
例えば気になるカクテル名をタブレットのボタンで選び、それにどんな酒類が混ざっているか教えてくれるようにしてみましょう。

```java
String cocktailName = ...;
String materialDescription = ...;

Phrase namePhrase = new Phrase("今夜は " + cocktailName + "を飲みませんか");
Say sayName = SayBuilder.with(qiContext)
                        .withPhrase(namePhrase)
                        .build();

Phrase descriptionPhrase = new Phrase(materialDescription);
Say sayDescription = SayBuilder.with(qiContext)
                               .withPhrase(descriptionPhrase)
                               .build();

sayName.run();
sayDescription.run();

```

<ins>[これ](https://github.com/aldebaran/qisdk-tutorials/tree/master/app/src/main/java/com/softbankrobotics/qisdktutorials/ui/tutorials)</ins>の"Hello human"のボタン名と台詞を変えればすぐにでも体験できます。
![スクリーンショット 2020-12-14 12.45.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/574697/27c6bc37-5c6b-6bad-3453-e9a8e80d4c0f.png)
飲めなくても知識は持てるのです。


#Sayにおける諸性質
SayもListen同様に短い対話に向いています。
SayやListenを実行している時にChatが機能しないように、ChatやListenを実行している時にSayは機能しないので注意してください。会話するか聞くか喋るかは常に択一なのです。

**[APIドキュメント](https://android.aldebaran.com/sdk/doc/javadoc/qisdk/com.aldebaran.qi.sdk.object.conversation/-say/index.html)を見ると、もっとSayを知ることができます。**

#あとがき
今回も[Pepper SDK for Android](https://android.aldebaran.com/sdk/doc/pepper-sdk/ch4_api/conversation/reference/say.html)を参考に書かせていただきました。
DiscussはChatで代用するよう記載されているため、次回はPhraseとPhraseSetについて学習したいと思います。名言や楽句の登場はありません。
それでは次回〜
Pythonのバージョンの切り替え(pyenv)

# 概要
pythonのバージョンの変更に関する記事です。
GCP系のツール(2.7系)など一部のツールはpythonのバージョンが指定されているため、使用時に切り替える必要が出てきます。
今回はpyenvというツールを使用してバージョンを切り替える方法と
anacondaによる方法を紹介します。

# 手順（pyenv編）

```
// pyenvのインストール
$ brew install pyenv

// インストールできるバージョンの参照
$ pyenv install -l

// 欲しいバージョンのインストール
$ pyenv install 2.7.16

// 手元のバージョンの確認
$ pyenv versions

// バージョンの変更　localの場合はlocal グローバルの場合はglobal
$ pyenv local 2.7.16
$ pyenv global 2.7.16
```

バージョンが変更されない場合は、下記で確認して、
anacondaでバージョン管理している場合は次に進んでください。



#手順(anaconda編)
anacondaなどをすでにインストールしている場合は、
参照先が違うため、pyenvではバージョンが変更されません。
conda環境は、プロンプトの頭の部分に表示されます

```
// anacondaの環境作成
conda create -n py27 python=2.7 anaconda

// anacondaの手元の環境確認
conda info -e

// 使用する環境を設定
conda activate py27

// conda環境を抜ける(baseに戻る)
conda deactivate
```

# まとめ
使用感はどれも似ており、
手元にバージョンや環境を作成して使用することになります。


# 引用・参考
本記事の作成にあたって、下記記事を参考にさせていただきました。

Anacondaでpythonのバージョンを使い分ける
https://qiita.com/hurts14/items/116ef0e332e159a51c4f
ｍicro:bitで100均LED電飾クリスマスツリー

子供と一緒にいったCoderDojoで知ったmicro:bit。光ったり、音が出たり、モーターを動かしたりと画面上のプログラミングとはまた違う楽しさがあります。12/12のCoderDojo西尾で作ったMicro:bit＆100均LEDでクリスマスツリーについて書いてみます。（Qiita初投稿です、ドキドキ！）

![IMG_20201214_131537.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670086/d887157c-3bcd-15da-a1e1-143d84616364.jpeg)


#1、準備したもの
ネット検索出見つけた、パソコン工房さんのこの記事を参考に作ってみることにしました。
https://www.pc-koubou.jp/magazine/13713

準備したもの
・PC
・Micro:bitと電池ユニット
・ワニクリップ2本
・点灯型LED電飾（セリアで購入）
・クリアカップ
・油性ペン
・折り紙
・セロテープ

![IMG_20201214_125613.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670086/ca40b6f0-32c9-964e-0d8f-cb6c783fdbcd.jpeg)

#2、プログラミング
micro:bitコードエディターでパソコン工房さんの記事を参考にプログラミングしました。

![スクリーンショット (32).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670086/769463c9-f7af-60b5-fd3b-98239576448b.png)

#3、配線
micro:bitにデータを転送し、LED電飾を配線してみます。
GND端子は電飾のマイナスに、0端子は電飾の＋にワニクリップでつなぎます。

![IMG_20201214_131114.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670086/e69ba802-a032-2bcc-2f68-7eae03c0171d.jpeg)

光りました！電飾の先は油性ペンで色をつけてカラフルにしました。

#4、飾り付け
クリアカップを油性ペンや折り紙を使って飾り付けます。
LED電飾はセロテープで固定。トップのお星様も光るように工夫してみました。

![IMG_20201214_131537.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670086/19701eda-9811-cf24-7219-4f8933fa8cb0.jpeg)

1時間ほどで完成です。
プログラミングは少しなので、小学校低学年から、短時間で楽しめる内容だと思います。
【GANでDNA配列を生成!?】FBGAN(Feedback GAN for DNA optimizes protein functions)

今回は論文読みということでFBGANを紹介します。
研究室の輪読会で読んだ論文です。指定が基本的にnatureのため、機械学習の有名なconferenceのものではありませんが、ご了承ください。
また、以下の資料の記載された画像で引用なきものは下記の論文の画像であることを断っておきます。

<details><summary>コード/論文URL</summary>
<div>

- 著者コード　→　[av1659/fbgan](https://github.com/av1659/fbgan)
- 論文 → [Feedback GAN for DNA optimizes protein functions](https://www.nature.com/articles/s42256-019-0017-4?utm_source=natureasia&utm_medium=referral&utm_content=jp_content&utm_campaign=NJPN_2_KI_natmachintell_feb2019issue)
</div></details>

---
![Dec-14-2020-JC-01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324488/c9449551-2e55-b5d0-a132-5740bfd628e6.png)

---
![Dec-14-2020-JC-02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324488/9fb3fd0f-3589-6fa4-d84a-25382bf2206e.png)

---
![Dec-14-2020-JC-03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324488/232e2d95-3382-faa8-6a2e-c017914bead4.png)

---
![Dec-14-2020-JC-04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324488/3bcb72af-686e-9999-e7db-3b1f53afa529.png)

---
![Dec-14-2020-JC-05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324488/e8d6549f-e1da-ed4b-5768-820ee8a0f16d.png)

---
![Dec-14-2020-JC-06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324488/29d655a7-9852-084a-e345-154e1876f599.png)

---
![Dec-14-2020-JC-07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324488/5e3e9b0b-4e68-fb9f-9d91-e5844ee5447f.png)

---
![Dec-14-2020-JC-08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324488/f979d88a-100b-4173-3110-be83db97936d.png)

---
![Dec-14-2020-JC-09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324488/574ec5d0-ace7-5c86-b88f-ad1ce0d10145.png)

---
![Dec-14-2020-JC-10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324488/fd2b0074-5f7e-0cd2-838a-4511cee78d8d.png)

---
![Dec-14-2020-JC-11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324488/42c94cf0-6e15-617e-f00d-a1525fb7fd3f.png)

---
![Dec-14-2020-JC-12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324488/20c756c4-e25a-7744-69a3-c2b0aba4f9ad.png)

---
![Dec-14-2020-JC-13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324488/b1291ec8-9d92-98b1-7c47-354cd34c1c74.png)

---
![Dec-14-2020-JC-14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324488/dda84129-d557-db68-5290-9e85d320b7a6.png)

---
![Dec-14-2020-JC-15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324488/072cde3a-50a5-2828-1a99-6e56808496ce.png)
Windowsイベントログファイル(EVTX)をwinlogbeatコマンドラインから直接Elasticsearchへ投入してみる

#はじめに
Windowsイベントログファイル(.evtx)をElasticsearchへ直接投入するやり方について説明する機会があったので備忘録（小ネタ）。[Winlogbeat](https://www.elastic.co/jp/beats/winlogbeat)をコマンドラインから実行するだけで簡単。

詳細は[こちら](https://www.elastic.co/guide/en/beats/winlogbeat/current/reading-from-evtx.html)をご参照ください。

#利用するソフトウェア
- OS: Ubuntu 18.04
- Elasticsearch (7.8.1) 
- Kibana (7.8.1)
- Winlogbeat(7.10.1)

#利用するWindowsログファイル
[Windows EVTX Samples](https://github.com/sbousseaden/EVTX-ATTACK-SAMPLES)で配布されている攻撃実行時のWindowsイベントログファイル(SecurityログとSysmonログ)を利用してみます。
※利用時にはライセンスをご確認ください。

#イベント投入用のwinlogbeat設定ファイル

「C:\Users\hoge\Desktop\upload_evtx\upload_evtx.yml」として以下を保存しておきます。

```yaml:upload_evtx.yml
winlogbeat.event_logs:
  - name: ${EVTX_FILE} 
    no_more_events: stop

winlogbeat.shutdown_timeout: 1s
winlogbeat.registry_file: "${CWD}/winlogbeat/evtx-registry.yml"

output.elasticsearch:
  enabled: true
  hosts: ['http://<elastic_ip>:9200']

```

※[Windows EVTX Samples](https://github.com/sbousseaden/EVTX-ATTACK-SAMPLES)で配布されている[winlogbeat_example.yml](https://github.com/sbousseaden/EVTX-ATTACK-SAMPLES/blob/master/winlogbeat_example.yml)とほぼ同じです。おまけを参照。

#winlogbeat.exeコマンドでイベントを投入

```powershell
PS C:\Users\hoge\Desktop> & "C:\Program Files\winlogbeat-7.10.1-windows-x86_64\winlogbeat.exe" -e -c 'C:\Users\hoge\Desktop\upload_evtx\upload_evtx.yml' -E EVTX_FILE="C:\Users\hoge\Desktop\EVTX-ATTACK-SAMPLES-master\Credential Access\sysmon_3_10_Invoke-Mimikatz_hosted_Github.evtx" -E CWD='C:\Users\hoge\Desktop\upload_evtx\
```

#Elastic Common Schema (ECS)へ変換してから投入
SecurityログやSysmonログはwinlogbeatに[ECS](https://github.com/elastic/ecs)への変換を行ってくれるプロセッサ（スクリプト）が同梱されています。ECSへ変換して格納した方がいろいろ便利なので有効化したい場合には以下の設定例を参照ください。

```yaml:upload_evtx.yml
winlogbeat.event_logs:
  - name: ${EVTX_FILE} 
    no_more_events: stop
    processors:
      # Sysmonログの変換
      - script:
          lang: javascript
          id: sysmon
          file: "C:\\Program Files\\winlogbeat-7.10.1-windows-x86_64\\module\\sysmon\\config\\winlogbeat-sysmon.js"
      # Securityログの変換
      - script:
          lang: javascript
          id: security
          file: "C:\\Program Files\\winlogbeat-7.10.1-windows-x86_64\\module\\security\\config\\winlogbeat-security.js"

winlogbeat.shutdown_timeout: 1s
winlogbeat.registry_file: "${CWD}/winlogbeat/evtx-registry.yml"

output.elasticsearch:
  enabled: true
  hosts: ['http://<elastic_ip>:9200']

```


Winlogbeatがデフォルトではサポートしていないイベントログの加工を行いたい場合でもjavascriptとしてスクリプトプロセッサを独自に書くことができます。少し古い記事ですが以下の記事もご参考まで。

[Winlogbeat 7.2.0 新機能: ScriptプロセッサのモジュールをJavascriptで作ってみる](https://qiita.com/rhpenguin/items/62277a0012f118d11ffd)


#おまけ
今回利用した[Windows EVTX Samples](https://github.com/sbousseaden/EVTX-ATTACK-SAMPLES)には全イベントファイルをまとめて投入してくれるPowerShellスクリプトが同梱されています。

```powershell
#Windows EVTX Samplesを展開したフォルダへ移動して・・・
PS C:\Users\hoge\Desktop\EVTX-ATTACK-SAMPLES-master> PowerShell.exe -ExecutionPolicy UnRestricted -File .\Winlogbeat-Bulk-Read.ps1 -Exe "C:\Program Files\winlogbeat-7.10.1-windows-x86_64\winlogbeat.exe" -Reset -Verbose -Config .\winlogbeat_example.yml
```
CakePHP3.8で、フォーム送信時にChrome最新版だと「送信しようとしている情報は保護されません」って警告文が出る

# 環境
- CakePHP3.8
- Chrome 87.0.4280.88
- SSL 導入済みサイト

# 症状
![chrome-notification.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152333/5b5d17c1-93c6-e20e-5a8f-e2e2c9cf5e1a.png)

タイトルの通りで、CakePHP3.8 で作っている SSL サーバ証明書導入済みシステムで、ログイン画面だろうが記事投稿画面だろうが、フォーム送信時に「送信しようとしている情報は保護されません」という警告画面が出るようになりました。ツラい。
先週まではそんなことなかったけど、今日（2020/12/14）、Chrome を最新版に更新してから出るようになりました。

# 対策
app.php の fullBaseUrl を指定することで解決しました。


```config/app.php
//'fullBaseUrl' => false,
'fullBaseUrl' => 'https://hoge.com', # https からのフルパス指定
```
Rails Viewに〇〇ロジックは書かない (※後日追記)

Railsを使用していて、viewやcontroller、modelにメソッドを
どう使い分けて定義するんだっけとなったため
備忘録として記述します

##Viewの役割
ページの表示や、ページ遷移、ユーザーが入力した情報を
controllerに送るなどの役割がある
**プレゼンテーションロジック**とも

##〇〇ロジックは書かない
〇〇に入る言葉は、**ビジネス**ロジックです
データとデータに関わる処理、DBに保存や読み込みをする処理のイメージ

##なぜかいたらいけないのか
・Viewに同じビジネスロジックが重複してしまうと、
変更範囲が広くなりコストがかかる
→`Model`に記述しておけば変更時は一箇所だけ

・Viewを介してテストを書く必要が出てくるので、
同じビジネスロジックの場合全てテストするのはコストがかかる
→こちらも`Modelに書けばテストは一つで済むから

・デザインが頻繁に変更される場合、
ビジネスロジックにその変更による影響がでることがある

##意識すること
Viewはとにかく表示をするだけ！シンプル
ロジックを記述する際には、Controller、Model、Helper、Decorator等を
使い分ける

また、後日追記します！

##参考記事、書籍
現場Rails
https://techracho.bpsinc.jp/hachi8833/2018_05_07/55778
https://qiita.com/sumin/items/24689d0a5622f000a71f
【AWS】初めてのデプロイでやってよかったこと

# はじめに

**本記事の概要**
**初学者の多くがデプロイに躓く原因とその対策**


プログラミング初学者の多くが躓くであろうデプロイ作業。
私も先月個人アプリを開発し、初めてデプロイ作業というものを経験しました。

結果から言うと、あまり苦戦することなくスムーズにデプロイを完了させることができました。
と言いつつも、エラーが全く出なかったわけではありません。**普通に設定漏れがありました。**

ただ、その設定漏れ箇所もいち早く突き止めることができたため、全体として時間はあまりかかりませんでした。

# 初学者の多くがデプロイで躓く理由

あくまで個人的な見解ですが…

**1. GUIでの設定で漏れがある(AWSなど)
2. CLIでコマンドの打ち忘れ、スペルミスがある
3. 設定漏れ箇所を特定するのに時間がかかる
4. エラーが発生した場合に、どこが原因かが分からず、とりあえず手探りに色々弄ってしまう（あーもうめちゃくちゃだよ）
5. そもそも各設定を何のために行っているかを理解していない**

5.については、各作業の意味を理解するに越したことはないですが、初学者にとっては難しい部分が多く、正直仕方ないかと思っています。

それ以外の1〜4は、初学者でもある程度対策できるところかなと思っています。

# 1.GUIでの設定漏れの対策

AWSなど、ブラウザ上で設定を行っていく場合は、**全設定画面のスクショをノートアプリに貼るようにしていました。**

WindowsであればSnippingToolを、Macであれば⌘+shift+control+4を使って範囲指定のスクショを撮っています。(全画面スクショでもいいです。)

撮ったスクショは下図のようにノートアプリに貼っています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620431/0c8bf655-395c-b9e1-e3ac-269943cc9d20.png)

おそらくデプロイ作業をするときは、何らかの教材や参考記事を見ながら進めていくと思うのですが、スクショをノートに貼る度にその教材と見比べながら進めていくと、漏れはかなり減ると思います。

ただ、この方法は当然時間がかかります。
が、実務においても設定のエビデンスを残すことは多いそうですし、今のうちに慣れておいた方が良いかと思います。
設定のエビデンスは後述のエラーの原因を突き止めるのにも使えますし、何よりもトラブルがあった時に自分の身を守るためにも残した方が良いと思われます。

# 2.CLIでコマンドの打ち忘れ、スペルミスの対策

CLI(コンソール画面など)におけるコマンドの打ち忘れについては、GUIの時と同じくコマンドの実行時のスクショをノートアプリに貼りながら、漏れがないかを逐一確認することで対策していました。

スペルミスもかなりよくあるミスだと思うのですが、こちらの対策として**そもそもコマンドは直接手打ちで入力しない**ようにしていました。

コマンドは基本的に教材からコピペで入力するようにし、IPアドレスやユーザー名など個人環境に依存する部分も予めノートアプリに書いておいて、それをコピペして入力するようにしていました。

これはデプロイに限らず、基本的にコマンドは事前に用意＆確認をしておいて、実際に設定する際にはそれをコピペするだけにしておくと、スペルミスなどのヒューマンエラーはかなり減るかと思われます。
あと、CLIに直接手打ちで入力していると、誤ってEnterキー二回押しちゃって中途半端なコマンドを実行してしまうこともあります…。

**CLIへの入力は基本的にペーストだけするとかなり安定します。**

# 3.設定漏れ箇所を特定するのに時間がかかることへの対策

一番理想なのはエラーメッセージからエラー箇所を特定できることなのですが、初学者にとっては少し難しいかもしれません…。
そうなってくると、おそらく設定を一つ一つ見直していく作業が生じるかと思います。

この時、**GUIをいちいち操作しながら該当箇所の設定を見直すのと、作業ログを見直すのとでは後者の方が要する時間は少ないです。**

私も作業ログを残しながら慎重に作業していたものの、悔しいことに設定漏れがありました。
ただ、**作業ログを見直すだけで漏れはすぐに見つかったので、結果的にそこまで大事には至らなかったです。**


# 4.手探りに色々弄ってしまうことについて

**これは基本的にタブーだと思います。**
ある程度エラー原因に心当たりがあるのであればいいのですが、何も考えずに片っ端から弄ってしまうと余計に泥沼にハマってしまう可能性が高いです。
**実務であればまずは上司に報告、スクールであればまずメンターに相談するべきかと思います。**

実際にエラー後に色々設定を弄ってしまった方からヘルプを求められたことがあるのですが、どうしてこうなる前に相談してくれなかったんだ！！！と思うばかりでした…。

とはいえ、トライ&エラーを行わないと原因を切り分けが進まない場合もあります。
私の中で「とりあえず設定を変更してみる」が許されるのは**設定を元に戻せることが確認できている**場合のみかなと思っています。

# 5.そもそも各設定を何のために行っているかを理解していないことについて

初学者にとってある程度は仕方ない部分かなと思っていますが、デプロイが完了した後でも良いので、各作業は何を設定しているのかくらいは調べた方が良いです。

教材がしっかりしていれば、基本的には教材に沿って進めれば何の問題もなくデプロイを完了させることができると思いますが、GUIなんかは画面レイアウトがコロコロ変わり、教材と差異が出てしまうイメージです。(教材に載ってる設定項目が実際の画面になかったり、別の画面で設定しないといけなかったり…)

デプロイ時の各作業の意味をそれなりに理解していると、多少画面レイアウトが教材と異なっていても、上手く設定できるかと思います。

# やってよかったことまとめ

- 各設定画面、コマンドの実行ログのエビデンスを残す
- コマンドはなるべく手打ちで入力しない
- 各設定の意味を調べる
React NativeでXcode12でbuildすると画像が表示されない件について

# はじめに
iOS14向けの対応を実施するにあたり、Xcodeのバージョンアップをして、buildしたところアプリ内の画像ファイルが一切表示されなくなる事象に出くわしました。

最初に調べたとき参考にあげさせていただいた一つ目の記事に行きつき、対応を行いました。そもそもreact-nativeのバージョンを0.63.X以降にあげれば対応が入っているようなんですが、そこまでコストをかけられないのもあり、今回はパッチでの対応にしました。

# 環境
react-native : 0.61.4

# 最初に実行した内容
## パッチファイルの作成・実行
プロジェクトのルートディレクトリで以下を実行

```
$ npx patch-package react-native

npx: 150個のパッケージを5.364秒でインストールしました。
patch-package 6.2.2
patch-package: you have both yarn.lock and package-lock.json
Defaulting to using npm
You can override this setting by passing --use-yarn or deleting
package-lock.json if you don't need it

• Creating temporary folder
• Installing react-native@0.61.4 with npm
• Diffing your files with clean files
✔ Created file patches/react-native+0.61.4.patch
```

作成されたpatchファイルに以下を追記する

```
diff --git a/node_modules/react-native/Libraries/Image/RCTUIImageViewAnimated.m b/node_modules/react-native/Libraries/Image/RCTUIImageViewAnimated.m
index 01aa75f..4ef8307 100644
--- a/node_modules/react-native/Libraries/Image/RCTUIImageViewAnimated.m
+++ b/node_modules/react-native/Libraries/Image/RCTUIImageViewAnimated.m
@@ -269,6 +269,8 @@ - (void)displayLayer:(CALayer *)layer
   if (_currentFrame) {
     layer.contentsScale = self.animatedImageScale;
     layer.contents = (__bridge id)_currentFrame.CGImage;
+  } else {
+    [super displayLayer:layer];
   }
 }
```

以下コマンドでパッチの実行

```
$ patch -p1 -i patches/react-native+0.61.4.patch
```

で**node_modules/react-native/Libraries/Image/RCTUIImageViewAnimated.m:**の270行目付近が以下のようになっていることを確認する

```
- (void)displayLayer:(CALayer *)layer
{
  if (_currentFrame) {
    layer.contentsScale = self.animatedImageScale;
    layer.contents = (__bridge id)_currentFrame.CGImage;
  } else {
    [super displayLayer:layer]; // 記載されていることを確認
  }
}
```

ここまでいけば後は、runしていただければ画像がでることを確認できます。
となるはずだったのですが、私の開発中アプリではごく一部の画像のみ表示されましたが、ほとんどの画像がいまだ表示されていない状態でした。

# react-native-fastimageのための追加対応

いろいろ調べた結果参考の２つ目に行きついたのですが、react-native-fastimageを利用していると追加対応が必要とのこと

iOSディレクトリに移動して、以下を以下を実行して、SDWebImageのバージョンをアップする。一応5.8.3まであげればいいようですが、私は最新まであげてしまいました。

```
pod update SDWebImage
```

これでrunして、動作確認したところ無事すべての画像が表示されていました。


# 参考
https://qiita.com/IZUMIRU/items/ff485f2cc2d35f724044
https://github.com/DylanVann/react-native-fast-image/issues/702
Ruby on Railsの「MVC」についてちょっとまとめてみる

# 最初に

**カレンダー企画2020の14日目**
プログラミングの勉強を始めて3ヵ月程経ったので学んだことのメモをアウトプットとして記事に残します。
これからプログラミングの世界に入る人の手助けになれたら嬉しい限りです。
間違っていたり、言葉が違っていたり、誤解されるような言葉があったら教えてください^^
言葉を長々と読みづらかったら申し訳ありません。少しずつなれてがんばります。

## Ruby on Railsの「MVC」についてまとめてみる

Ruby on Railsは、`MVC`という考え方で構成されている。
M：Model（モデル）
V：View（ビュー）
C：Controller（コントローラー）

それぞれに役割を分けてプログラムのメンテナンスをする時にしやすくしたり、複数人で作業をする時に影響が出にくい。


## Model

アプリケーションのデータを取り扱う場所。データベースに対してデータの登録や取得、更新、削除などといった処理を役割として担っている。

たとえば
データベースという巨大な倉庫を管理しているイメージかな。
必要な時に必要な情報を取り出したり、しまったりしてくれる感じです。

## View

パソコンの画面に関わる部分です。使う側（user）が目にするところです。ブラウザに表示させるHTMLを組み立てる場所。

たとえば
配達員のイメージかな
注文を受けたものをお客様に届ける感じ
お客様が頼んでいないものを勝手に届ける事はない


## Controller

ModelやViewを統合的にコントロールしている場所。
userが見たいページをクリックしたら、最初にControllerが受け取り、Modelと連携をして必要な情報をデータベースから引き出し、それをViewを使って表示させるみたな流れをコントロールしているのがControllerの役割

たとえば
司令塔みたいなイメージ
お客様から注文を受けて巨大倉庫からスムーズに作業が行われるように指示を出したり、倉庫から他注文の品を次は適切な場所に届けるように配達員に指示を出す感じ



## 最後に

イメージを伝えながら説明をしたつもりですが、難しかった^^;
1つ言えるのは役割が明確なので複雑化する事は少ないというのが良いですね。アプリケーションを作成していて躓いても何が機能していないのか？どこで詰まっているのか？をこの構造を理解していると発見しやすいです！


図解してくれているサイトの一部はこちら
[参考サイト1](https://qiita.com/s_tatsuki/items/66ffee4519451812a448)
[参考サイト2](https://www.javadrive.jp/rails/ini/index7.html)
野球のボールカウント（どう書く）

[https://qiita.com/Nabetani/items/ebd8a56b41711ba459f9](https://qiita.com/Nabetani/items/ebd8a56b41711ba459f9)

連続する入力（種類はストライク・ボール・ファウル・ヒット・ピッチャーフライ）が与えられたとき、ボールカウント・アウトカウントの遷移を出力する問題です。

```ruby:Ruby
module BallCount
  def self.solve(input)
    out = strike = ball = 0
    sb_zero = ->{ strike = ball = 0 }
    
    input.each_char.map {|c|
      case c
      when "s"
        strike += 1
        if strike == 3
          sb_zero.()
          out += 1
        end
      when "b"
        ball += 1
        sb_zero.() if ball == 4
      when "h"
        sb_zero.()
      when "p"
        out += 1
        sb_zero.()
      when "f"
        strike += 1 if strike <= 1
      end
      
      out = strike = ball = 0 if out == 3
      
      "#{out}#{strike}#{ball}"
    }.join(",")
  end
end


if __FILE__ == $0
  require 'minitest/autorun'
  describe 'BallCount' do
    [
      ["s", "010"],
      ["sss", "010,020,100"],
      ["bbbb", "001,002,003,000"],
      ["ssbbbb", "010,020,021,022,023,000"],
      ["hsbhfhbh", "000,010,011,000,010,000,001,000"],
      ["psbpfpbp", "100,110,111,200,210,000,001,100"],
      ["ppp", "100,200,000"],
      ["ffffs", "010,020,020,020,100"],
      ["ssspfffs", "010,020,100,200,210,220,220,000"],
      ["bbbsfbppp", "001,002,003,013,023,000,100,200,000"],
      ["sssbbbbsbhsbppp", "010,020,100,101,102,103,100,110,111,100,110,111,200,000,100"],
      ["ssffpffssp", "010,020,020,020,100,110,120,200,210,000"]
    ].each do |input, expect|
      it input do
        assert_equal BallCount.solve(input), expect 
      end
    end
  end
end
```

一文字の入力`c`に出力`"#{out}#{strike}#{ball}"`ひとつが対応する、つまりは写像（map）なので、素直に`Enumerable#map`を使っています。対応にはこれも素直に case ~ when を使います。

それから、ストライクとボールを共に 0 にする操作は頻出するので、あらかじめクロージャとして lambda 関数（`sb_zero`）を定義しておいてあります。
UIPageViewControllerのスワイプジェスチャーを一時的に無効化したい

# 課題

こんな感じのView構成になっているとします。
![スクリーンショット 2020-12-14 12.48.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122917/5871f555-7ca4-fb6b-bffb-0accb9997917.png)

UINavigationController上の「UIViewController-C」からpush遷移で「UIViewController-D」を表示した状態で、
画面左端のスワイプで「UIViewController-C」にbackしたいのですが（青矢印）、
実際の動作は「UIViewController-A」が表示されてしまいました（赤矢印）。
![スクリーンショット 2020-12-14 12.43.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122917/4e76b386-76e7-bb34-d390-917e7492b38a.png)
どうやら、UINavigationControllerのスワイプジェスチャーよりもUIPageViewControllerのスワイプジェスチャーが優先されているみたいです…

# 対策

UIPageViewControllerのdataSourceをnilに設定することで、スワイプを無効化できました。
UIViewController-Dが表示された際、UIPageViewControllerにNotificationをpostしてdataSourceをnilに設定し、画面が消えたときに戻す作戦で課題を解決できました。

```swift

class PageViewController: UIPageViewController {
    static let needToChangeSwipeEnabledNotification = Notification.Name("NotificationForChangeMainPageSwipeEnabled")

    override func viewDidLoad() {
        super.viewDidLoad()
        dataSource = self
        NotificationCenter.default
            .addObserver(forName: PageViewController.needToChangeSwipeEnabledNotification,
                         object: nil,
                         queue: nil,
                         using: { [weak self] notification in
                            guard let canSwipe = notification.object as? Bool else { return }
                            self?.changeSwipeEnabled(to: canSwipe)
                         })
    }

    private func changeSwipeEnabled(to canSwipe: Bool) {
        dataSource = canSwipe ? self : nil
    }

// 省略
}
```

```swift
class ViewController_D: UIViewController {

// 省略
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        NotificationCenter.default.post(name: PageViewController.needToChangeSwipeEnabledNotification, object: false)

    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
        NotificationCenter.default.post(name: PageViewController.needToChangeSwipeEnabledNotification, object: true)
    }
}
```
OpenCVのカメラキャリブレーションモジュールについてざっくり説明する

本記事はアドベントカレンダー [ほぼ厚木の民](https://adventar.org/calendars/5825) の記事です。

はじめまして、11日目担当の新人の稲生（いのう、と読みます。）です。技術系の記事を書くのが初めてなので拙いところが多いかもしれませんが、温かい目で見ていただけると幸いです。
この1年カメラキャリブレーションについて論文やツールをひたすら漁っていました。その中でOpenCVのモジュールについて備忘録がてら、まとめていこうと思います。

##そもそもカメラキャリブレーションとは
[MATLABのチュートリアル](https://jp.mathworks.com/help/vision/ug/camera-calibration.html)が一番わかりやすいのでそちらを読んでもらった方が早いと思いますが、端的に言うと**カメラの焦点距離や歪み具合、位置などの情報をパラメータとして推定すること**です。チェッカーボードをカメラの前でいろんな姿勢で撮影した画像を使って行うのが一般的です。
パラメータを使って写真の歪みを修正したり、物体の3次元位置の推定、などなどいろんなことができるようになります。

<center><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214360/e066a990-ad72-8212-2e49-c36f10ae8888.png" title="中心射影" width=100%>

##OpenCVでのカメラキャリブレーション
OpenCVでは3つのモジュールが実装されています。

- cv::calibrateCamera() 
<center><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214360/25d1e48c-97e3-7762-395e-698305282e2f.jpeg" title="中心射影" width=50%>
上の画像のような我々が日頃使っているカメラのレンズ(中心射影レンズ)のキャリブレーションをしたいときに使います。製品、研究問わず色んなところで使われています。しかし、下の写真のような魚眼レンズのような広角なレンズには基本、適用できません。
<center><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214360/2ec72953-3ff6-559f-d639-daabd095f9e2.png" title="魚眼" width=50%>

- cv::fisheye::calibrate()
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214360/cc43fb8f-4119-9463-dbb4-1c91ca9c67e0.png)
文字通りこれは魚眼レンズ向けのモジュールになります。なのですが、例えば[こんなレンズ](https://products.entaniya.co.jp/ja/products/hal-250200/fisheyehal-200/)や[こんなレンズ](https://yoshimi.ocnk.net/product/216)のような画角180度を超える（＝レンズ後方の景色が少し映る）ものでキャリブレーションすると大体うまくいきません。[ソースコード](https://github.com/opencv/opencv_contrib/blob/master/modules/ccalib/src/omnidir.cpp)をのぞいてみるとこんなことが書いてあります。
```// the current camera model is only valid up to 180 FOV
// for larger FOV the loop below does not converge
// clip values so we still get plausible results for super fisheye images > 180 grad```
**このカメラモデルは画角180度までしか対応していない**、と明記されています。でも最近の魚眼レンズは180度以上のものがむしろメジャーなのではないかと思います。360度カメラとして有名なRicoh ThetaやInsta360などは前後に2つレンズがついていて、それぞれ画角180度以上あります。

ちなみにMATLABの[魚眼レンズ向けモジュール](https://sites.google.com/site/scarabotix/ocamcalib-toolbox)では画角195度まで対応、としています。では画角200度超のレンズはどうすればいいか。

- cv::omnidir::calibrate()

こちらはomnidirectional(無指向性、全方位）なレンズ向けのモジュールです。Omnidirectionalなレンズって何って話ですが下のようなカメラです。
<center><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214360/c9290e74-8fd0-12f2-f2ca-4ad7e235d76d.png" title="全方位" width=50%>
見た目が魚眼レンズと全然違いますが立派なレンズの一種です。

モジュールの名前もレンズの形も全然違うし、一見、魚眼レンズには使えなさそうな印象もあります。しかし、結論から言うと画角に関わらず魚眼レンズをキャリブレーションする場合も**fisheye::calibrate()よりこちらを使った方が良い**です。

ただomnidir自体は拡張モジュールなので使う際は自分でOpenCVをビルドする必要がある、使ってる人が少なすぎて情報が殆どないのが欠点です。執筆し始めたのが遅すぎたのでこのあたりの話は時間があるときにまた書こうと思います。実装と比較の参考にソースコードを置いておきます。

[calibrate.cpp](https://github.com/urotanke95/opencv_calib/blob/main/calibrate.cpp)


##まとめ
OpenCVには3つのキャリブレーション機能が実装されていて、良い推定結果を得るためにはレンズの特性に合わせて使うモジュールを選ぶ必要があります。

- cv::calibrateCamera()
中心射影レンズ向け

- cv::fisheye::calibrate()
魚眼レンズ(~画角180度)向け

- cv::omnidir::calibrate()
魚眼レンズ、全方位レンズ向け
VSCodeのターミナルを「選択でコピー」「右クリックで貼り付け」の設定に変更する

# VSCodeのターミナルを「選択でコピー」「右クリックで貼り付け」の設定に変更する

Visual Studio Codeの設定から変更可能です。

## 選択でコピー

1. Code > Preferences > Settingsを選択し、設定を開く（日本語化している場合は、Code > 基本設定 > 設定、Windowsの場合は、ファイル > ユーザー設定 > 設定）。
2. Features > Terminalを選択する（日本語化している場合は、機能 > ターミナル）。
3. Terminal › Integrated: Copy On Selectionの設定項目にチェックを入れる。

## 右クリックで貼り付け

1. 設定を開く。
2. Features > Terminalを選択する。
3. Terminal › Integrated: Right Click Behaviorの設定項目をpasteに変更する。

## 補足

settings.jsonに以下の2行を追加しても同様に設定変更できます。

```json:settings.json
{
    // ...
    "terminal.integrated.copyOnSelection": true,
    "terminal.integrated.rightClickBehavior": "paste",
    // ...
}
```

## 参考

[Integrated Terminal in Visual Studio Code](https://code.visualstudio.com/docs/editor/integrated-terminal)