OmniAICreator/Qiita-1.07M huggingface dataset:
何を入力しても/etc/zshrc: 7: command not found: local というエラー

**あらかじめ・・・**
タイトル内容の前に、以下に自身の作業環境について記載しています。

加えて、問題解決後にエラー時の内容を記録していなかった為、詳細なエラーの内容を記載できない部分に関しては表記を濁してあります。

※初学者である僕自身の備忘録的に記録を残しますので、何か問題点があればご指摘いただければと思います。

##前提事項
###環境
OS：MacOS Catalina
ターミナル:-zsh
###作業者レベル
プログラミング学習初学者(開始３ヶ月目)

上記となります
***
##症状
ターミナルにてどのコマンドを入力、実行しても以下のエラーが返ってくる

```.zsh
/etc/zshrc:7: command not found: locale
```
と表示され、何も実行できない。

ターミナルを使用し、npmにて「nodebrew」インストールの際、「何か」してしまった様で、調べてみると`PATH`の破損？が原因のようです。

##対処
まずは、中身(PATH)の確認の為以下の通り入力します。

```.zsh
echo $PATH
```

返ってくる中身（PATH）に以下が含まれていなければ問題ありです。

```.zsh
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:
```

僕の場合、インストール作業時に何をどう間違えたか分かりませんが、こうなっていなかった為、以下の様にコマンドを入力し修正をかけました。

```zsh.
echo export PATH='/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:$PATH' >> ~/.zprofile
source ~/.zprofile
```

これが「bash」を使用している方であれば、以下の様になるはずです。

```bash.
echo export PATH='/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:$PATH' >> ~/.bash_profile
source ~/.bash_profile
```

僕の場合、これで修復された様で使用可能になりましたが、ダメだった場合Time Machineでの復元を考えてました。

一応、ターミナルが使えるようにはなりましたが、対応として正解か否か・・・
コメントいただける方いらっしゃいましたら、よろしくお願いいたします。
[Ansible]特殊文字をエスケープ処理する方法

Ansibleを利用していると、replace,lineinfileなどでエスケープ処理をするタイミングがあると思います。その時に便利な方法です。

# やりたいこと
以下の様なシェルスクリプトを以下のようにAnsibleで置換処理をしたい。

```bash
## /tmp/test.sh
#!/bin/bash

FILE="/tmp/hoge.txt"
# → FILE="/tmp/fuga.txt"

[ -e ${FILE} ] && echo "OK"
# → [ -s ${FILE} ] && echo "OK"
```

# Ansibleタスクの記述
regexpに{{ <em>item名</em> **| regex_escape()** }}のように記載をすると、特殊文字をエスケープ処理してくれます。
regexpの記述は特に気にせず、置き換えを実施したい文字列をそのまま記述すればよいので、便利です。エスケープし忘れなどのミスも防止出来るので、積極的に使っていきたいですね。

```yaml
---
- name: test
  replace:
    dest: /tmp/test.sh
    regexp:  '{{ item.regexp | regex_escape() }}'
    replace: '{{ item.replace }}'
  with_items:
    - regexp:  'FILE="/tmp/hoge.txt"'
      replace: 'FILE="/tmp/fuga.txt"'
    - regexp:  '[ -s ${FILE} ] && echo "OK"'
      replace: '[ -e ${FILE} ] && echo "OK"'
```

## 結果
きれいに置換出来ました。

```bash
## /tmp/test.sh 
#!/bin/bash

FILE="/tmp/hoge.txt"

[ -s ${FILE} ] && echo "OK"
```

https://docs.ansible.com/ansible/2.9_ja/user_guide/playbooks_filters.html
Rails5  Rspecテスト時のエラー Webdrivers::BrowserNotFound:  Failed to find Chrome binary

## はじめに
Ruby on Rails5 速習実践ガイドのChapter5-8にて、"bundle exec rspec spec/system/tasks_spec.rb"をターミナル上で実行したところ、下記のエラーにハマりました。
その備忘録です。

## 発生している問題・エラー
```
Failures:
  1) タスク管理機能 一覧機能表示 ユーザーAがログインしているとき ユーザーAが作成したタスクが表示される
     Failure/Error: driven_by :selenium_chrome_headless
     
     Webdrivers::BrowserNotFound:
       Failed to find Chrome binary.
     
     # /Library/Ruby/Gems/2.6.0/gems/webdrivers-4.4.1/lib/webdrivers/chrome_finder.rb:21:in `location'
     # /Library/Ruby/Gems/2.6.0/gems/webdrivers-4.4.1/lib/webdrivers/chrome_finder.rb:10:in `version'
     # /Library/Ruby/Gems/2.6.0/gems/webdrivers-4.4.1/lib/webdrivers/chromedriver.rb:51:in `browser_version'
     # /Library/Ruby/Gems/2.6.0/gems/webdrivers-4.4.1/lib/webdrivers/chromedriver.rb:124:in `browser_build_version'
     # /Library/Ruby/Gems/2.6.0/gems/webdrivers-4.4.1/lib/webdrivers/chromedriver.rb:32:in `latest_version'
     # /Library/Ruby/Gems/2.6.0/gems/webdrivers-4.4.1/lib/webdrivers/common.rb:135:in `correct_binary?'
     # /Library/Ruby/Gems/2.6.0/gems/webdrivers-4.4.1/lib/webdrivers/common.rb:91:in `update'
     # /Library/Ruby/Gems/2.6.0/gems/webdrivers-4.4.1/lib/webdrivers/chromedriver.rb:139:in `block in <main>'
     # ./spec/spec_helper.rb:21:in `block (2 levels) in <top (required)>'

Finished in 0.0532 seconds (files took 1.66 seconds to load)
1 example, 1 failure

Failed examples:

rspec ./spec/system/tasks_spec.rb:19 # タスク管理機能 一覧機能表示 ユーザーAがログインしているとき ユーザーAが作成したタスクが表示される
```

## 原因・解決方法

ターミナル上にGoogle chromeがインストールされていなかったようです。

↓ターミナル上のホームで、google-chromeをインストール

```
$ brew cask install google-chrome 
```
↓再度、Rspecを実行

```
$ bundle exec rspec spec/system/tasks_spec.rb
```

↓無事解決できました。

```
Finished in 6.11 seconds (files took 1.17 seconds to load)
1 example, 0 failures
```

## 参考にした記事

以下を参考にさせていただきました。
https://ja.stackoverflow.com/questions/69050/rspec%E3%81%A7-failed-to-find-chrome-binary-%E3%81%AE%E3%82%A8%E3%83%A9%E3%83%BC%E3%81%8C%E8%A7%A3%E6%B1%BA%E3%81%A7%E3%81%8D%E3%81%AA%E3%81%84
Ubuntu のターミナルをかっこよく

つい最近、以下のような記事を見つけました。
[Bashのプロンプトを超絶おしゃれにする Starship を紹介](https://qiita.com/unhappychoice/items/3b774310d95e2124eb77)

ターミナルのカスタマイズは一度は誰でもやることでしょう。
僕は普段Ubuntuを使っているのですが、上の記事ではMacで環境構築を行っているようでした。
Ubuntuに導入する記事が見当たらなかったので書こうと思います。

## 目次
- Rustのインストール
- Starshipの導入

## Rustのインストール
Ubuntu環境へのRustのインストールは[ここ](https://qiita.com/yoshiyasu1111/items/0c3d08658560d4b91431)を参考にしました。
インストール、パスの設定を行ったあと、実行確認を行いました。
[パスの設定](https://qiita.com/yoshiyasu1111/items/0c3d08658560d4b91431#%E3%83%91%E3%82%B9%E3%81%AE%E8%A8%AD%E5%AE%9A)にある以下のコマンドは.bashrcに追記しておくといいでしょう

```
$ source $HOME/.cargo/env
```

## Starshipの導入
Rustの環境導入が出来たらあとは簡単です。
まず[公式ページ](https://starship.rs/)に従い、Starshipをインストール。

```
$ cargo install starship
```
次にinit scriptをshellのconfig fileに追記。
僕は普段bashを使っているので、.bashrcに以下を追記。

```
eval "$(starship init bash)"
```

これで環境構築は終了です。
あとは[ここ](https://starship.rs/config/#prompt)を参考にしながら自分好みにカスタマイズしましょう！
yumで、Cannot retrieve metalink for repository エラーが出た時の対処

#エラー内容
yum コマンドが、metalink エラーで動作しなくなった時の対処

yum repolist all などと入力すると、下記のエラーが出るようになった。

``` 
Cannot retrieve metalink for repository: epel/x86_64. Please verify its path and try again
```
#対処方法

epelリポジトリへのmetalinkでの接続ができないのが原因なので
以下のファイルのbaseurlのコメントを外して、
metalink設定をコメントアウトする

```bash:/etc/yum.repos.d/epel.repo
[epel]
name=Extra Packages for Enterprise Linux 7 - $basearch
baseurl=http://download.fedoraproject.org/pub/epel/7/$basearch
#metalink=https://mirrors.fedoraproject.org/metalink?repo=epel-7&arch=$basearch
```

[epel-debuginfo]、[epel-source]にも同様の設定があるので同様に修正する。

サーバーを初期化後にこのエラーが出たので、証明書関連の設定が影響した
可能性があるがこれでyumが動作するようになった。
Javascriptの構文

このチュートリアルでは、Javascriptにおける大文字小文字の区別、識別子、コメント、文、式について学べるように記載しました。

#####Javascriptにおける大文字小文字の区別
変数、関数、名前、クラス名など含むすべてのJavascriptは、大文字小文字を区別します。
例えば、関数にinstanceofという名前をつけることはできません。
それは、キーワードとして既に使用されているからです。
ただし、instanceOfであれば有効な関数名として使用できます。

#####識別子
識別子は、変数名、関数名、パラメータ名、クラス名です。識別子は１つあるいは複数の文字から成っており、以下の規則があります。

* 最初の文字は大文字小文字の全て、アンダースコア、$のみ使用可能
* ２文字目以降は、上記に加えて数字が使用可能

使用できる文字は、アスキー文字のみに限定されませんが拡張アスキー文字やUnicodeは推奨されていません。
識別子にはキャメルケースを使用するのが最良の方法です。
キャメルケースとは、最初の単語を小文字で開始し、次の意味を成す単語を大文字で開始することです。
以下のような例です。

```
counter
inArray
beginWith
redirectPage
```

#####コメント
Javascriptにおいて、コメントを記載する方法は以下の２パターンがあります。
* コメントが１行のみの場合、文頭に//を入れる
* コメントが複数行の場合、/\*で初めて\*/で閉じる

```javascript
// this is a single-line comment

/*
* This is a block comment that can
* span multiple lines
*/
```

#####構文
Javascriptは必ずしも文末にセミコロンを必要としないが、使用することが推奨されています。
理由としては、コードが読みやすい、問題が起きたときの対処がしやすいことがあります。

```javascript
var a = 10;
var b = 20;
```

複数の構文をまとめる場合、文の最初に中括弧{を記載し、最後に}で閉じる必要があります。

```javascript
if( a > b) {
   console.log('a is greater than b');
   return 1;
}
```

#####計算式
変数aに変数bを足す構文は以下となります。

```javascript
a + b;
```

#####キーワード及び予約語
Javascriptには、いくつかの予約後とキーワードが定義されています。
我々は、これらを識別名として使用はできません。
next.jsでdotenvで環境変数を設定するのは間違い！たった3分で環境変数を設定する方法

#概要
・next.jsでは「**.env.local**」ファイルで環境変数を設定できる。
・クライアント側でも環境変数を設定したいときは接頭語に「**NEXT_PUBLIC_**」をつける
・開発環境は「**.env.development**」、本番環境は「**.env.production**」でそれぞれの環境変数を設定できる

#環境変数を設定する（サーバー編）
next.jsでは簡単に環境変数を変更する仕組みがあります。
ルートディレクトリに「**.env.local**」ファイルを置き、その中で定義した環境変数はアプリの中で使うことができます。

たとえば、開発環境と本番環境で異なるデータベースを使いますよね。そんな時に「.env.local」ファイルに設定すれば環境変数をアプリ内で利用できます。

```.env.local
DB_HOST=localhost
DB_USER=root
DB_PASSWORD=root
```

```環境変数の使用.js
export async function getServerSideProps(context) {
  console.log(process.env.DB_HOST) //コンソールに「localhost」を出力（サーバー側）
  return {props: {}}
}
```

##環境変数に他の環境変数を設定したい場合
また、「.env.local」で設定した環境変数を別の環境変数で使うには、「$」を使います。
たとえば、ホスト名にポート番号を追加したいときには以下のように定義します。

```.env.local
PORT=3000
HOST=http://localhost:$PORT
```

```index.js
export async function getServerSideProps(context) {
  console.log(process.env.HOST) //コンソールに「http:localhost:3000」を出力（サーバー側）
  return {props: {}}
}
```

#環境変数を設定する（クライアント編）
先ほどの、「.env.local」で設定した環境変数は**node.jsのみで適用**されます。そのため、ブラウザ側で動くプログラムでは使うことができません、
クライアント側でも環境変数を使いたいときにはどうすればいいのでしょうか？

この問題を解決するのが環境変数の接頭語の「**NEXT_PUBLIC_**」です。環境変数の接頭語に「NEXT_PUBLIC_」をつければ、クライアント側でも使うことができます。
これにより、**ブラウザ側、サーバー側どちらでも環境変数を利用できる**のです。

```.env.local
NEXT_PUBLIC_TEST=client-server
```

```index.js
export async function getServerSideProps(context) {
  console.log(process.env.NEXT_PUBLIC_TEST) //コンソールに「client-server」を出力（サーバー側）
  return {props: {}}
}

const index = () => {
  return <p>{process.env.NEXT_PUBLIC_TEST}</p>  //画面に「client-server」を出力（クライアント側)
}

export default index
```

#環境によって読み込むファイルを変更する方法
環境ごとに読み込む環境変数を変更したい場合があります。
たとえば、開発環境では開発用のDBを使うけど、本番環境では本番用のDBを使いたいなど環境ごとにDBを切り替えたい場面などです。

そんな時は環境ごとのenvファイルを用意します。以下の4種類でそれぞれの環境変数を設定できます。
・**.env**：全環境共通の環境変数
・**.env.development**：開発環境（next dev）の環境変数
・**.env.production**：本番環境（next start）の環境変数
・**.env.local**：デフォルトの環境変数（すべての環境変数を上書き）

これの環境変数の優先順位は以下の通りです。
**①.env.local**
**②.env.development/.env.production**
**③.env**

基本的に、「.env」にデフォルトで全ての環境変数を設定して、「.env.development」、「.env.production」で上書きするのがいいのではないでしょうか？


#参考
[next.jsの環境変数の設定](https://nextjs.org/docs/basic-features/environment-variables)
docker centosでpython3をインストールする方法

##はじめに
この記事ではAWSのAmazon Linux2を使用して次のことを実行します。
1. dockerのインストール
2. docker imageであるcentosを起動する
3. 2で起動したコンテナ内でpython3をインストール
##1. dockerのインストール

まず以下のようにyumのアップデートを行います。

```
[ec2-user@ip-xxx-xxx-xxx-xxx ~]$ sudo yum update -y
```

次にdockerをインストールします。

```
[ec2-user@ip-xxx-xxx-xxx-xxx ~]$ sudo amazon-linux-extras install docker -y
```

インストールが完了したら、docker daemonを起動します。

```
[ec2-user@ip-xxx-xxx-xxx-xxx ~]$ sudo service docker start
```

ec2-userをdockerグループに追加します。
これは必須ではないですが、以降```sudo```なしで```docker```コマンドが使用できます。

```
[ec2-user@ip-xxx-xxx-xxx-xxx ~]$ sudo usermod -a -G docker ec2-user
```

上記コマンドを実行したら、一度ターミナルを閉じます。その後再度接続し直します。

##2. centosを起動する

まず```run```コマンドによってコンテナを起動します。イメージのプルがされていない場合、プルをしてから起動することができます。
オプション```-it```により、起動したコンテナの中に入ることができます。
(・・・は表示されるメッセージを省略して書いています)

```
[ec2-user@ip-xxx-xxx-xxx-xxx ~]$ docker run -it centos
・
・
・
[root@xxx /]#
```

##3. コンテナ内でpython3をインストール

```
[ec2-user@ip-xxx-xxx-xxx-xxx ~]$ yum install python3 -y
```

以下のように```python3```コマンドを入力することで対話モードになり、インストールされたことがわかります。

```
[root@xxx /]# python3
Python 3.6.8 (default, Apr 16 2020, 01:36:27)
[GCC 8.3.1 20191121 (Red Hat 8.3.1-5)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>
```

インストール後は```pip3```コマンドを使用し、必要なパッケージのインストールを行うことができます。
次のコマンドでaws-cliのバージョン1をインストールしています。

```
[root@xxx /]# pip3 install awscli
```



##参考記事
- AWS 公式サイト
https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/docker-basics.html
- CentOS7 に pip と awscli をインストール
https://rriifftt.hatenablog.com/entry/2015/10/28/142043
【LineAPI×GAS】①新規開拓営業マンとマネージャー層向けLINEbot

# 目標
<img width="400px" alt="arrow.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700999/d7064462-da5b-0830-f540-8c3708529e7f.jpeg">

終了をトリガーとして、その日の行動件数等を入力し、
平均などと比較した上での評価を出力するbotを作成していきます。

※javascript上で完結するのが難しかったため、
　スプレッドシートの関数も使用しております。

# 実際に使用したもの

- GAS(Google Apps Script)
- LINE Messaging API
- Googleスプレッドシート

# 流れ
1 LINEのMessaging APIを作成する
2 Googleスプレッドシートを編集する
3 GoogleAppsSpreadsheetを編集する
4 deployを行う

今回は１，２をご紹介します。

# LINEのMessaging APIを作成する
[こちら](https://qiita.com/nkjm/items/38808bbc97d6927837cd)を参考に作成してください。
Channelを作成するまでできればOKです。

# Googleスプレッドシートを編集する

今回使用する関数は

- AVERAGE
- IF
- vlookup

です。

実際の画面はこちらです。
![スクリーンショット 2020-09-25 12.46.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700999/c3fcd1da-4ddd-8f9f-cd4d-0a7cb2ff2fb3.png)
このような形で入力に対してのスコア、コメントを入れていきます。


## LINEで入力した値を保存する場所
青く選択している箇所に上から順に入力されていくように作ります。
![スクリーンショット 2020-09-25 12.47.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700999/f47fc1f9-0487-9f44-e959-d37fa722e556.png)

## LINEで入力した値にスコアをつける
まずは行動量の平均の値を取得します。
※B30はあくまで一例ですので、適宜変更してください。

```
=AVERAGE(B3:B30)
```
![スクリーンショット 2020-09-25 12.48.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700999/bc83124c-67bd-6d18-66e0-00aec2f3a0c2.png)
下記画像は青く選択した箇所がスコアを付けるための関数が入っています。
関数は左から順に下記のように記述しました。
if文の条件等はお好みでそれぞれ変更してください。

```
=IF(B4="","", IF(B4>=$B$2,"a",IF(B4=0,"c","b")))
=IF(D4="","", IF(D4>B4,0,IF(D4>=B4*30%,"a",IF(D4>=1,"b","c"))))
=IF(F4="","", IF(F4>D4,0,IF(F4>=D4*10%,"a",IF(F4>=1,"b","c"))))
```
![スクリーンショット 2020-09-25 12.48.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700999/b9f72310-9b7b-22c1-e9d0-a106351ecad7.png)

## スコアをまとめる
Q列にある文言を取得すためのスコアになります。
ただ文字列をまとめるだけです。

```
=C4&E4&G4
```
![スクリーンショット 2020-09-25 12.48.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700999/f0875932-fdca-d6b5-ba31-ced289469d8e.png)

## まとめたスコアと一致する文言を取得する
下記のようにvlookup関数を用いてH列の文言の検索をかけていきます。
検索値　H4
検索範囲　P2:Q16の一番左
検索結果出力　Q列の文言を出力
FALSE　完全一致したものだけを抽出

```
=IF(H4="","", VLOOKUP(H4,$P$2:$Q$16,2,FALSE))
```

![スクリーンショット 2020-09-25 12.48.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700999/533a4366-3439-cedf-c26e-da41660a3077.png)

こちらの文言が目標物の
「まとめると、、、」以下に続きます。

これで下準備は完了です。
次回は実際にGASを編集していきます。
php・可変変数に配列を渡す

環境
初書：2020/09/27
PC：macOS 10.15.7
php 7.4.10

# 前置き

PHPで可変変数を扱う時があったのだが、その時にかなり手こずったのでメモ。

# 前提
可変変数の知識

# コード（失敗例）

```php:index.php
class cls {
    public string $str1;
    public string $str2;
    public function __construct(){
        $this->str1 = "aa";
        $this->str2 = "bb";
    }
}

$ouc = new cls();
```

とりあえずクラスを用意して、インスタンスした。
そしてこの後、str変数にアクセスしたいのだが、この時に少し変わったことをする。

```php:index.php
$arr[] = "str1";
$arr[] = "str2";

$ouc->$arr[0] = "cc";
```
何をしたいかというと、`$arr[0]` = "str1"、つまり`$ouc->str1 = "cc";`を行おうとした。
一見問題なく実行できそうだが、実はnoticeが発生する。

```
PHP Notice: Array to string conversion in php
```
これは配列を文字列として扱おうとした際に起こるエラーである。
だが、パッと見では特に不具合がある場所はない。

# エラーの原因

原因自体は単純で、構文の解析方法が思っているのと違うということ。
PHP7以降の構文解析は、

```txt
$ouc->$arr[0] = "cc";
      ¯¯¯¯           // 1
¯¯¯¯¯¯¯¯¯¯¯¯¯        // 2
```
という順番になる。
つまり、$arr (=Array。配列なので）を先に返し、
`$ouc->Array[0]`に`cc`を代入しようとしたのである。（そして実際に代入した）
そのため、`var_dump($ouc)`を行うと、

```php
object(cls)#1 (3) {
  ["str1"]=>
  string(2) "aa"
  ["str2"]=>
  string(2) "bb"
  ["Array"]=>
  array(1) {
    [0]=>
    string(2) "cc"
  }
}
```
という形になる。

# 対処法
可変変数の別の記述方法である

```php
$ouc->{$arr[0]} = "cc";
```
という風に、全体を`{}`で括って正しい順番で解析してもらうか、一旦別の変数に置く。

# 終わりに

このバグに遭遇した場合、（構文解析の順番を知らない場合は）エラー文をみてもこれが原因だということに気付けない上に、エラー箇所より前の時点でログを出しても特に見つからない[^1]ので（もちろん、あとでvar_dumpするとすぐにわかるのだが）、頭の片隅に入れておいてもいいかもしれない。

[^1]: `$arr[0]`単体でechoしても、`cls`をvar_dumpしても気付かないし、issetしても…falseになるから気付くかもしれない。自分はエラーに気を取られて戻り値が来ている事に気付いてなかった。

# 参考サイト
- [PHP研修 each()関数と配列の可変変数のPHP7.2対応](http://www.gigas-jp.com/appnews/archives/6318)
【Xcode11】Xcode encountered an error が発生した

## 事象
![スクリーンショット 2020-09-27 15.42.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263659/7061539c-dd77-6fe9-b134-9465a1e8ecaa.png)

プロビジョニングプロファイルを上書きインストールしようとしたら上記のエラーが発生した。

## 対処法
既存のプロビジョニングプロファイルを削除してからインストールする。
手順は下記の通り。

1 下記のスクショのように、上書きしたいプロビジョニングプロファイルのinfoマークからピンクで囲ったファイルをドラッグアンドドロップでDesktopなどに置く。

![スクリーンショット_2020-09-27_15_41_15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263659/c24a8795-4e98-2968-f02a-a0a7dd00d9e5.png)

2  ファイル名をコピーしておく
3  `cd ~/Library/MobileDevice/"Provisioning Profiles"` でプロビジョニングプロファイルのディレクトリまで移動する。
4 `rm {手順2でコピーしたファイル名}` で削除する。
5 新しいプロビジョニングプロファイルをインストールする。
6. 下記のスクショのようにエラーが出るので、Updateボタンを押下する。

![スクリーンショット_2020-09-27_15_45_25-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263659/a7bf2e85-83ab-3dad-8b2c-516339d9b685.png)
[ WordPress ] プラグイン Custom Field Suite の関連ポストの情報を、投稿ページに表示させる

WordPress のプラグイン Custom Field Suite には「関連ポスト」というフィールドがあります。今回、記事に投稿者を紐づけたいと思いましたが、WordPress にそもそも備わっている author は以下の理由から避けました。

##【避けた理由１】セキュリティ
何も対策せず投稿者を作ると、下記のURLが生成されます。

https://example.com/author/tanaka/
https://example.com/author/sato/

authorのユーザー名は、そのままWordPressのログインIDとなります。わざわざ晒したくないところです。

##【避けた理由２】メールアドレスが必須
ログインIDとなるということは、大抵のサービスと同様、ユーザーを作る際にメールアドレスが求められます。今回、記事に紐付けたい投稿者は50名を超えていました。

##Custom Field Suite の関連ポストの情報を、投稿ページに表示させるソースコード
以上の2つの理由から、まずカスタム投稿タイプの機能を使って「投稿者」を作り、投稿者名や所属、略歴などを入力するようにしました。そして、その投稿者の情報を、投稿に紐づけるため、 Custom Field Suite で「関連ポスト」のフィールドを投稿に用意し、投稿者を紐付けました。

その関連ポストの情報を投稿に表示させるソースコードが下記です。特に get_post_meta や wp_get_attachment_image が工夫した点です。

```
<?php
$values = CFS()->get('kanrenpost');
foreach ($values as $post_id):
setup_postdata( $post_id );
  $rslink = get_permalink($post_id);
  $rstitle = get_the_title($post_id);
  $rsoriginalname = get_post_meta($post_id,'kanrenpost__originalname',true);
  $rsoriginalimage = wp_get_attachment_image(get_post_meta($post_id,'kanrenpost__originalimage',true));
?>
	<a href="<?php echo $rslink ?>">
		<?php echo $rstitle ?>
		<?php echo $rsoriginalname ?>
		<?php echo $rsoriginalimage ?>
	</a>
<?php endforeach; ?>
```

##参考URL
[WordPress：Custom Field Suiteの使い方からカスタマイズまで | 新宿のホームページ制作会社 ITTI（イッティ）](https://www.itti.jp/web-design/how-to-display-custom-field-suite/)
[関数リファレンス/get post meta - WordPress Codex 日本語版](https://wpdocs.osdn.jp/%E9%96%A2%E6%95%B0%E3%83%AA%E3%83%95%E3%82%A1%E3%83%AC%E3%83%B3%E3%82%B9/get_post_meta)
[]()
Rがどこのディレクトリを見に行っているか確認する

## 環境・補足事項

<dl>
<dd>RStudio Version 1.3.1093</dd>
<dd>Mac Mojave バージョン10.14.6</dd>
<dl>

動作確認済み。

##シチュエーション

エクセルファイルを読むパッケージをインストール。
エクセルファイルを読みに行きたいが、どこのディレクトリを読んでいるのかよくわかってない。
適当に書いてみると当然エラー文。

```R
install.packages('openxlsx')
library(openxlsx)
phys <-read.xlsx('sampledata2.xlsx')
```

####エラー文
read.xlsx.default("sampledata2.xlsx") でエラー: File does not exist.

私「まあそう出ますよね。」

##対処方法

```R
getwd()
```

上記により、Rが読みに行っているデフォルトのディレクトリが出てくる。

私の場合はDesktopディレクトリの下に該当ファイルを配置していた。
よって、下記のように書くことで解決した。

```R
phys <-read.xlsx('Desktop/sampledata2.xlsx')
```

ちなみに、基本読み込むディレクトリを一箇所に決め打ちしたなら
（例えば、Desktop/forRstduyData/　のようにデスクトップディレクトリにR用のものを用意したとか）
下記のようにして読み込むディレクトリを変更することも可能。

```R
setwd('Desktop/forRstudyData')
```

デフォルトディレクトリに戻したいならば、

```R
setwd('デフォルトディレクトリを確認した時のパス')
```

とすれば良い。

##追記

後述するテキストでは面倒臭くなる。
データの読み込み方として、
①エクセルファイルでコピー
②下記を打って内容を読み取り

```R
scan('clipboard')
```

とあるが、これはウィンドウズ専用。

macでは

```R
read.table(pipe("pbpaste"))
```
とすることで解決。

##最後に

「Rで学ぶ確率統計学」という書籍で勉強している。
微積分と統計学の基本的な教科書を読んで式に慣れたら取り組むと面白い教科書かと思う。
データを活用することを想定した時、疑問に思っていたことが氷解していく感覚を得られたため、オススメしたい逸品である。

##参考資料
https://datumstudio.jp/blog/r%E3%81%A7excel%EF%BC%88xlsx%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%EF%BC%89%E3%82%92%E8%AA%AD%E3%81%BF%E8%BE%BC%E3%82%80

http://riseki.php.xdomain.jp/index.php?R%E3%81%A7%E3%82%AF%E3%83%AA%E3%83%83%E3%83%97%E3%83%9C%E3%83%BC%E3%83%89%E3%81%8B%E3%82%89%E3%83%87%E3%83%BC%E3%82%BF%E3%82%92%E8%AA%AD%E3%81%BF%E8%BE%BC%E3%82%80
BUFFALO の外付けHDDをFAT32にフォーマットする方法　（2020年9月）

#1.DiskFormatter2 をダウンロードし、パソコンにインストールします。
[DiskFormatter2はこちらから](https://www.buffalo.jp/support/faq/detail/14772.html)
![buffalo2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/ee6c1cb2-52a3-ddbb-11b4-1b420474e933.png)

#2.パソコンにフォーマットする外付けハードディスク/SSD/USBメモリーを接続します。

#3.DiskFormatter2を起動します。

![buffalo.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/d9fdac7e-71bc-100a-6109-a5561aaee833.png)

以上で設定は終わりです:blush:
HTTPメソッド 私的まとめ


RestfulではCRUDは同じアドレスでHTTPメソッドに違いで処理が分けられる


|HTTPメソッド|CRUD|
|---|---|
|GET|Read。レコード取得|
|POST|Create。レコード新規作成|
|PUT|Update。レコード更新|
|DELETE|Delete。レコード削除|

HTTPメソッド一覧


|HTTPメソッド|意味|
|---|---|
|GET|指定したリソースの表現をリクエストします。 GET を使用するリクエストは、データの取り込みに限ります。|
|HEAD|GET リクエストと同じレスポンスを求めますが、レスポンス本文はありません。|
|POST|指定したリソースに実体を送信するために使用するメソッドであり、サーバー上の状態を変更したり、副作用が発生したりすることがよくあります。|
|PUT|対象リソースの現在の表現の全体を、リクエストのペイロードで置き換えます。|
|DELETE|指定したリソースを削除します。|
|CONNECT|対象リソースで識別されるサーバーとの間にトンネルを確立します。|
|OPTIONS|対象リソースの通信オプションを示すために使用します。|
|TRACE|対象リソースへのパスに沿ってメッセージのループバックテストを実行します。|
|PATCH|リソースを部分的に変更するために使用します。|


参考：[HTTPリクエストメソッド](https://developer.mozilla.org/ja/docs/Web/HTTP/Methods)

Laravelのリソースコントローラのリソースアクションは以下

|処理|アクション|
|---|---|
|一覧表示|index|
|新規作成|create,store|
|レコード表示|show|
|更新処理|edit,update|
|処理処理|destroy|
Laravel7継承レイアウトの基本を図解してみた

#絵に描いてみた
LaravelのBlade式のレイアウトに関して、巷には教科書や公式ドキュメントなど説明がありますが、文学よりも漫画で育ってきた私は理解するのに思ったより苦労しました。
その時、こんな図解があったらいいな...と思っていた絵を描いてみました↓

![Laravel継承レイアウト (1).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/645077/d126c035-2e37-1d1b-b11f-35d38fb9c452.jpeg)

このindex.blade.phpブラウザで表示するとこうなります↓
![スクリーンショット 2020-09-27 16.12.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/645077/e1c5acb2-bb06-512e-780c-3a176e96d280.png)

#文字でまとめると
* **ベースレイアウト（親）で用意できるもの**
`@yield('')`：子のsectionやsection+endsectionを受け付ける。
`@section('')` + `@show`：子のsection+endsection(+parent)を受け付ける。感覚的にはendsectionで締められそうですができません。


* **継承レイアウト（子）で使えるもの**
`@extends('')`：これ無いと始まらない
`@section('')`：yieldに対して使う。
`@section('')` + `@endsection`：これもyieldに対して使う。
`@section('')` + `@endsection` (+`@parent`)：section-showに対して使う。parentが使えることも特徴。

#最後に
以上です。お役に立てれば幸いです。また、何かご指摘があればぜひお願いします。
Pythonによる画像処理100本ノック#8 Maxプーリング

## はじめに
どうも、らむです。
今回は画像をグリッド分割する手法であるプーリング処理の中でも、領域中の最大値を代表値とするMaxプーリングについて実装します。

## 8本目：Maxプーリング
前回説明したプーリングとは、画像を固定長の領域にグリッド分割し、その領域内の値を全てある値にする処理です。この処理を施すことで画像はモザイク状になります。
Maxプーリングでは領域内の画素値の最大値で領域内を埋めます。
平均プーリングとMaxプーリングの違いは平均値を用いるか最大値を用いるかという点のみです。

## ソースコード

```maxPooling.py
import numpy as np
import cv2
import matplotlib.pyplot as plt


def maxPooling(img,k):
  dst = img.copy()

  w,h,c = img.shape
  # 中心画素から両端画素までの長さ
  size = k // 2

  # プーリング処理
  for x in range(size, w, k):
    for y in range(size, h, k):
      dst[x-size:x+size,y-size:y+size,0] = np.max(img[x-size:x+size,y-size:y+size,0])
      dst[x-size:x+size,y-size:y+size,1] = np.max(img[x-size:x+size,y-size:y+size,1])
      dst[x-size:x+size,y-size:y+size,2] = np.max(img[x-size:x+size,y-size:y+size,2])

  return dst


# 画像読込
img = cv2.imread('image.jpg')

# Maxプーリング
# 第2引数は領域長
img = maxPooling(img,40)

# 画像保存
cv2.imwrite('result.jpg', img)
# 画像表示
plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
plt.show()
```

<img width="300" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519081/5f7ccd93-cb2d-f14b-9004-0fd116035c34.jpeg">　<img width="300" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519081/9b66587a-3f2c-5a21-0146-192b3be445c9.jpeg">　<img width="300" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519081/ab250c7d-e6ca-5114-7ddf-869b4e6e01ba.jpeg">


画像左は入力画像、画像中央は前回の平均プーリング、画像右は今回の出力画像です。
上手くモザイク状の画像になっていることが分かりますね。また、輝度の高い最大値を使っているだけあって画像全体が平均プーリングよりも明るくなっています。


## おわりに
もし、質問がある方がいらっしゃれば気軽にどうぞ。
imori_imoriさんの[Github](https://github.com/yoyoyo-yo/Gasyori100knock/blob/master/Question_01_10/answers_py/answer_6.py)に公式の解答が載っているので是非そちらも確認してみてください。
それから、pythonは初心者なので間違っているところがあっても優しく指摘してあげてください。
WSLでsshpassを使ってscpファイル送信②

# 初めに
WSL(Ubuntu)で、シェルを実行したら、パスに記載しているファイルを指定サーバー上の指定フォルダに転送する。
今回はパス毎で転送先を指定できるような形式
どこまでファイルにして、どこまで実行ファイルに書くかはお好みで
2020/10/7 修正

# 実行(確認)環境
WSL2 
Ubuntu 18.04
CentOS7（格納先）


## フォルダ構成

```
# 実行フォルダ（どこでも大丈夫なハズ）
c:\test\
 ├ transport.sh
 ├ filepath(パスを記載)
 └ passfile(パスワードを記載)

# 転送ファイル群
c:\temp\
 ├ test1.txt
 ├ test2.txt
 └ test3.txt
```

## ソース
### 設定ファイル系 
``` text:filepath
C:/temp/test1.txt,/root/temp1
C:/temp/test2.txt,/root/temp2
C:/temp/test3.txt,/root/temp3
```
※改行はLFで

``` text:passfile
hogehoge
```
※１行で記載する必要あり

### シェルスクリプト
``` Shell:transport.sh
#!/bin/bash

# sshのユーザー名
USERNAME="root"
# サーバーのホスト
SERVERHOST="XXX.XXX.XXX.XXX"

# ファイルパスをループ
for line in `cat filepath`
do
    # 分割
    arr=(${line//,/ })
    # ローカルファイルパス変換
    upfiles=$(wslpath -u ${arr[0]})
    # サーバーパス
    serverpath=${arr[1]}
    # 送信情報をセット
    transports=$transports" ${upfiles} ${USERNAME}@${SERVERHOST}:${serverpath}"
done
# 送信
sshpass -f passfile scp -o StrictHostKeyChecking=no $transports
```

# 実行(一応)
``` Shell:
cd /mnt/c/test/
./transport.sh
``` 

bin/shでの配列操作が分からなくて、bin/bashに変更、、
ていうか、違いなんて知らなかった、、
~~まぁ、実用性は遅すぎてほぼ０です、、~~
１つのsshpassに指定できるので、実用性はだいぶ上がるはず
jQueryのプラグインを複数追加したら動かない

##はじめに 
自分の振り返りを兼ねて、ここに記していきたいと思います。
jQueryのプラグイン「drawer.js」を新たに実装したとき、ディベロッパーツールでエラーが起きていることを発見しました。
原因と解決方法を記していきたいと思います。
##原因
Uncaught TypeError: $(...).drawer is not a function at HTMLDocument.<anonymous> (index.html:747)
一体なんだ？と詳しくみてみると
エラー箇所はHTML内の下記に示されていました。
ただし、コード自体に誤りはなさそうでした。

```html

<script>
$(document).ready(function() {
  $('.drawer').drawer();
});
</script>
```

上記の場合だけでは、反映することができず、ドロワーメニューは開くことができません。
いろいろ調べた結果、、、
今回の場合は、他のプラグインを入れていることで動かなくなっている
つまり、**コンフリクト（プラグイン同士の競合）** が原因でした。
##解決方法
先ほどのコードに下記のコードを追加しました。

```html

<script>
jQuery.noConflict(); 
(function($) {
 
$(document).ready(function() {
  $('.drawer').drawer();
});
})(jQuery);
</script>
```

`jQuery.noConflict();`を追加することで解決することができました。
KubernetesでEvictedのPodを自動的に削除する

# TL;DR
###  手法１. CrontabにEvictedのPodを削除するコマンドを追加する。
crontabにEvictedのpodを一括削除するコマンドを登録する。

```
$ crontab e
インタラクティブモードになるので下記の行を追加する。１分間に1回、default namespaceに属するEvictedのPodを一括削除する。
* * * * * /usr/bin/kubectl get pod -n default | grep Evicted | awk '{print $1}' | xargs kubectl delete pod -n default
```

###  手法２. kube-controller-managerにステータスがterminatedになっているPodを削除する設定を追加する。
```
sudo su -
vi /etc/kubernetes/manifests/kube-controller-manager.yaml
インタラクティブモードになるのでspec.containers.commandに下記を追加する。
- --terminated-pod-gc-threshold=1
```
# 目的
Kubernetes上でPodを起動しているとメモリ不足やディスク容量の問題で、PodがEvictedの状態になり大量に溜まってしまう現象がたまにあります。このEvictedのPodを一括で消すコマンドがQiitaの記事に紹介はされていましたが、自動的に消したくなったので今回検証しました。

# 検証環境
下記の環境で検証しました。
OS: Ubuntu 18.04
kubernetes v1.18.4
kubernetesのセットアップはkubeadmを用いました。

# 手法１ CrontabにEvictedのPodを削除するコマンドを追加する。
一番直感的にわかりやすい方法です。KuberntesのEvictedのPodを一括削除するワンライナーをcrontabに登録します。詳しくはcrontabの設定方法をネットで調べてもらいたいのですが、実行頻度も定義することができます。Evictedは秒単位で発生するような頻繁な事象ではないため、十分これで対応できると思います。

## 手順
下記のコマンドでcrontabに設定を追加します。ubuntuのユーザーはkubernetesをインストールした時のユーザーで実行して下さい。

```
$ crontab e
インタラクティブモードになるので下記の行を追加する。１分間に1回、default namespaceに属するEvictedのPodを一括削除する。
* * * * * /usr/bin/kubectl get pod -n default | grep Evicted | awk '{print $1}'
```

# 手法2 kube-controller-managerにステータスがterminatedになっているPodを削除する設定を追加する。
kube-controller-managerのコマンドにオプションを追加することで、PodやコンテナイメージのGarbage Collection機能を設定することができます。[詳しくはKubernetesのドキュメント](https://kubernetes.io/docs/reference/command-line-tools-reference/kube-controller-manager/)を参照してください。

## 手順
私はkubeadmでkubernetesをインストールしたので、kube-contoller-managerのマニフェストファイルに設定を追加する方法で行いました。
terminated-pod-gc-thresholdという設定を追加するのですが、ここに閾値を設定することでterminatedとなったコンテナの数が閾値より大きくならないようにkube-controller-managerが削除します。（デフォルト値は12500となっており機能するタイミングはほとんどありません。）
今回は閾値を1に設定しているので、terminated状態のPodが1より増えないように設定しています。

```
sudo su -
vi /etc/kubernetes/manifests/kube-controller-manager.yaml
インタラクティブモードになるのでspec.containers.commandに下記を追加する。
- --terminated-pod-gc-threshold=1
```
DockerでAzureKinectDKを動かそうと思ったらEULAに阻まれた件

# DockerでBuildしようと思ったそのときに
よくわからんがDockerでROSを動かしてAzureKinectDKを動かそうを思いました。
ですがなんとまぁ謎の認証EULAくんの登場によって阻まれたのでした.

## 僕の環境
| OS| MacOS catalina 10.15.7 |
|:-:|:-:|
|Docker Desktop | 2.3.5|

## 問題となった症状
Dockerfileにて

```Dockerfile
### 前略 ###
RUN sudo apt update && apt install k4a-tools libk4a1.4-dev
### 攻略 ###
```

としてDocker build .... をすると謎の文

```出力
Do you accept the EULA license terms? [yes/no] 
```

ときかれてyesを入力しても進まないという現象に見舞われました.

多分このパッケージのインストールに認証が必要なんでしょうねぇみたいに思ってinstallのオプションに-yを追加しましたが無事無視されニッチもサッチもビルドが進まないという感じになりました.

## 驚くほど簡単な解決法
問題となっているパッケージのインストール部分(今回で言えば k4a-tools libk4a1.4-devかな？）のコマンドを

```Dockerfile
RUN audo apt update && apt install ACCEPT_EULA=y k4a-tools link4a1.4-dev
```

ACCEPT_EULA=yをつけるだけでそのまま勝手に認証をしてくれます.

仮に他のパッケージのインストール時に出てきたとしてもこれつけとけばOKです.(多分)
JavascriptにおけるHello Worldの例

#####概要
このチュートリアルは、HTMLページにJavascriptコードを埋め込む方法について示します。

HTMLページにJavascriptを記述するには\<script\>要素を使用します。
HTMLページにJavascriptを記述する方法は、以下の2つがあります。

* HTMLページに直接Javascriptコードを埋め込む
* 外部にJavascriptコードを記載したファイルを作成し、それを参照する

#####HTMLページへのJavascriptコードの埋め込み
HTMLページに直接Javascriptコードを埋め込むことは、推奨されていません。
この方法で記載する場合は、検証目的にみにするべきであります。
\<script\>要素に記載されたJavascriptコードは、上から下まで解釈されます。

```html
<!DOCTYPE html>
<html lang="jp">
<head>
    <meta charset="UTF-8">
    <title>JavaScript Hello World Example</title>
    <script>
        alert('Hello, World!');
    </script>
</head>
<body>
</body>
</html>
```
上の例では、\<script\>要素の中でalert()関数を使用することによりHello, World!メッセージを画面に表示します。

#####外部Javascriptファイルの読み込み
以下に、外部Javascriptファイルを使用する方法を記載します。
１．拡張子.jsのファイルを作成する(例：main.js)
２．jsファイルを保存するフォルダーを作成し、１で作成したフィアルをその中に保存する
３．HTMLファイルの\<script\>タグ内にsrc属性で２で作成したファイルを指定する

HTMLファイルの記載例

```html:default.html
<!DOCTYPE html>
<html lang="jp">
<head>
    <meta charset="UTF-8">
    <title>JavaScript Hello World Example</title>
    <script src="js/mail.js"></script>
</head>
<body>
</body>
</html>
```
main.jsファイルに以下の内容を記載し、default.htmlを開くと"Hello, World!"とメッセージが表示される。

```javascript:main.js
alert('Hello, World!');
```
１つのページに複数のJavascriptファイルを読み込ませる場合、表示されている順に実行される。

```javascript
<script src="js/main1.js"></script>
<script src="js/main2.js"></script>
```
この例では先にmain1.jsが実行されその後、main2.jsが実行される。
Javascriptファイルを読み込ませる記述は、\</body\>タグの直前に記載するほうがよい。
それは、ページのレンダリングフェーズにおいてブランクページが表示されるからです。

#####async及びdefer属性
Javascriptコードのロードと実行する方法を変えるために、\<script\>要素内にasync及びdefar属性を使用することができます。

これらの属性はJavascriptファイルを外部に置く場合のみ作用します。
async属性は、Webブラウザに非同期にJavascriptを実行するように指示するものです。
この属性は、Javascriptファイルを順番に実行することを保証しないものです。
以下の例で言えば、必ず最初にmain.jsが実行されるわけではないということになります。

```javascript
<script async src="main1.js"></script>
<script async src="main2.js"></script>
```

defar属性を使用すると、ドキュメントが全て解析された後にJavascriptファイルが実行されます。

```javascript:default.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>JavaScript defer demonstration</title>
    <script defer src="main.js"></script>
</head>
<body>
</body>
</html>
```
このページでは、HTMLファイルの中でJavascriptを使用する方法について記載しました。
InstagramのDMを保存する方法

# 背景
最近は、LINEよりもインスタグラムのDMを使用する方が増えてきたようです。
しかし、インスタグラムのDMはメッセージを検索したり、遡りすることができません。
そこで、インスタグラムの画面から、JavaScriptを実行して、テキストとして保存する方法をご紹介します。(利用規約的にもセーフだと思います。アウトだったら消します)

# 手順
手順を示します。途中で失敗したら、ブラウザの更新ボタンを押して、やり直してください。

1. PCブラウザで保存したいDM画面を開きます。https://www.instagram.com/direct/t/[番号]
2. ブラウザの検証機能を開き、コンソール画面を開きます。
3. 以下のコードを実行して、保存したいところまで遡ります。(量が多いと時間かかります)

```
timer = setInterval(() => {
  document.getElementsByClassName('frMpI  -sxBV')[0].scrollBy(0, -window.innerHeight);
}, 100)
```
4.保存したいところまで来たら、以下のコードで止めます。

```
clearInterval(timer);
```
5.テキストファイルとして保存します。

```
out = document.getElementsByClassName('VUU41')[0].innerText
let blob = new Blob([out],{type:"text/plan"});
let link = document.createElement('a');
link.href = URL.createObjectURL(blob);
link.download = 'out.txt';
link.click();
```
SwiftLog、XcodeのOutput出力であれば、バックエンド使わず、Extension追加で賄う

# SwiftLog
[https://github.com/apple/swift-log](https://github.com/apple/swift-log)

Swift Packageです。

# Extension

```swift
import Logging

extension Logger {
    static var level = Logger.Level.info
    
    init(function: String = #function) {
        self.init(label: function)
        self.logLevel = Logger.level
    }
    
    func trace(_ message: String = "" , function: String = #function, line: Int = #line) {
        self.trace(Logger.Message(stringLiteral: String("[\(function):\(line)] \(message)")))
    }

    func debug(_ message: String = "" , function: String = #function, line: Int = #line) {
        self.debug(Logger.Message(stringLiteral: String("[\(function):\(line)] \(message)")))
    }

    func info(_ message: String = "" , function: String = #function, line: Int = #line) {
        self.info(Logger.Message(stringLiteral: String("[\(function):\(line)] \(message)")))
    }

    func notice(_ message: String = "" , function: String = #function, line: Int = #line) {
        self.notice(Logger.Message(stringLiteral: String("[\(function):\(line)] \(message)")))
    }

    func warning(_ message: String = "" , function: String = #function, line: Int = #line) {
        self.warning(Logger.Message(stringLiteral: String("[\(function):\(line)] \(message)")))
    }

    func error(_ message: String = "" , function: String = #function, line: Int = #line) {
        self.error(Logger.Message(stringLiteral: String("[\(function):\(line)] \(message)")))
    }

    func critical(_ message: String = "" , function: String = #function, line: Int = #line) {
        self.critical(Logger.Message(stringLiteral: String("[\(function):\(line)] \(message)")))
    }
}
```

# Example

```swift
import UIKit
import Logging

class ViewController: UIViewController {

    let logger = Logger()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        logger.info()
        logger.info("start")
 :
 :
 :
```
OracleからAzure DB（PostgreSQL）へ移行する~⑪データベースの移行（Oracle2Azure Database for PostgreSQL）

OracleからPostgreSQLへのことなるRDBMSへのデータベースの移行に関する考え方を記載します。
#データベース移行の目標
OracleからPostgreSQLへのことなるRDBMSへの移行を実現する場合、RDBMSそのものの優劣を比較するのではなく、データベースを利用しているシステムそのものの目線で、「As-Is(現状)」と「To-Be（あるべき姿）」を把握する必要があります。この「As-Is(現状)」と「To-Be（あるべき姿）」に対するFit&Gap確認して、課題を明確化するようにします。

Fit&Gapの分析で出てきたGapに対して、Gapを埋めるために、どのように対処していくかを検討していきますが、To-Beに限りなく近づけることで、膨大な修正費用がかかってしまう事も多くあります。現実的な落としどころである「Can-Be（現実的解）」を模索することも重要です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/697647/3de20335-f7d9-63a6-c3ea-f36929aa8c91.png)

#移行タスクの全体の流れ
移行タスク全体の流れは大きく以下のような流れで進行させます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/697647/eaa45d45-1fb1-6478-4d94-a17d872e17a5.png)

また、実際の作業に取り掛かる前に、より全体の作業に対する規模感、スケジュール感などを算出するために、PoCを実施するのも有効な手段です。
PoCを実施する場合、現行調査フェーズ、計画フェーズ、移行検証フェーズの３つの観点フェーズを中心に実施する事になります。
また、可能な限り性能テストも行います。一般的にPL/SQLなどはOracleに比べてPostgreSQLの方がロジック実行にて遅くなることが多い為、どれぐらい遅くなるのか、ロジック実行の見直し（ループ処理などを１つのSQLで実行可能にするなど）による性能が改善可能かを確認します。
※移行検証フェーズに関してはPoCでは全て実施は行わず一部のみを対象とし全体を類推することもあります。

##現状調査
現状調査では主に以下の事を実施します。

* 現行リソースの調査
現状のサーバに搭載されているCPU数とメモリ、ストレージの容量を把握します。ここから、実際の利用状況を確認し、必要なCPU数、メモリ、ストレージを算出します。例えば、Oracle Databaseが4コア2CPUのサーバ上で稼働しており、CPU使用率が25%程度が最大の場合には、まずはAzure for PostgreSQLのスペックは2仮想コア程度からスタートするのが望ましいと考えられます。また、メモリ、ストレージに関しても現状利用状況と合わせた形でAzure for PostgreSQLのスペックを選定するのが望ましい事になります。足りなければすぐにスケールアップ可能なのもクラウドの大きなメリットな為、緻密に計算する必要は無くあくまで目安を立てるのが重要です。目安を立てるために、現状のスペック及び利用状況を把握します。
    * Azure for PostgreSQLでは最大接続数も重要   
    Azure for PostgreSQLでは最大接続数もスペック選定の重要な要素です。
    スペックによって[最大接続数](https://qiita.com/masahiro-yamaguchi/items/aaff88e13c95667761e4)が決まっています。

* ソースDBの調査
ソースとなるOracle DBの調査も重要な要素です。以下の項目を対象となるOracle DBから情報を収集し、移行できないオブジェクトの有無などの確認を行います。
    * オブジェクトの総数
    * テーブルやインデックスの容量
    * 文字コード
    * 利用オプション
    * 初期化パラメータ
    * Dumpファイル（メタデータのみ）
    
特にDumpファイルは重要でこのDumpファイルのデータでメタデータのみのOracle Databaseのコピーを作成し、Ora2PGなどのツールにより自動でのマイグレーション変換率を計測します。

#移行難易度の判定
移行難易度は、主にこれらの要素により判定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/697647/1e6447dc-911c-0370-7fea-50a5c05ef227.png)

移行元のOracleでOracle特有のオプションを利用していた場合、代替手段を考える必要がある為、移行難易度は上昇します。また、本番移行時の停止時間や、移行判定の基準等もヒアリングし、総合的な移行難易度を判定します。

同じデータ量、移行難易度でも、本番移行に丸1日かけることができる場合、移行後の確認等に時間を掛けることができますが、半日しか停止できない場合、移行後の確認にかけることのできる時間は減少してしまい品質の担保を工夫する必要が出てきます。

また、移行判定（パフォーマンスなど）が厳しい場合、移行リハーサル等を重ねてより洗練していく必要がありますので、難易度としては高くなります。

#移行コストの見積
移行難易度や移行までに準備できる期間等を考慮し、移行コストの見積もりを実施します。

POCの場合、POC対象としたシステムの移行結果などを踏まえ、実際の本番移行に向けた精緻なコストの見積を算出します。

#移行計画
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/697647/7e9cbb2d-cebe-ca34-e16c-f09edb962328.png)
実際に移行を行っていくうえで、計画をしっかり決め実施していく必要があります。PoCの結果やヒアリングした内容をもとに計画を策定していきます。

例えば、対象のシステムが保守期限切れになる場合には、期限切れになる前に移行をしなければなりません。そのために移行準備にかけられる期間・移行のテストにかけられる期間を算出し、移行までのスケジュールを決めておく必要があります。

また作業を実施する部署やベンダーが複数ある場合には、各作業の作業範囲を明確化して、役割分担をしておく必要があります。

その他にも本番移行時のシステムを停止しておける時間や、万が一システムの移行に問題があった際に復旧できるようにコンティンジェンシープランの策定、移行が完了した際に何を持って移行が成功しているのかを決めるための判定基準など決めておく必要があります。

#最後に
今回はデータベース移行までの流れを記載しました。

##次回は
移行時に使用するツール群について記載します。
【Azure】AzureLogAnalyticsログクエリまとめ＃1 パフォーマンス

LogAnalyticsWorkspaceで対象VMのパフォーマンスを抽出するときにお便利なクエリ集です。前提として、対象VMへの設定が必要になります。(秒でできる設定です:ok_hand:)

[設定方法-LinuxOS](https://docs.microsoft.com/ja-jp/azure/azure-monitor/platform/data-sources-performance-counters#linux-performance-counters)
[設定方法-WindowsOS](https://docs.microsoft.com/ja-jp/azure/azure-monitor/platform/data-sources-performance-counters#windows-performance-counters)

抽出されたデータをもとに、アラートやダッシュボードも作成できます。メトリクスを使ったアラート/ダッシュボードよりもカスタマイズが効くので、お便利かなと思います。

#CPU

```
Perf 
| where Computer == "対象VM" 
| where ObjectName == "Logical Disk" and CounterName == "% Used Space" and InstanceName == "_Total" 
```

特定のコンピューターの CPU 使用率の平均、最小、最大、75 パーセンタイル (1 時間ごと)
※InstanceName <> **"_Total"** の箇所は実機に合わせてください

```
Perf 
| where CounterName == "% Processor Time" and InstanceName == "_Total" and Computer == "対象VM"
| summarize ["min(CounterValue)"] = min(CounterValue), ["avg(CounterValue)"] = avg(CounterValue), ["percentile75(CounterValue)"] = percentile(CounterValue, 75), ["max(CounterValue)"] = max(CounterValue) by bin(TimeGenerated, 1h), Computer
```

特定のコンピューターのfree

```
Perf 
| where Computer == "対象VM" 
| where ObjectName == "Logical Disk" and CounterName == "Free Megabytes" and InstanceName == "_Total" 
```

#RAM
vm全体のメモリ使用率

```
Perf 
| where Computer == "対象VM"  
| where ObjectName == "Memory" and CounterName == "% Used Memory" 
```

プロセッサ時間の平均、50 パーセンタイル、95 パーセンタイルを 1 時間のビンに表示

```
Perf
| where TimeGenerated > ago(1d) 
| where CounterName == "% Processor Time" 
| summarize avg(CounterValue), percentiles(CounterValue, 50, 95)  by bin(TimeGenerated, 1min)
```


#SWAP
swap領域使用率

```
Perf 
| where Computer == "対象VM"  
| where ObjectName == "Memory" and CounterName == "% Used Swap Space"
```
#Local storage

特定のdiskのfree

```
Perf 
| where Computer == "対象VM"  
| where ObjectName == "Logical Disk" and CounterName == "Free Megabytes" and InstanceName <> "_Total"
```

/mnt/src/sasfs1のfreeMegabyteをタイムチャート形式で表示

```
Perf 
| where Computer == "対象VM" and InstanceName == "/mnt/src/sasfs1" 
| where ObjectName == "Logical Disk" and CounterName == "Free Megabytes"
```

論理ディスクのCPU使用率

```
Perf
| where Computer == "対象VM"  
| where ObjectName == "Logical Disk"  and CounterName == "% Used Space" 
```

ディスクの読込み秒数（persec）
※**InstanceName == "/"**の箇所は実機にあわせてください

```
Perf 
| where Computer == "対象VM" 
| where ObjectName == "Logical Disk" and CounterName == "Disk Reads/sec" and InstanceName == "/" 
```

ディスクの書込み秒数（persec）

```
Perf 
| where Computer == "対象VM" 
| where ObjectName == "Logical Disk" and CounterName == "Disk Writes/sec" and InstanceName == "/" 
```

#syslog
SysylogからErrorのみ抽出

```
Syslog 
| where SeverityLevel == "err" 
```

特定のエラーを排除した状態でSysylogからErrorのみ抽出

```
Syslog 
| where SeverityLevel == "err" 
| where SyslogMessage <> "blk_update_request: I/O error, dev fd0, sector 0" 
```
TinyGoの開発環境をVSCode向けにセットアップする

TinyGoのVSCode向け開発環境セットアップがちょっと面倒だったので書き残し。
公式の記事は[ここ](https://tinygo.org/ide-integration/)。
TinyGoのインストール・セットアップは他記事をご参照ください。
筆者の環境 : MacBook Air (Retina, 13-inch, 2020) macOS Catalina 10.15.5

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/335219/4049cd45-96b1-fe1c-be91-1d644156d27a.png)

## 2020/09/27 追記1
``.vscode/settings.json`` は下記TinyGo拡張機能のインストール・セットアップを行えば自動的に生成されるとのご指摘をいただきました。
なので以下``settings.jsonの作成`` パートはスキップしてしまって構いません。


## ~~TinyGoの設定確認~~
~~TinyGoでは本家Goとは別パスにあるGOROOT(?)を使用するようです。[^1]~~
@sago35 さんよりご指摘頂き、TinyGoは``machine``パッケージなどのTinyGo専用パッケージはTinyGoのROOTより解決し、それ以外のimportパスは通常のGo言語の物を使っている(GOPATHも本家Goと同じ)とのことでした。sago35さんありがとうございます！
~~``tinygo info`` でTinyGo用のGOROOTのパスを確認して下さい。~~

```TinyGoのGOROOTを確認する
$ tinygo info microbit
// 出力結果...

// LLVM triple:       armv6m-none-eabi
// GOOS:              linux
// GOARCH:            arm
// build tags:        cortexm baremetal linux arm nrf51822 nrf51 nrf microbit tinygo gc.conservative scheduler.tasks
// garbage collector: conservative
// scheduler:         tasks
// cached GOROOT:     /home/user/.cache/tinygo/goroot-go1.14-f930d5b5f36579e8cbd1c139012b3d702281417fb6bdf67303c4697195b9ef1f-syscall
```

~~``cached GOROOT:... `` で始まる行のパスがTinyGo用GOROOTです。~~
~~``build tags:...`` で始まる行がビルド時に使用するオプションです。~~

## ~~settings.jsonの作成~~
~~VSCodeの設定を直接いじっても良いのですが、通常のGoを用いた開発に影響を出したくないため、プロジェクトフォルダに``.vscode``フォルダを作成し``settings.json`` ファイルを作成します。
その際``GOROOT`` はそのまま貼り付けて問題ないのですが、GOFLAGSは``-tags=``を先頭につけ、スペースに代わりにカンマ(`,`) を使って区切ります。
例えば筆者の環境では``build tags: darwin amd64 tinygo gc.extalloc scheduler.coroutines`` という結果だったため、
``-tags=darwin,amd64,tinygo,gc.extalloc,scheduler.coroutines`` となります。~~

```settings.json
{
    "go.toolsEnvVars": {
        "GOROOT": "さっき取得したGOROOT...",
        "GOFLAGS": "-tags=avr,baremetal,linux,arm,atmega328p,atmega,avr5,arduino,tinygo,gc.conservative,scheduler.none"
    }
}
```


## TinyGo 拡張機能のインストール

Extensionsより[TinyGo](https://marketplace.visualstudio.com/items?itemName=tinygo.vscode-tinygo) をインストールします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/335219/d735c6ab-8ec4-e071-7aab-ec7217ace26c.png)

インストール後、コマンドパレットより`TinyGo target`を選択し、使っているマイコンを選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/335219/6f0c5419-d9d4-5829-1e06-b30411127ee3.png)

筆者の場合Arduino互換機の[Maruduino](https://www.marutsu.co.jp/pc/i/605620/)のため、`arduino`を選択します。[^2]

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/335219/8573db3c-24c0-75d1-59ca-b1dc5f894170.png)

選択後、VSCodeをリロードし"machine"パッケージの自動補完が正しく効けば完了です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/335219/566edd30-7252-7402-9e67-85015bad585c.png)




[^1]: ビルド時にGOROOTとかGOPATHを独自のものに置き換えてビルドしている(?)ようですが詳しくはわからず... どなたかコメントでご教授いただけると幸いです。
[^2]: マイコン初心者の自分にも優しくArduino選びに付き合っていただけました。marutsuさんありがとうございました...!
【盲点】flutterでhot reloadを効かせる

## 結論
> $ flutter upgrade

上記で最新版に保つ。以上。

---

## 参考：調べると出てくる他の要因
- main()の書き換えはhot reloadが適用されない
- コマンドラインツールでflutter runすると適用されない
- debug modeで実行しないと適用されない
AtCoderのレートでTwitterのプロフィールを自動でアップデートしてくれるWebアプリ、AtCoder Twitter Profile Updaterを作った話。

はじめに
======
Twitterで競プロアカウントを運営している方でBioにAtCoderのレートを入れていたりバナー画像をレート遷移グラフに設定している人、それなりにいると思います。
いちいち新しい情報に更新するの面倒ではないですか？
今回はそういう方のためにバナー画像とBioの更新を自動化するツールを作ってみました。

作ったもの 👉 [AtCoder Twitter Profile Updater](https://atcoder-twitter-profile-updater.vercel.app)
GitHub 👉 [makutamoto/atcoder-twitter-profile-updater](https://github.com/makutamoto/atcoder-twitter-profile-updater)

どんなアプリ？
=====
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/582655/98f4f4db-1020-cdc4-2fa8-9b86daa1b0cb.png)

Twitter認証をしてAtCoderIDを入力するとAtCoderから情報をとってきて自動でプロフィールを更新してくれます。
自動更新を有効にすると毎週月曜日(大体土日にコンテストがあるので月曜日にしました)に自動でデータを更新してくれます。

技術解説
=====
レートとレート遷移グラフの取得
-----
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/582655/985b137c-8bd0-96d4-8992-cc6f0c93d26f.png)
このWebアプリは上の画像のようにレート遷移グラフを自動取得します。
これは[Puppeteer](https://github.com/puppeteer/puppeteer)を用いて実現しました。
Puppeteerはいわゆるヘッドレスブラウザというもので、Chromiumをバックグラウンドで起動してページ遷移などの操作やデータ取得、スクショ撮影などをすることができます。
ブラウザをまるまる起動するので重いですが、正確な描画ができるのが特徴です。
Lambdaに日本語フォントが入っていないため、企業コンのタイトルが文字化けするのがたまに傷ですが。（そのうち直します）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/582655/75ed1782-d294-8a5d-b0cb-6fbc442e11e4.png)
Puppeteerを使ってAtCoderのユーザーページを切り出すと、上のような画像が得られます。
Twitterのバナー画像は1500x500じゃないと勝手に切り取られるので、スケールをして余った背景はそれぞれのレートの色で塗りつぶしています。
このアイデアは[このページ](https://lorent-kyopro.hatenablog.com/entry/2020/06/11/152347)を参考にしました。

ちなみに、スケールと塗りつぶしの画像加工は[Jimp](https://github.com/oliver-moran/jimp)を使っています。
他のライブラリのほうが速いのですが、部分的にネイティブコードが含まれていてLambdaで動くか不安でした。
そのため、全てJavaScriptで書かれているJimpを採用しています。

またレート取得についてですが、レート情報もユーザーページに含まれているため、そこから引っこ抜きました。

Bioの更新
-----
Bioの「AtCoder(レート)」という部分文字列を置換するために正規表現を使いました。
具体的な実装はこんな感じです。

```javascript
newBio = bio.replace(/AtCoder\(\d*?\)/g, `AtCoder(${rating})`);
```

フロントエンド
-----
フロントエンドは[Next.js](https://nextjs.org)で、[React Bootstrap](https://react-bootstrap.github.io)を使って実装しました。
特記することは特にありませんが、[Vercel](https://vercel.com)で簡単にデプロイできるので推しです。

バックエンド
-----
今回、はじめてAWSを使ってみました。
構成をGitで管理するために[AWS CDK](https://docs.aws.amazon.com/cdk/api/latest/docs/aws-construct-library.html)を使っています。
これはクラウド構成をTypescriptなどのプログラミング言語で記述できるもので、IDEの補間が使えたりクラウド資源をコンポーネント化したりできるので今回便利に使わせていただきました。

具体的な構成は図を作っておいたのでそちらを見て下さい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/582655/273c5449-f65c-3928-f533-6d4667145366.png)

感想
=====
制作に４日ほどかかりました。
特に苦労したのはAppSync関係のセッティングですかね。（Apache Velocityがうまく書けなかった……）
ただ、習得すれば大きな武器になると思うので精進します！
アクションとインスタンスメソッドって何が違うの？

コントローラーに記述されるこれ

````ruby:XXX.controller.rb
def アクション名
  XXXXXX
end
````

これってアクションとかインスタンスメソッドって言ったり、どっちが正しいの？何が違うの？


###アクション
=>ルーティングで指定されるときの名前

つまり、これはアクション

````ruby:config/routes.rb
Rails.application.routes.draw do
  get 'index' to: "tweets#index"
````

###インスタンスメソッド
=>アクションの指定によって実際に実行される、コントローラに実装された「def XXXX ~ end」という形式のコード

つまり上にも書いたこのコードはアクションになる。なるほど。。。

````ruby:XXX.controller.rb
def アクション名
  XXXXXX
end
````
【ActiveAdmin】セレクトボックス内の項目を好きな順でソートする方法

#はじめに
rails_adminを使っていたのですが、セレクトボックス内の項目順序を変えるのすら出来なくて泣き叫んでいました。
調べても調べても分からんかったので、これもしかして出来ないんちゃう……？と。

そこでactive_adminに移行してしまいました。
こちらでは出来ました。


#構成
Item belongs_to Kind


#active_adminで生成したファイルの設定

```app/admin/items.rb
ActiveAdmin.register Item do
  # 変更許可するカラム
  permit_params :name, :kind_id

  # （中略）

  form do |f|
    inputs do
      input :name 
      input :kind, as: :select, collection: Kind.all.order(:name)
    end

    actions
  end

end
```

.orderで逆順にするなら`.order(name: "DESC")`


#まとめ

うーん美しい。

地味に苦労したのですが、目標を分割したら割とすぐ出来ました。

1.カスタムした配列をセレクトボックスで選ばせる
2.Modelからデータを引っ張ってくる

他の所で配列作ったりしてもいいのですが、最終的にこれで通りました。

もっと言うと、Modelの関連付けがちゃんとしてたら`as: :select`もこれ無くて大丈夫です。


それにしても表示カラムの制限とか好き放題やれて、Modelごとに綺麗に分離してるの……気持ちいい……🤤

active_admin大好きになってきてます


終わり
准备基本情报技术者试验的童鞋有吗？

准备基本情报技术者试验的童鞋有吗？

好不容易找了个上市公司的正社员工作，因为学历是成人学历。
签证又是企业内转勤签证。
结果企业内转勤签证变更为技人国签证失败。

因为考过了基本情报技术者试验就可以申请工作签再无限制了，所以正在挣扎准备中。
我学得非常痛苦。

请问有在一起准备这个考试的朋友吗？大家相互交流一下。
我的微信1019354192@qq.com
【Unity】NRSDK1.3.0のInput-Interactionシーンを読んでみる（Inputシーン編2/3）【Nreal】

##はじめに
NRSDK 1.3.0にあるInput-Interactionシーンを観察していきます。

Inputのサンプルシーンは3つあるので、本記事は(2/3)としています
もし間違いがあれば、指摘いただければ幸いです。

【別のInputシーン編記事はこちら】
[NRSDK.3.0のInput-ControllerInfoシーンを読んでみる（Inputシーン編1/3）](https://qiita.com/y-mic/items/3b45ab197fa20901395e)

##Input-Interactionシーンについて
Nrealのコントローラーのクリック、ポインターのRay判定などのサンプル
「Active True」「Active False」でCubeの表示非表示を行い、
ポインターをCubeのコライダーに当てると、Cubeが緑色になる。外すと、白色になる。

下記画像はUnityEditorで実行時のスクリーンショット
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436651/6b2b96f5-de35-239d-5b24-60dd54663e82.png" width="500">
##シーン構成
| シーン構成 |
|:-----------|
|NRCameraRig|
|NRInput|
|Cube|
|Canvas|
|SimpleControllerVibration|
|Directional Light|

##NRCameraRig、NRInput
Nrealに対応したカメラ、入力システム
別のサンプルシーンで観察してます。
[NrealSDK1.3.0のHelloMRシーンを観察してみる](https://qiita.com/y-mic/items/508c5a3e6cbdc9a20f86)

##Cube
| スクリプト名 | 役割|
|:-----------|:-----------|
|CubeInteractiveTest| MonoBehaviourを継承、IPointerClickHandler, IPointerEnterHandler, IPointerExitHandlerの計3種類インターフェースを実装し、Cubeにポインターが「触れた」、「離れた」、「クリックした」際の処理を記述している|

##Canvas
ActiveTrue,Falseボタン、InputFieldをもつCanvas
RenderModeはWorldSpaceになっており、カメラからZ:3に配置されている。
カメラに追従しない系Canvas。
（カメラに追従する系Canvasは、NRCameraRig>CenterCamera直下にWorldSpaceで配置すればできる）
実装するなら、HololensのUIのように一定距離離れるとじんわり付いてくるCanvasを作りたいですね。

| スクリプト名 | 役割|
|:-----------|:-----------|
|CanvasRaycastTarget|Canvasの子UIにRayを当てるためのもの。アタッチされていないと、RayでUIを触れることができない|
**ignoreReversedGraphics**
レイキャスターから反対方向を向いている場合も考慮するかどうか。

##SimpleControllerVibration

| スクリプト名 | 役割|
|:-----------|:-----------|
|SimpleControllerVibration|コントローラーのボタン押下時、コントローラーを振動させるものだと思われる。|
Nreal Developer Kitで確認した時は、振動がなかった気がする。　
Nreal公式の[製品仕様](https://developer.nreal.ai/dev-kit)を見た限り、振動するものはないが、Android端末は振動するのか？？（スマホは未確認）

**vibrationTime**
振動時間。デフォルトは0.06。

##Directional Light
Unity標準のライト。

##まとめ
オブジェクト、UIへの入力方法も理解できました。
やはり目の前のオブジェクトの色が変化したりするのは見ていて楽しいです。
（ちなみにInputFieldの役割は不明です、、）

##さいごに
Androidにすれば、振動や入力用キーボード表示などできたりするのでしょうかね。
開発するにしてもテスト等々DeveloperDeveloper Kitがメインになると思うので、
出来ることをはっきりしていきたいです。
これからもNrealに関する記事を投稿していきたいと思います。
Unicode Decode Eroorでpip installできないのを手動で直す

#はじめに
Windows10、Anaconda環境でpip install markovifyを実行するとこんなエラーが出た
```UnicodeDecodeError: 'cp932' codec can't decode byte 0x94 in position 8016: illegal multibyte sequence
```
#原因
WindowsがCP932(Shift_JIS)でエンコードされていないファイルをCP932に変換してるっぽい
#解決策
僕の場合は[markovifyのソースファイル](https://github.com/jsvine/markovify)を落としてsetup.pyを修正することで解決しました
具体的には、READMEの読み込みに失敗しているのが原因なので
```with open(os.path.join(HERE, 'README.md')) as f:
```これを
```with open(os.path.join(HERE, 'README.md'),encoding='utf-8') as f:
```こうして
```python setup.py install
```を実行して無事にインストールできました。やったね。