OmniAICreator/Qiita-1.07M huggingface dataset:
【実機あり】MRTK ver2.6.1 の Example を一通り試してみた 2

# はじめに

https://qiita.com/h_koya/items/6f0bb900a0b517d55e74
前回の続きです。
実機でないと確認できない部分をまとめました。

MRTK ver2.6.1 の Example 実機なしで確認できない部分を実機で行いました。

# 環境
- Windows 10 Enterprise
- Unity 2019.4.1f1
- MRTK 2.6.1


# Boundary
## BoundaryVisualization
VR用の機能です。
プレイエリアの可視化ができるようです。


# ハンドトラッキング
## HandMenu
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">MRTK ver2.6.1 の HandMenu のデモ動画です！<br><br>手のひらを表にするとメニューが表示されます。<a href="https://twitter.com/hashtag/MRTK?src=hash&amp;ref_src=twsrc%5Etfw">#MRTK</a> <a href="https://twitter.com/hashtag/HoloLens2?src=hash&amp;ref_src=twsrc%5Etfw">#HoloLens2</a> <a href="https://t.co/lGT4oXpQjE">pic.twitter.com/lGT4oXpQjE</a></p>&mdash; 原口昂弥 (@k_haraguchi55) <a href="https://twitter.com/k_haraguchi55/status/1381924827406028801?ref_src=twsrc%5Etfw">April 13, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## LeapMotionHandTracing
Leap Motion Controller が必要です。
持っていないので試せませんでした。

# PulseShader
## PulseShaderHandMesh
ハンドメッシュをパルスで確認できます。
FPSが下がって動画が取れなかったです。、、、

# ReadingMode
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">MRTK ver2.6.1 の ReadingMode のデモ動画です！<br><br>ReadingModeの体験ができます。<br>ReadingModeは解像度が向上する代わりに視野角が狭くなります。<a href="https://twitter.com/hashtag/MRTK?src=hash&amp;ref_src=twsrc%5Etfw">#MRTK</a> <a href="https://twitter.com/hashtag/HoloLens2?src=hash&amp;ref_src=twsrc%5Etfw">#HoloLens2</a> <a href="https://t.co/BFimV3VnqQ">pic.twitter.com/BFimV3VnqQ</a></p>&mdash; 原口昂弥 (@k_haraguchi55) <a href="https://twitter.com/k_haraguchi55/status/1382582468860022786?ref_src=twsrc%5Etfw">April 15, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# Solvers
## SurfaceMagnetismSpatialAwareness
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">MRTK ver2.6.1 の Surface Magnetism + Spatial Awarenessのデモ動画です！<br><br>認識した空間の表面にオブジェクト配置できます。<a href="https://twitter.com/hashtag/MRTK?src=hash&amp;ref_src=twsrc%5Etfw">#MRTK</a> <a href="https://twitter.com/hashtag/HoloLens2?src=hash&amp;ref_src=twsrc%5Etfw">#HoloLens2</a> <a href="https://t.co/y1R4I13pTo">pic.twitter.com/y1R4I13pTo</a></p>&mdash; 原口昂弥 (@k_haraguchi55) <a href="https://twitter.com/k_haraguchi55/status/1381946351869587457?ref_src=twsrc%5Etfw">April 13, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# SpatialAwareness
## SpatialAwarenessMesh
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">MRTK ver2.6.1 の Spatial Awareness Mesh のデモ動画です！<br><br>空間メッシュを視覚化できます。<a href="https://twitter.com/hashtag/MRTK?src=hash&amp;ref_src=twsrc%5Etfw">#MRTK</a> <a href="https://twitter.com/hashtag/HoloLens2?src=hash&amp;ref_src=twsrc%5Etfw">#HoloLens2</a> <a href="https://t.co/6hqsQgeZkc">pic.twitter.com/6hqsQgeZkc</a></p>&mdash; 原口昂弥 (@k_haraguchi55) <a href="https://twitter.com/k_haraguchi55/status/1381915965982605314?ref_src=twsrc%5Etfw">April 13, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
Lambda Layer で PDFTK を利用する。

API Gateway + Lambda を使ってS3上のPDFをマージする処理を実装した際に、
PDFTK を Lambda Layer に組み込んだ時のメモ。

###PDFTK を動かす Lambda Layer の作成方法

1. Dockerなどで Amazon Linux 2の環境を用意(もしかしたらcentosだったかも・・・)
2. Amazon Linux 2 上で PDFTK をビルド(もしかしたらcentosだったかも・・・)
3. ビルドした PDFTK のファイルを Lambda Layer の構成に組み込む


### 1. Dockerなどで Amazon Linux 2の環境を用意

ここは省略

### 2. Amazon Linux 2 上で PDFTK をビルド

PDFTKのサイトの「 Build from Source Code 」の手順でビルドする。
https://www.pdflabs.com/docs/install-pdftk-on-redhat-or-centos/

### 3. ビルドした PDFTK のファイルを Lambda Layer の構成に組み込む

この2ファイルを下記Lambda Layer の構成に組み込み、nodejsフォルダを圧縮して Lambda Layer にアップロードするだけ。
・/usr/local/bin/pdftk
・pdftk-2.02-dist/lib64/libgcj.so.10

![スクリーンショット 2021-04-15 160915.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1251670/0bf9d697-d3b9-e78d-929a-0d3494524a94.png)

次の index.js では、pdftk の cat (結合) と version （バージョン表示）のみ実装している。

```javascript:index.js

const { PATH, LD_LIBRARY_PATH, PKG_CONFIG_PATH } = process.env

const BIN = '/opt/nodejs/node_modules/pdftk-lambda/bin'

process.env.PATH            = `${PATH}:${BIN}`
process.env.LD_LIBRARY_PATH = `${LD_LIBRARY_PATH}:${BIN}`
process.env.PKG_CONFIG_PATH = `${PKG_CONFIG_PATH}:${BIN}`

/**
 * バージョン
 */
module.exports.version = () => {
  return new Promise((resolve, reject) => {
    require('child_process').exec(
      'pdftk --version',
      (error, stdout, stderr) => {
        if (error) reject(error)
        else resolve(stdout)
      }
    )
  })
}

/**
 * 結合
 * Example:pdftk pdf1.pdf pdf2.pdf cat output combined.pdf
 */
module.exports.cat = ( inputFiles, outputFile ) => {
  console.log('pdftk ' + inputFiles.join(' ') + ' cat output ' + outputFile);
  return new Promise((resolve, reject) => {
    require('child_process').exec(
      'pdftk ' + inputFiles.join(' ') + ' cat output ' + outputFile,
      (error, stdout, stderr) => {
        if (error) reject(error)
        else resolve(stdout)
      }
    )
  })
}


```


Lambda Layer を使う場合はこんな感じ。

```javascript:
var pdftk  = require('pdftk-lambda');

/**
 * PDF結合
 */
async function pdfMerge( inPutFiles, outPutFile ){
    let ret = true;
    try{
        await pdftk.cat( inPutFiles, '"' + outPutFile + '"' );
    }catch(e){
        ret = !ret;
        console.log('-(pdtfk cat error log start )-');
        console.log(e);
        console.log('-(pdtfk cat error log end )-');
    }
    return ret;
}
```
protodepでillegal base64 dataエラー


## 現象

gitコマンドからは問題なく操作出来るが、
protodep経由だとgitからClone出来なくて困った。

```shell
$ protodep up -f
[INFO] force update = true
[INFO] cleanup cache = false
[INFO] identity file =
[INFO] use https = false
[INFO] Getting github.com/ft-labo/${リポジトリ名} 🕐 Error: clone repository is failed: knownhosts: /Users/mitsuaki1229/.ssh/known_hosts:5: illegal base64 data at input byte 372
Usage:
  protodep up [flags]

Flags:
      --basic-auth-password string   set the password or personal access token(when enabled 2FA) with Basic Auth via HTTPS
      --basic-auth-username string   set the username with Basic Auth via HTTPS
  -c, --cleanup                      cleanup cache before exec.
  -f, --force                        update locked file and .proto vendors
  -h, --help                         help for up
  -i, --identity-file string         set the identity file for SSH
  -p, --password string              set the password for SSH
  -u, --use-https                    use HTTPS to get dependencies.

clone repository is failed: knownhosts: /Users/mitsuaki1229/.ssh/known_hosts:5: illegal base64 data at input byte 372
```

## 原因

known_hostsに改行されずに保存されているエントリが存在した。

例

```known_hosts
127.0.0.1 ssh-rsa 44OU44Kr44OB44Ol44Km44GS44KT44GN44Gn44Gh44KF44GG127.0.0.1 ecdsa-sha2-nistp256 44Gq44KT44Gn44Ko44Oz44K444OL44Ki44Gv54yr44GM5aW944GN44Gq44KT44Gg44KN44GG44GL44CC54is6Jmr6aGe44KC5Y+v5oSb44GE44Go5oCd44GG44KT44Gg44GR44Gp44Gq44O844CC44GE44KE44G+44GB54yr44KC5aW944GN44Gq44KT44Gg44GR44Gp44CC
```

## 解決

改行後

```known_hosts
127.0.0.1 ssh-rsa 44OU44Kr44OB44Ol44Km44GS44KT44GN44Gn44Gh44KF44GG
127.0.0.1 ecdsa-sha2-nistp256 44Gq44KT44Gn44Ko44Oz44K444OL44Ki44Gv54yr44GM5aW944GN44Gq44KT44Gg44KN44GG44GL44CC54is6Jmr6aGe44KC5Y+v5oSb44GE44Go5oCd44GG44KT44Gg44GR44Gp44Gq44O844CC44GE44KE44G+44GB54yr44KC5aW944GN44Gq44KT44Gg44GR44Gp44CC
```

再実行

```shell
$ protodep up -f
[INFO] force update = true
[INFO] cleanup cache = false
[INFO] identity file =
[INFO] use https = false
[INFO] Getting github.com/ft-labo/${リポジトリ名}
mitsuaki1229@mitsuaki1229-mba-ftl:
```

## 解析

protodepのソースを見る限り、NewPublicKeysFromFileの先々にて、pem.goのDecodeを使って、ファイル内の行に対して、base64のエンコードをしてる模様。
known_hostsの改行されずにくっついてる残りの行に対して、base64エンコードをしようとしてるため、`illegal base64 data at input byte`が出てるように見える。

https://github.com/stormcat24/protodep/blob/c95189bc461bdd54f0b4f09810a19c662b951638/repository/git.go#L88-L91

```go
			URL:  r.authProvider.GetRepositoryURL(reponame),
		})
		if err != nil {
			return nil, errors.Wrap(err, "clone repository is failed")
```

https://github.com/stormcat24/protodep/blob/c95189bc461bdd54f0b4f09810a19c662b951638/helper/auth.go#L111

```go
	am, err := ssh.NewPublicKeysFromFile("git", p.pemFile, p.password)
```

go/1.16.3/libexec/src/encoding/pem/pem.go

Decodeの該当箇所。

```go
	base64Data := removeSpacesAndTabs(rest[:endIndex])
	p.Bytes = make([]byte, base64.StdEncoding.DecodedLen(len(base64Data)))
	n, err := base64.StdEncoding.Decode(p.Bytes, base64Data)
```
dockerのimage名を変更する


## 概要
dockerを使用するときに、image名を自分用に変更したい場合があります。
その場合に利用できます。

## 使用方法

```
# docker tag <変更前のimage名> <変更後のimage名>

#例
docker tag nginx:1.18.0 hogehoge/nginx:1.18.0
```
GaoFashion

Gaofashion store, all the t-shirts, sweatshirts, hoodies, tank tops, mug that you could be looking for. Gaofashion is an exclusive store for the world’s best animal themed apparels such as lion, donkey, mouse and so on.
Website: https://gaofashion.com
Email: support@gaofashion.com
Add: 4 S Hudson St, Orlando, FL 32835, USA
Phone: +14072931882

More Social:
http://www.nfomedia.com/profile?uid=rJkUZeI
http://www.lawrence.com/users/gaofashion/
https://sites.google.com/view/gaofashion/home
http://tupalo.com/en/users/2544639
https://answers.informer.com/user/GaoFashion
https://www.blurb.com/user/gaofashion?profile_preview=true
http://www.synthedit.com/qa/user/gaofashion
https://www.viki.com/users/gaofashion/about
https://8degreethemes.com/support/users/gaofashion/
https://8tracks.com/gaofashion
https://amara.org/en/profiles/profile/A1_yleKcZDcENQwNEQeDygoxFAzBBa2iH1lu_NBrPkI/
https://about.me/gaofashion
https://able2know.org/topic/557165-1#post-7119506
promise 与 await 的互换

Rewriting promise code with async/await
Let's look back at a simple fetch example that we saw in the previous article:

fetch('coffee.jpg')
.then(response => {
  if (!response.ok) {
    throw new Error(`HTTP error! status: ${response.status}`);
  }
  return response.blob();
})
.then(myBlob => {
  let objectURL = URL.createObjectURL(myBlob);
  let image = document.createElement('img');
  image.src = objectURL;
  document.body.appendChild(image);
})
.catch(e => {
  console.log('There has been a problem with your fetch operation: ' + e.message);
});
By now, you should have a reasonable understanding of promises and how they work, but let's convert this to use async/await to see how much simpler it makes things:

async function myFetch() {
  let response = await fetch('coffee.jpg');

  if (!response.ok) {
    throw new Error(`HTTP error! status: ${response.status}`);
  }

  let myBlob = await response.blob();

  let objectURL = URL.createObjectURL(myBlob);
  let image = document.createElement('img');
  image.src = objectURL;
  document.body.appendChild(image);
  }
}

myFetch()
.catch(e => {
  console.log('There has been a problem with your fetch operation: ' + e.message);
});
It makes code much simpler and easier to understand — no more .then() blocks everywhere!
PHPで返却しているJSONが途中で切れるバグを解消した

## 環境

PHP 7系
JavaScript (Pure)
Docker
HAProxy 2.2
VSCode Remote Container

小さい Web システムプロジェクトなので、APIを作成するためのライブラリ等は使っていない。

## 発生した問題

`echo json_encode($data);` という簡単なコードで、APIを作成していた。

小さいプロジェクトなので、APIを作成するためのライブラリ等は使っていない。

比較的短いJSONを出力すると、APIから返却されたJSONが途中で切れてしまうバグに遭遇した。

```json
{"locale": "ja-JP"}
```

これぐらいだと `{"locale": ` のように切れてしまう。これが

```json
{"locale": "ja-JP", "dummy": "なんでなんだろうなああああああああああああ"}
```

のように長いJSONを返すと、切れないで表示される。（JavaScriptが正常にパースできる。）

## 原因

```php
header('Content-Type: application/json');
echo('{"locale": "ja-JP"}');
```

このように、echoする前にヘッダを設定する必要があった。ちなみに実際には、JavaScriptのコールバックが必要なJSONPコールだったので、 `application/javascript` にした。

## コメント

あまり使ったことのないHAProxyのせいだと思い込み、かつ似たようなIssueが過去に報告されていたのでかなりはまりました。
RHEL 7.6にDocker環境を作る w/ 社内プロキシやCA証明書

# はじめに

社内プロジェクトでDockerを使いたいけどプロキシやら社内CA証明書やら設定しなきゃ...というのを毎回調べるのが面倒になるので手順をメモ。

---

# 手順

---

## Subscription manager への登録

[参考: RedHat Customer Portal - Subscription Management コマンドを使用する](https://access.redhat.com/ja/articles/3221791)

```sh
# 色んなパターンがあるので適切な方法で。
sudo subscription-manager register --username=yourusername --password=yourpassword
sudo subscription-manager register --activationkey=hogehoge --org=fugafuga --proxy=http://inhouse.proxy.example.com:8080
```

---

## 追加yumリポジトリの有効化

[参考: RedHat Customer Portal - リポジトリを有効にする](https://access.redhat.com/ja/articles/3221791)

```sh
sudo subscription-manager repos --enable=rhel-7-server-extras-rpms
```

---

## Dockerのインストール

```sh
sudo yum install docker -y
```

入るバージョンが結構古いので注意。最新版を入れたければ公式ガイドの手順に従うのが無難。
[Install Docker Engine on CentOS](https://docs.docker.com/engine/install/centos/)

---

## Dockerへの環境変数(プロキシ関係)の設定

```sh
sudo systemctl edit docker
```

viが起動するのでプロキシ関係の設定を次のように追加

```
[Service]
Environment=http_proxy=http://inhouse.proxy.example.com:8080
Environment=https_proxy=http://inhouse.proxy.example.com:8080
Environment=HTTP_PROXY=http://inhouse.proxy.example.com:8080
Environment=HTTPS_PROXY=http://inhouse.proxy.example.com:8080
```

大文字小文字のどっちの変数名を見てるかわからなかったので、とりあえず両方設定。多分片方だけでいい。

---

## (オプション)dockerコマンドをsudoなしで使えるようにする

ユーザをdockerグループに追加するとできるようになる。
[参考: Manage Docker as a non-root user](https://docs.docker.com/engine/install/linux-postinstall/#manage-docker-as-a-non-root-user)

```sh
sudo groupadd docker
sudo usermod -aG docker some-user
```

実行後にユーザの再ログインがいるかも。

---

## CA証明書のインストール

CA証明書ファイルを`someCert.crt`とするとこんな感じ。
[参考: RedHat Customer Portal - 4.14. 共有システムの証明書の使用](https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/7/html/security_guide/sec-shared-system-certificates)

```sh
sudo cp someCert.crt /etc/pki/ca-trust/source/anchors/
sudo update-ca-trust extract
```

上記は全リポジトリ（というかRHEL全体）で有効なCA証明書になる。特定のリポジトリのみに必要なCA証明書なら次のページを参考に設定を。

* [Docker-docs-ja - 証明書をリポジトリのクライアント認証に使用](https://docs.docker.jp/engine/security/certificates.html)

---

## Dockerの起動

```sh
sudo systemctl start docker
sudo systemctl enable docker
```

---

## Dockerの動作確認

```sh
docker run --rm hello-world
```

* `--rm`オプションつけておくと停止後にコンテナが自動で消える。動作確認後はどうせ不要なコンテナなのでつけておくと吉。

---

## (オプション) プライベートレジストリにHTTP接続できるようにしておく

デフォルトではレジストリへの接続はHTTPSになるが、社内リポジトリはオレオレ証明書などで設定が面倒だったりするのでHTTPで接続できるようにしてしまう。

* [「server gave HTTP response to HTTPS client」と言われてDocker Private registoryのpushやpullができなかったときの対処](https://qiita.com/nkmry/items/e2ce67dd66be1f347b67)


---

# お疲れさまでした

多分これで動くと思いますが、なんかおかしなことしてたらマサカリください。
Seleniumで検索ボックスにsend_keysしようとしてelement not interactableとなってerrorになる件

#スクレイピングのために Selenium+ChromeDriver を導入
現在開発中のWEBアプリのためにあるサイトの検索ボックスにキーを代入してスクレイピングていうやつをしようと思い、Selenium と ChromeDriver をインストール。
アプリ開発って、python だけできればいいってわけじゃないって改めて実感。
逆に、できることの幅は広がる広がる。

#で、検索ボックスに send_keys で入力しようとしたら、element not interactable とエラーになって怒られる
ネットに落ちてる情報をかき集めて何とか目的のサイトの目的の検索ボックスにアクセスする方法を見出して、send_keys で値を入力しようとしたら、なぜかエラー・・・

```
>>> from selenium import webdriver
>>> driver = webdriver.Chrome()

DevTools listening on ws:....
>>> driver.get('https://xxxxxxx..../')
>>> search_box = driver.find_element_by_name("value")
>>> search_box.send_keys('test')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Users\xxxxx\anaconda3\envs\myconda\lib\site-packages\selenium\webdriver\remote\webelement.py", line 477, in send_keys
    self._execute(Command.SEND_KEYS_TO_ELEMENT,
  File "C:\Users\xxxxx\anaconda3\envs\myconda\lib\site-packages\selenium\webdriver\remote\webelement.py", line 633, in _execute
    return self._parent.execute(command, params)
  File "C:\Users\xxxxx\anaconda3\envs\myconda\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 321, in execute
    self.error_handler.check_response(response)
  File "C:\Users\xxxxx\anaconda3\envs\myconda\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 242, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.ElementNotInteractableException: Message: element not interactable
  (Session info: chrome=89.0.4389.128)

>>> 
```
なんでや！！！！

同じことを google でやったら普通にできました。

```
>>> from selenium import webdriver
>>> driver = webdriver.Chrome()

DevTools listening on ws:....
>>> driver.get('https://www.google.com/')
>>> search_box = driver.find_element_by_name("q")
>>> search_box.send_keys('test')
>>> search_box.submit()
>>> 
```
コードに問題はない。ということはサイト依存でエラーになるかならないか決まるってことですね。

#原因は探したい要素の name が2つ以上あったこと
色々調べた結果、探そうとしている要素が2つ以上あるとうまく取得できないようでした。
上記のエラーになったサイトでは、目的としている検索ボックスの name="value" が2つめの "value" だったようで、1つめの "value" が指定された部分に send_keys が有効ではなかったようです。

#find_element_by_name を find_elements_by_name にして list で取得することでエラー回避
複数の要素を抽出したいときは、find_element を find_elements にすることで、list で抽出できるとのこと。
試してみたらうまくいきました！

```
>>> from selenium import webdriver
>>> driver = webdriver.Chrome()

DevTools listening on ws:....
>>> driver.get('https://www.google.com/')
>>> search_box = driver.find_element_by_name("q")
>>> search_box.send_keys('ChromeDriver')
>>> search_box.submit()
>>> driver.get('https://xxxxxxx..../')
>>> search_box = driver.find_elements_by_name("value")
>>> search_box[1].send_keys('test')
>>> search_box[1].submit()
>>> 
```
要素の2番目を指定するあたり不細工ですが、css セレクターとかいうのもよくわからなかったので、ローカルで使用するだけのプログラムだし今のところいいか～ということでこれで実行！

#まとめ
こういう細かいバグ取りって、同じようなエラーをしている場合と、検索してもなかなかでてこないエラーもありますよね。
こうして記録しておくことで、同じようなことで悩まれる人が減ったらいいなと思います。
PowerShell7にPowerlineを設定時に起きたエラーの対応備忘録

こちらを参考にPowerShell7にPowerlineを設定しようとした際にエラーが発生したので備忘録。

[Windows TerminalでPowerlineの環境を整える - ビー鉄のブログ](https://www.beeete2.com/blog/?p=2619)

PowerShellで

```
notepad $PROFILE
```

を実行し、下記3行を追加した。

```
Import-Module posh-git
Import-Module oh-my-posh
Set-Theme Paradox
```

再度PowerShellを立ち上げると下記のエラーが発生。

```
The term 'Set-Theme' is not recognized as the name of a cmdlet, function, script file, or operable
program. Check the spelling of the name, or if a path was included, verify that the path is correct
and try again.
```


[Windows Terminal - PowerShell customization via oh-my-posh/posh-git Set-Theme error?](https://github.com/microsoft/terminal/issues/9237)
> It seems the "Set-Theme" cmdlet was renamed to "Set-PoshPrompt".

どうやらコマンドが変わったとのこと。

### 修正後

```
Import-Module posh-git
Import-Module oh-my-posh
Set-PoshPrompt Paradox
```

解決。
Kubernetes　Podのstatus一覧

# Podのstatusは、`Waiting`、`Running`、`Terminated`の3つ

KubernetesはPod内の各コンテナの状態を追跡します。

PodがschedulerによってNodeに割り当てられると、kubeletはcontainer runtimeを使用してコンテナの作成を開始します。

コンテナの状態はWaiting、RunningまたはTerminatedの3ついずれかになります。

status|意味
- | -
Waiting | RunningまたはTerminatedのいずれの状態でもない
Running | 問題なく実行中
Terminated | 完了。または、何らかの理由で失敗

## Podのコンテナのstatus確認コマンド

```
kubectl describe pod [POD_NAME]
```

Pod内のコンテナごとにStateの項目として表示されます。

## Waiting

コンテナがRunningまたはTerminatedのいずれの状態でもない場合コンテナはWaitingの状態になります。

Waiting状態のコンテナは引き続きコンテナイメージレジストリからイメージを取得したりSecretを適用したりするなど必要な操作を実行します。
Waiting状態のコンテナを持つPodに対してkubectlコマンドを使用すると、そのコンテナがWaitingの状態である理由の要約が表示されます。

## Running

Running状態はコンテナが問題なく実行されていることを示します。

コンテナがRunning状態に入る前にpostStartフック（もしあれば）が実行されます。
Running状態のコンテナを持つPodに対してkubectlコマンドを使用すると、そのコンテナがRunning状態になった時刻が表示されます。

## Terminated

Terminated状態のコンテナは実行されて、完了したときまたは何らかの理由で失敗したことを示します。
Terminated状態のコンテナを持つPodに対してkubectlコマンドを使用すると、終了理由と終了コード、コンテナの開始時刻と終了時刻が表示されます。

コンテナがTerminatedに入る前にpreStopフックがあれば実行されます。

## 参考

[Podのライフサイクル | Kubernetes](https://kubernetes.io/ja/docs/concepts/workloads/pods/pod-lifecycle/#container-states)
pythonのログ出力方法

## 概要

pythonのアプリでログを簡単に設定できる方法を記載します
私の場合はfastapiを使って実装しましたのでその例と交えて説明します。

- 導入のメリット
    - カスタマイズしやすい
    - 設定が一箇所に集約できる
    - フレームワーク依存がない

- デメリット
    - python 3.8以上である必要がある


## logのwrapperを作る

```logutil.py
import logging
import os

logging.basicConfig(format='%(levelname)s:%(asctime)s:%(pathname)s:%(lineno)s:%(message)s')
logger = logging.getLogger(__name__)

if os.environ['ENV'] == "prd":
    logger.setLevel(logging.INFO)
else:
    logger.setLevel(logging.DEBUG)    

def debug(message):
    logger.debug(message, stacklevel=2)

def info(message):
    logger.info(message, stacklevel=2)

def error(message):
    logger.error(message, stacklevel=2)
```

## 実際の呼び出し例

```hello.py
import logutil as log

log.info("hello")

```

## ポイント

- 環境変数を渡してあげることによって、ログレベルを分岐できます

例）こんな感じで渡してあげるとロード時に読み込んでくれます。

```
export env=prd
```

- python3.8以上でないといけない理由 stacklevel=2
    - wrapperをしている都合上、呼び出しもとのソース行数を表示したいと思います。この宣言をすると呼び出しもののソース行を表示してくれます。
Perl: メールの送信 （添付ファイル付き）

こちらのプログラムを参考にしました。
[(Perl) Net::SMTPSを使ってメール送信](https://netlog.jpn.org/r271-635/2018/06/perl_netsmtps.html)

Ubuntu 20.10 で必要なライブラリーのインストール

```bash
sudo apt install libemail-mime-perl
sudo apt install libpath-class-perl
```

linux_logo.gif というファイルを添付するサンプルです。


```pl:mail_attache.pl
#! /usr/bin/perl
#
#	mail_attache.pl
#
#						Apr/15/2021
#
# ---------------------------------------------------------------- 
use warnings;
use strict;
use utf8;
use Encode qw(encode);
use Net::SMTP;
use Email::MIME;
use Email::MIME::Creator;
use Path::Class;
use Dotenv;
 
# ---------------------------------------------------------------- 
print STDERR "*** start ***\n";

my $env = Dotenv->parse('.env');
print STDERR %$env{'SERVER'} . "\n";
print STDERR %$env{'PORT'} . "\n";
#
my $mailhost = %$env{'SERVER'};
my $mailport = %$env{'PORT'};
my $mail_username = %$env{'FROM'};
my $mail_password = %$env{'PASSWORD'};

my $from_mail = %$env{'FROM'};
my $to_mail = %$env{'TO'};


my $subject = 'test テストApr/15/2021 PM 14:51';
my $body =
    "年齢からいえば、関羽がいちばん年上であり、次が劉備、"
  . "その次が張飛という順になるのであるが、"
  . "義約のうえの義兄弟だから年順をふむ必要はないとあって、"
  . "「長兄には、どうか、あなたがなって下さい。\n"
  . "それでないと、張飛の我ままにも、おさえが利きませんから」と、関羽がいった。";
 
my $mail = Email::MIME->create(
	'header' => [
        'From'    => encode( 'MIME-Header-ISO_2022_JP', $from_mail ),
        'To'      => encode( 'MIME-Header-ISO_2022_JP', $to_mail ),
        'Subject' => encode( 'MIME-Header-ISO_2022_JP', $subject ),
    ],
parts => [
	Email::MIME->create(
		'attributes' => {
                      'content_type' => 'text/plain',
                      'charset'      => 'ISO-2022-JP',
                      'encoding'     => '7bit',
    },
    'body' => encode( 'iso-2022-jp', $body ),
),
Email::MIME->create(
	'attributes' => {
		'content_type' => 'image/gif',
		'name'         => 'attached image name',
		'filename'     => 'linux_logo.gif',
		'encoding'     => 'base64',
		'disposition'  => 'attachment',
		},
		'body' => scalar Path::Class::file('linux_logo.gif')->slurp,
               ),
    ],
);

 
eval {
    my $smtp = Net::SMTP->new(
	$mailhost,
	Port  => $mailport,
	doSSL => 'starttls',
#	Debug => 1
    );
 
	$smtp->auth($mail_username, $mail_password, 'CRAM-MD5' );
	$smtp->mail($from_mail);
	$smtp->recipient( $to_mail, { SkipBad => 1 } );
	$smtp->data();
	$smtp->datasend( $mail->as_string() );
	$smtp->dataend();
	$smtp->quit;
};

if ($@) {
    die "ERROR : $@\n";
}

print STDERR "*** end ***\n";
# ---------------------------------------------------------------- 
```
【就活用】プログラミング未経験から転職活動を行い、入社が決定するまでにかかったお金

#はじめに
私はプログラミング未経験から転職活動を行い、自社開発企業に入社することが決まりました。

転職活動を行うためには、生活費の他に旅費等がかかりますので、転職活動前にある程度お金を貯めておく必要があるかと思います。

本記事では私がプログラミングスクールに通い学習を行い、転職活動をし、入社が決定するまでにかかった費用を載せております。

今後転職活動をされる方の目安になれば幸いと思います。

#前提
私は以下の条件のもと、転職活動を行っていました。
・スクールに通う前に、プロゲートの有料コンテンツの学習を行うため課金
・学習と転職活動はスクールで行う
・コロナ禍での転職活動
・実家住まい

#かかったお金の内訳

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1052793/9e105484-df0e-90c1-fafd-26b18dbb5adb.png)

※私は実家住まいのため、生活費としては食費のみ支払っていました。
　その他の通信費や娯楽などの費用は省略しております。

プログラミング学習〜転職活動で合計で約80万円ほどかかりました。
実家暮らしではなく、一人暮らしで転職活動を行うとなると、さらにこれ以上お金がかかるということになるかと思います。

#コロナ禍での転職活動
コロナ禍のため面接はオンライン面接となりました。なので、面接に行くための交通費があまりかからないというメリットがありました。

今転職活動される方は、コロナ前と比べると少ない交通費での転職活動が行えます。

#結論　転職活動は色々とお金がかかるので、計画的に貯金しておくことが必要
転職活動する期間は予定を立てることは難しいと思いますが、学習や就活以外にも計画的に貯金しておくこと重要だと思います。

私の転職活動にかかった費用が、これから転職活動される方のご参考になれば本当に幸いです。

以上です。
TypeORMで外部キーでJOINしたテーブルのカラムでWHERE条件を指定する

```sql
SELECT * FROM parents
INNER JOIN children ON parents.foreign_key = children.id
WHERE children.search_column = 'target';
```

みたいなクエリをいい感じに書きたい。

# 方法1: `Repository#find`の`where`にクエリビルダを使用する

この方法が書きたかった。`where`プロパティにオブジェクトリテラルではなく関数を渡すとクエリビルダオブジェクトを受け取れる。

```typescript
parentRepository.find({
  join: { alias: 'parent', innerJoin: { children: 'parent.foreignKey' } },
  where: (qb) => {
    qb.where('children.searchColumn = :searchColumn', { searchColumn: 'target' });
  },
});
```

参考:

https://github.com/typeorm/typeorm/issues/4396#issuecomment-566254087

# 方法2: 素直に最初からクエリビルダを使用する

上の方法を知るまではこう書いていた。

```typescript
parentRepository.createQueryBuilder('parent')
  .innerJoin('parent.foreignKey', 'children')
  .where('children.searchColumn = :searchColumn', { searchColumn: 'target' })
  .getMany();
```

# まとめ

TypeORMでもクエリビルダを使い始めるとほとんど型の恩恵を受けられないので、`find`で一部のユースケースをカバーできるのは地味にうれしい。

そしてやっぱりActiveRecordは便利だと思う。それはそうとPrismaもMigrationがついに正式版になったので（長かった）、これから始めるならそっちかなあと思ったりもする。一度触ってみたい。
pandasで一分足からOHCLを作成

```rb
import pandas as pd

filepass =  "C:/Users/aaaa/Desktop/USDJPY_M1/USDJPY_M1.csv"
date  =  pd.read_csv(filepass, sep=',',header=None,names=('day', 'open', 'high','low', 'close', 'volume'))
date['day'] = pd.to_datetime(date['day'],format='%Y.%m.%d %H:%M')#str to datetime64
df = date.set_index('day')
d_ohlc = {'open': 'first',
          'high': 'max',
          'low': 'min',
          'close': 'last',
          'volume': 'sum'}
day_df = df.resample('D').agg(d_ohlc)
day_df = day_df[day_df.index.weekday < 5]#mon==0,...,sun==6
```
参考：
https://note.nkmk.me/python-pandas-time-series-multiindex/
https://python.civic-apps.com/date-format/
https://note.nkmk.me/python-pandas-time-series-resample-asfreq/
https://note.nkmk.me/python-pandas-resampling-ohlc/
JSの全貌

今回は、Javascriptの概念を深ぼってみたのでまとめていきます！！


#1) JS
①ブラウザ内
1.ブラウザに表示された画面に動きを与えることができます。
2.ザーバーと通信を行い、情報の送受信を行うことができます。
　例えば、郵便番号を入力すると住所をサーバーから受信してフォームに表示する(お問い合わせフォーム)、他人が送信したチャット情報を自分の画面に表示させる事ができる（インスタグラム、フェイスブック）、検索フォームに入力した単語に関連するキーワード候補を（Google検索、ヤフー検索）表示させることができます。

②ブラウザの外
1.React（スマホアプリ用のフレームワーク）を使うと、スマホアプリを作ることができます。
2.Node.js（サーバーサイド言語）を使うと、サーバーで動くアプリケーションを作ることができます。
3.Google Apps Script(GAS)これは、Googleが独自に開発した言語ですが、これを使うことでGoogleが提供するサービス（Googleスプレッドシート）などを効率化することができます。

#Jqueryとの違い
　ここで、Jqueryとの違いについて説明します。
結論から言うと、JqueryはJSのライブラリーになります。つまり、JavaScriptを簡単に書くことができるということです。なので、前提条件として、JSがないと存在することができないということです。記述方法も似ているので、気になった人は調べてみてください。
初心者に向いていると言われています。


それでは、本題のJSのできることについてです。
結論から言うと、できないことあるのかな？ってくらいにたくさんあります。
*制御とは、自由勝手に振る舞わせない、支配する。機械装置などの望む通りの運転状態にすることです。

#HTML制御
別の文字に変更、新しい文字に変更、すでにある文字の削除などを行います。

#CSS制御
CSSで表示されていた文字の変更などを行います。

#フォーム制御
1.選択したボタンによって表示内容を変える
2.入力された内容を制御する
　単価×数量＝〇〇円とか
3.入力フォーム内容チェック
　フォームに入力された値をリアルタイムに読み込む。
4.入力文字数のカウント

#アニメーション制御
1.表示・非表示の切り替え
2.フェードイン・フェードアウトの切り替え
3.サイズの拡大・縮小
4.画像の回転
5.移動

#写真制御
1.サムネ写真の切り替え（楽天、アマゾンの商品の切り替えとか）
2.スライド
3.ヘッターを表示

#その他
1.スクロール制限
2.ヘッターを上部に固定する

#JS自体ができること
1) 現在時刻の取得,ポップアップウィンドウの表示,フォームに入力させた値をもとにメッセに返す
2)非同期通信
　Ajaxを使用して行います。
　通常、HTTP通信を同期通信と言います。HTTP通信の場合、リクエストを出してから、レスポンスを受け取るまで処理を実行することはできません。しかし、Ajaxを使うことで、リクエストを出してから、レスポンスを受け取るまでに処理を完了することができます。
メリットは、以下のようになります。
・操作性の向上　・パフォーマンスの向上（ページの一部のみの更新）　
逆にデメリットに関しては以下のようになります。
・クロスブラウザ処理の発生（異なるドメインへのアクセス）　・サーバー負担　・コードの量の増加
Ajaxの構成要素については後ほど。

3)ユーザーの動きに応じて表示内容を変えることができます

4)Node.jsを使うことでサーバーサイドからOSの機能にアクセスすることができるため、ネットワークシステムをJSでかくことができます。

#Ajaxの構成要素　
・XMLHttpRequesut
・javascript
・DOM
・JSON(XML)

#DOM
ドキュメントをものとして扱うものです。
ツリー構造をしています。

![IMG_3EC9C7B920BF-1.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1033397/bd4eb386-685e-47fa-523e-eceb01d68ba5.jpeg)

WEbページとJSをつなぐ役割をしています。
例えば、IDからノードを取得して操作します。

今回の内容は以下のサイトを参考にしていただくとわかりやすいかと思います。

http://www.tamegorou.info/it/2430/　

https://eng-entrance.com/what-is-dom
【Vue.js】プロパティとライフサイクルフックの早見表


#Vue プロパティ

|プロパティ名|役割|
|:--|:--:|
|el|VueインスタンスをどのHTML要素に結び付けるを定義|
|data|Vueインスタンスが保持するデータ（状態）を定義する|
|methods|Vueインスタンスのメソッド（振る舞い）を定義する|
|filters|Vueインスタンスが持つフィルターを定義する|
|computed|Vueインスタンスが持つ算出プロパティを定義する|
|watch|Vueインスタンスが持つウォッチャを定義する|
|components|Vueインスタンスが持つコンポーネントを定義する|
|props|コンポーネントが持つプロパティを定義する|
|emits|コンポーネントが発行するイベントを定義する|

#Vue ライフサイクルフック

|フック名|発生のタイミング|
|:--|:--:|
|beforeCreate|Vueインスタンスが生成された直後に発生|	
|created|リアクティブデータを監視する準備が終わった時|	
|beforeMount|VueインスタンスがDOMと結びつく直前|
|mounted|VueインスタンスがDOMと結びついた直後|
|beforeUpdate|リアクティブデータが更新され、DOMに反映される直前|
|updated|リアクティブデータが更新され、DOMに反映された直後|
|beforeUnmount|Vueインスタンスのマウントが解除される直前|
|unmounted|Vueインスタンスのマウントが解除された直後|
|beforeDestroy|Vueインスタンスが破棄される直前|
|destroyed|Vueインスタンスが破棄された直後|
コロナの影響で会社がオンラインピザのサービスを始めた。

うちはSpeedVisaという「クラウド型在留資格管理システム」(https://s.s-visa.com/)
を運営していましたがコロナがあれで違う方向に向かうことになりました。

新しいサービスのなまえは。。。<h3>SPEED PIZZA!</h3>
![topgif.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/645432/787f9194-d6da-d7ab-643e-e3f45bd57f4b.gif)
ソースや具材などを選んで発行するとなんと３０秒で発行できるピザ！🤤

![merge_from_ofoct (1).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/645432/786140e5-1be7-ffb3-dfef-94e5235860db.jpeg)
最後は3Dで選んだピザの具材が落ちて来ますが画像がないので想像に任せます！
自分はこのプロジェクトのフロントエンドのコーディングをしました。
少しこったのはトップバーのチーズの動きやスクロール祭のアニメーションなどです。
<h4>このプロジェクトで失敗し/わかったこと</h4>

2. デザインを見て不明なところは全部確認する <br>
レスポンジブの情報や実装するのが難しいところなどを確認する。
途中からレスポンシブだとわかって少し時間かかりました。<br>
3. READMEを読む<br>
 readmeにnpmとnodeのバージョンを書いていたのを読んでいなかったためマージのとき色々問題が起こるとこだった。
結果node brewなどのバージョン管理ツールの存在を知りました。＿○／|＿<br>
5. 見積もる<br>![estimate.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/645432/77917349-73c6-fbb4-9975-0c3a783e3229.gif)

自分の会社のものだと後押しにしがちだなと感じました。同じくリリース時間が決まっているのだからちゃんと見積もって時間内につくる！<br>
4. Nuxt jsの面白さ<br>
　動的イメージや簡単な多言語もできるし、ホットリローディング機能もあらためて便利だなと思いました。<br>

<h4>次やりたいこと</h4>
1. ベースから一人で作る。<br>
今回加藤様がベース作りやAPIつなぎをしてくださったんですが次回はベースから最後までつくります！<br>
2. 簡単なレスポンジブの方法を手に入れる。<br>
どんなプロジェクトにも対応できるベースのやり方を考える。
Azure Databricksにて別テナントにあるAzure DevOpsのGitに接続した場合の仕様について

## 概要
Azure Databricksにて別テナントにあるAzure DevOpsのGitに接続することは、2021年4月15日時点では、仕様上不可能です。エラーメッセージと仕様が記載されているドキュメントを紹介します。


## エラー事象
別テナントにあるAzure DevOpsに接続すると、下記のようなエラーが表示されました。

> Unable to parse credentials from Azure Active Directory account. Ensure Azure DevOps account is connected to AAD

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/5125a307-1f17-7515-4619-8908ad26d494.png)


## 仕様が記載されているドキュメント
下記のドキュメントに、同じテナントでないと認証が動作しないことが記載されております。

> Azure DevOps Services 組織は、Databricks と同じ Azure AD テナントにリンクされている必要があります。

引用元：[Azure DevOps Services バージョン管理-Azure Databricks - Workspace | Microsoft Docs](https://docs.microsoft.com/ja-jp/azure/databricks/notebooks/azure-devops-services-version-control#get-started)

## 対策
Azure Databricksと同じテナント上に、Azure DevOpsを用意してください。
stylelintがtsx(jsx)に効かない問題の現時点での対処法

# 何が起きてた？
stylelint 13.3.1から、tsxファイルにstylelintが全く反応しない（問題があってもDoneになる）問題があった
条件は `.babelrc` などのbabel設定ファイルでpluginsの配列要素数が2以上のときだった

issueとしては以下

https://github.com/stylelint/stylelint/issues/4732#issuecomment-682291718

# 直接的要因と思われる場所
https://github.com/stylelint/postcss-css-in-js/pull/2/files

# workaround
```
  "parserOpts": {
    "plugins": ["jsx", "typescript"]
  },
```
を追加すると、stylelint 13.12.0でも動作するようになった

issueにも書いた

https://github.com/stylelint/stylelint/issues/4732#issuecomment-820027303
React 　.envファイル環境変数設定　

① 最新のFirebaseのコンソールでは、databaseURLが自動生成されないので代わりに下記のdatabseURLを使用。


```
REACT_APP_FIREBASE_APIKEY="APIKEY"
REACT_APP_FIREBASE_DOMAIN="DOMAIN"
REACT_APP_FIREBASE_DATABASE="https://PROJECT_ID.firebaseio.com"
REACT_APP_FIREBASE_PROJECT_ID="PROJECT_ID"
REACT_APP_FIREBASE_STORAGE_BUCKET="STORAGE_BUCKET"
REACT_APP_FIREBASE_SENDER_ID="SENDER_ID"
REACT_APP_FIREBASE_APP_ID="APP_ID" 
```


②.envファイルで定義した環境変数を割り当てる

```
const firebaseConfig = {
  apiKey: process.env.REACT_APP_FIREBASE_APIKEY,
  authDomain: process.env.REACT_APP_FIREBASE_DOMAIN,
  databaseURL: process.env.REACT_APP_FIREBASE_DATABASE,
  projectId: process.env.REACT_APP_FIREBASE_PROJECT_ID,
  storageBucket: process.env.REACT_APP_FIREBASE_STORAGE_BUCKET,
  mffessagingSenderId: process.env.REACT_APP_FIREBASE_SENDER_ID,
  appId: process.env.REACT_APP_FIREBASE_APP_ID,
};

firebase.initializeApp(firebaseConfig);
```
Perl: メールの送信

こちらと同じ機能ですが、記述の仕方が異なります。
[Perl: Starttls でメールの送信](https://qiita.com/ekzemplaro/items/e4fa06aa00fa6955ee2c)

```pl:mail_ex01.pl
#! /usr/bin/perl
#
#	mail_ex01.pl
#
#					Apr/15/2021
#
# ----------------------------------------------------------------
use Dotenv;
use Net::SMTP;
#
print STDERR "*** start ***\n";
#
my $env = Dotenv->parse('.env');
print STDERR %$env{'SERVER'} . "\n";
print STDERR %$env{'PORT'} . "\n";
#
my $mailhost = %$env{'SERVER'};
my $mailport = %$env{'PORT'};
my $mail_username = %$env{'FROM'};
my $mail_password = %$env{'PASSWORD'};
my $to_mail = %$env{'TO'};
my $from_mail = %$env{'FROM'};
my $smtp = Net::SMTP->new($mailhost, Port => $mailport);
#
$smtp->auth($mail_username, $mail_password);
$smtp->mail($from_mail);
$smtp->to($to_mail);

my $subject = "Subject: Hello Apr/15/2021 PM 13:47 from Perl\n";

my $header = << "MAILHEADER_1";
From: $from_mail
To: $to_mail
Subject: $subject
Mime-Version: 1.0
Content-Type: text/plain; charset = "ISO-2022-JP"
Content-Transfer-Encoding: 7bit

MAILHEADER_1

$smtp->data();
$smtp->datasend("$header\n");

my $name = "夏目漱石";
my $store = "小山支店";
my $price = "1,200";
my $url = "https://test.example.com";

my $message =<<EOF;
Apr/15/2021 PM 13:46
Hello! This E-mail is automatically sent from Perl program.
こんにちは。これは、テストのプログラムです。
Please check the item
	[NAME]: $name
	[STORE]: $store
	[PRICE]: $price
	[URL]: $url
EOF
#
$smtp->datasend("$message\n");
$smtp->dataend();

$smtp->quit;
#
print STDERR "*** end ***\n";
#
# ----------------------------------------------------------------
```
Unity Cloud Build のAPIからビルドターゲットを作成する場合の注意点

Unity Cloud Build のAPIからビルドターゲットを作成しようとした時に Request Body の設定で嵌った箇所の備忘録です。

### Unityバージョン
説明文では最新バージョンの指定は「latest」とだけ記載されていますが、実際には末尾に対象バージョンを付ける必要がありました。
![unityVersion_field.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/705678/fab529ed-b321-cee9-6e12-4af05cf13756.png)
「latest」だけで実行した場合、以下のエラーメッセージしか表示されず、原因に気づきにくいため注意が必要です。
![response.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/705678/55623c25-e74e-1063-d707-b27bfeeff355.png)

### ビルドスケジュール
デフォルトでは「date」の項目が空の状態で存在しており、気付かずに空のまま実行するとエラーになります。
日時を設定しても良いですが、不要な場合は「Edit JSON」から「date」の項目を削除しても解決します。
![build_schedule.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/705678/86eba607-9299-06ab-ec0d-9c3df69d7d67.png)
Homebrew/homebrew-core (no Git repository) だったときの対処方法


```console
brew install yarn
```

下記エラーが発生。

```console
==> Searching for similarly named formulae...
Error: No similarly named formulae found.
Error: No available formula or cask with the name "yarn".
==> Searching for a previously deleted formula (in the last month)...
Error: No previously deleted formula found.
==> Searching taps on GitHub...
Error: No formulae found in taps.
```

```
#下記コマンドで確認
brew --version

#実行結果
Homebrew 3.0.10
Homebrew/homebrew-core (no Git repository)
Homebrew/homebrew-cask (git revision d6edaf4247; last commit 2021-04-02)
```

`Homebrew/homebrew-core (no Git repository)`この一文が気になる。

ということで、下記を実行。

```
brew doctor

#実行結果
~省略~
Warning: Some taps are not on the default git origin branch and may not receive
updates. If this is a surprise to you, check out the default branch with:
  git -C $(brew --repo homebrew/core) checkout master
~省略~
```

`brew doctor`はhomebrewの問題をチェックするためのコマンドです。

Warningが出たので、この通りコマンドを実行してみます。

```
git -C $(brew --repo homebrew/core) checkout master

#実行結果
Branch 'master' set up to track remote branch 'master' from 'origin'.
Already on 'master'
```

これでもう一度`yarn`をインストールしてみる。

```
brew install yarn

#実行結果
🍺  /usr/local/Cellar/node/15.13.0: 3,273 files, 55.6MB
==> Installing yarn
```

インストールできました。めでたしめでたし。




このときはgoogleで「`No previously deleted formula found.`」と検索した時にヒットした下記記事が参考になった。
[brew installでError: No available formulaが返るとき](https://qiita.com/Feel-Physics/items/98b4aacbd6e52a2bde2e)
AWS SAA合格体験記(知識ゼロからの学び方)

# きっかけ
新卒1年目3月頃、インフラ実務未経験でしたが、徐々に案件の中でAWSに触ることが増えてきて、AWSの知識を横断的に学びたいと思ったので、AWS認定ソリューションアーキテクトアソシエイトを受けることにしました。
知識ゼロから合格するまでに行ったことを体験記として記して行きますー。

# 勉強し始めから合格までの概要
筆者のレベル
理系出身新卒1年目AWSは案件で少し触った程度で勉強したことはない。
2020年2月に勉強を始める(週に５時間程度)
1. 基礎を学ぶ
2. SAAの参考書読む
3. 問題ひたすら解く
2021年4月に合格

# 具体的にやったこと
## 基礎を学ぶ
AWSはSAAより難易度の低いクラウドプラクティショナーという資格があり、今回はその試験を飛ばして、 SAAを受けるため、基礎を学ぶために最初にクラウドプラクティショナーの参考書を読むことにしました。
![image1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/978980/7bc4e803-810b-5e39-4a5b-5dbf8e25a3a9.png)

その参考書がこちら

https://www.amazon.co.jp/AWS%E8%AA%8D%E5%AE%9A%E8%B3%87%E6%A0%BC%E8%A9%A6%E9%A8%93%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88-AWS%E8%AA%8D%E5%AE%9A-%E3%82%AF%E3%83%A9%E3%82%A6%E3%83%89%E3%83%97%E3%83%A9%E3%82%AF%E3%83%86%E3%82%A3%E3%82%B7%E3%83%A7%E3%83%8A%E3%83%BC-%E5%B1%B1%E4%B8%8B-%E5%85%89%E6%B4%8B-ebook/dp/B07QX45RXM/ref=sr_1_4?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&dchild=1&keywords=AWS&qid=1618461846&s=digital-text&sr=1-4


## SAAの参考書読む
https://www.amazon.co.jp/AWS%E8%AA%8D%E5%AE%9A%E3%82%A2%E3%82%BD%E3%82%B7%E3%82%A8%E3%82%A4%E3%83%883%E8%B3%87%E6%A0%BC%E5%AF%BE%E7%AD%96-%E3%82%BD%E3%83%AA%E3%83%A5%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%88%E3%80%81%E3%83%87%E3%83%99%E3%83%AD%E3%83%83%E3%83%91%E3%83%BC%E3%80%81SysOps%E3%82%A2%E3%83%89%E3%83%9F%E3%83%8B%E3%82%B9%E3%83%88%E3%83%AC%E3%83%BC%E3%82%BF%E3%83%BC-%E5%B9%B3%E5%B1%B1-%E6%AF%85/dp/4865941991/ref=sr_1_12_sspa?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&dchild=1&keywords=AWS+SAA&qid=1618461785&s=digital-text&sr=1-12-spons&psc=1&spLa=ZW5jcnlwdGVkUXVhbGlmaWVyPUEyVFRZVDlLMjlHR1RPJmVuY3J5cHRlZElkPUEwMTM3ODQyMVdZRERYVEtFSUxMTiZlbmNyeXB0ZWRBZElkPUE2Rkw1OERMVlg0SjYmd2lkZ2V0TmFtZT1zcF9tdGYmYWN0aW9uPWNsaWNrUmVkaXJlY3QmZG9Ob3RMb2dDbGljaz10cnVl

# 問題ひたすら解く
https://learn-aws.cafe/saa/sign-resilient-architectures

こちらのゴールドプラン

https://aws.koiwaclub.com/
【Flutter】ターミナルで “zsh: command not found:flutter” の解決方法

#原因
・flutterがインストールされている場合、flutterの環境パスがうまく設定されていないのが原因
・OSのアップデートなどで出ることが稀にある
・vimエディタを使ってパスの設定が必要

#解決手順
1. ターミナルを起動
2. **vim ~/.zshrc** と入力
3. **iキー** を押してInsertモードに変更
4. **export PATH="$PATH:/hogehoge/flutter/bin"**と入力<br>
  <font color="red">※ **hogehoge**の部分はflutterをインストールしたパス (追記1)</font>
5. **escapeキー**でInsertモードを終了
6. **:wq** と入力すると保存して終了 (追記2)
7. ターミナルの再起動
8. **flutter doctor** で診断
  
**(追記1)**

・パスがわからなかったら、Finderなどでflutterがあるフォルダを開く
・ターミナルにflutterフォルダをドラッグ＆ドロップすると、フォルダのパスを表示してくれる
・Usersのnameフォルダに入ってる場合は下記が例
　export PATH="$PATH:/Users/name/flutter/bin"

**(追記2)**

**:q**　保存済みのファイルからvimを終了
**:q!**　ファイルを保存しないでvimを終了
**:wq**　ファイルを保存してからvimをを終了
Perlで\p{Hiragana}とかが記号にマッチする問題

みなさん、ワンライナーで日本語を簡単に処理したい場合、何を使うでしょうか。
ワンライナーで言語処理といえばPerlですよね[要出展]。
Perlでは、「ひらがな」「カタカナ」「漢字」といった文字にマッチする正規表現を簡単に書くことができます。
例えば、[青春→鯖鰆みたいなやつ](https://takeda25.hatenablog.jp/entry/20170323/1490238056)という記事では、漢字にマッチさせるのに`\p{Han}`という正規表現を使っていました。

```sh
$ perl -Mutf8 -CSD -le 'print "漢" =~ m{\p{Han}} ? 1 : 0'
1
$ perl -Mutf8 -CSD -le 'print 1 if "あ" =~ m{\p{Han}} ? 1 : 0'
0
```

それが、Perlをアップデートしてから、この正規表現がおかしくなっていることに気づきました。

```sh
$ perl -Mutf8 -CSD -le 'print "「" =~ m{\p{Han}} ? 1 : 0'
1
```

なんてこった。
"「"は明らかに漢字じゃないだろう？

調べてみると、[perlunicode](https://perldoc.perl.org/perlunicode#Scripts)に以下のような記述がありました。

> Prior to Perl v5.26, the single form returned the plain old Script version, but was changed because Script_Extensions gives better results.

「Perl v5.26までは単独形は昔ながらのScriptのバージョンを返していたが、Script_Extensionsにしたよ。そっちのほうが**いい結果**になるからね」

**いい結果**????
それ誰の意見よ??????


そもそもScript_Extentionsとは何か、ということで[Unicodeのページ](http://unicode.org/L2/L2011/11406-script-ext.html)を見てみると、例えば[U+064B ARABIC FATHATAN](https://codepoints.net/U+064B)はアラビア文字でもシリア文字でも使われるから、`\p{scx=Arabic}`でも`\p{scx=Syriac}`でも（scxはScript_Extensionsの略）マッチしてくれるとうれしい、みたいな感じのようです。
ふぅん。
まあいいや。

それで、カギカッコ、つまり[U+300C LEFT CORNER BRACKET](https://codepoints.net/U+300C)について調べてみると、Script_Extensionsは次のようになっています。

> Bopomofo Hangul Han Hiragana Katakana Yi

なるほど、カギカッコは漢字やひらがなやカタカナと一緒に使われるからそれらのScript_Extensions扱い、ということのようです。
しかし、残念ながら――聡明な読者の皆様はお気づきのことでしょうが――日本語を扱う際には、「漢字+各種記号」「ひらがな+各種記号」「カタカナ+各種記号」という集合はまったく使い道がないのです。
なぜかというと、日本語文というのは「（漢字+ひらがな+カタカナ）+各種記号」という構成であって、例えば「カタカナ+各種記号」といった文章は基本的に存在しないからです。

そういうわけで、少なくとも日本語に関しては、**いい結果**どころかひどい結果になるのですが、`\p{Katakana}`は「カタカナ+各種記号」にマッチするようになってしまった、ということです。
こんな非互換変更が入ってしまうなんて…。

仮に、ひらがなとカタカナにのみScript_Extensionsとして「－」（長音記号）が入る、ということであれば、これは明らかに**いい結果**になる変更なので、非互換変更であっても納得できたかもしれません。
でも、そうはならなかった。
そういうわけで、例えばひらがなのみにマッチさせたいとき、Perl v5.26以前であれば`\p{Hiragana}`と書けばよかったところ、Perl v5.26以降では`\p{sc=Hiragana}`と書かなければいけません。
面倒ですが、しょうがないですね。

ちなみに、例えば文章からカタカナ語を抽出したいという場合、`[\p{sc=Katakana}ー]+`のようにするのが常道です。
Script_Extensionsがやりたかったこと、みたいな感じですね。
例えば、このテキスト（`source.txt`とします）について実行すると、次のようになります。

```sh
$ perl -Mutf8 -CSD -nle 'print $1 while m{([\p{sc=Katakana}ー]+)}g' source.txt
ワンライナー
ワンライナー
カタカナ
マッチ
マッチ
...
```
SBI証券HPへのログインを自動化してみた

# やってみたこと  
SBI証券を使って、株のデイトレードをしている。
Chromeで、毎日SBI証券の口座管理ページにログインする作業がルーティンとなっているため、自動化できるかやってみたら、意外と簡単だった。
# 環境  
* Chrome 　
* ChromeDriver
* Python 3.8

# 手順  
1. Chromeインストール  
https://www.google.com/intl/ja_jp/chrome/
1. ChromeDriverをダウンロード  
Chromeのバージョンを確認して、以下サイトで対応するバージョンを選択する  
https://chromedriver.chromium.org/downloads  
1. Pythonで以下のようなコードを作成  

```python:
from selenium import webdriver
from selenium.webdriver import ChromeOptions 
from selenium.webdriver.chrome.webdriver import WebDriver   

driver = webdriver.Chrome(executable_path=r'./chromedriver.exe')    
driver.get('https://www.sbisec.co.jp/ETGate')  

# ****はユーザーID  
loginid = driver.find_element_by_name('user_id').send_keys('****')   
# ****はパスワード  
passwd = driver.find_element_by_name('user_password').send_keys('****')  
Log_in = driver.find_element_by_name('ACT_login').click()  

Account = driver.find_element_by_xpath('//a[img/@title="口座管理"]').click()  
```  
</br>
4. Pythonコードと同じフォルダにChromeDriver.exeを配置して、Pythonコードを実行

# 続きでやってみたこと
[SBI証券の取引履歴から決済損益トップ５、ワースト５を抽出してみた](https://qiita.com/dygl2/items/b12672a5eb7aa4140773)
【Vue × Firebase】データを追加＆取得してみた


#post.vue

```vuejs
<button class="btn" @click.prevent="postItem">投稿</button>
```

```vuejs
<script>
  methods: {
    postItem() {
      firebase
        .firestore()
        .collection("posts")
        .add({
          title: this.title,
          description: this.description,
          image: this.image,
          genre: this.genre,
          time: firebase.firestore.FieldValue.serverTimestamp()
        })
        .then(() => {
          confirm("投稿しますか？");
        });
    }
  }
};
</script>
```
postItem()が押下されたら、dbインスタンスを初期化して"posts"という名前のコレクションを参照し、add()でそれぞれのデータを格納する。

```javascript
time: firebase.firestore.FieldValue.serverTimestamp()
```
作成・編集時刻につきましては、自動で取得してくれる便利なものがありますので、そちらを使用してます。
◇参考　[Firestoreでドキュメントの作成/編集時刻をサーバ側に任せる方法](https://qiita.com/Nappa723/items/2c96d6e3fed2b9f9dc4b)

```javascript
 .then(() => {
          confirm("投稿しますか？");
        });
```
上記で確認ダイアログを表示させています。

```javascript
mounted() {
 this.db = firebase.firestore().collection("posts");
      },
```
※何度も使う場合は、**リファクタリングで関数で定義しておくとGOOD!!**

#board.vue / 親コンポーネント

```vuejs
<List v-for="(list,index) in allData" :index="index" :list="list" :key="list.id" />
```
allDataのデータをlistとindexにそれぞれ格納。

**v-for="(list,index) in allData"**　/ **v-for="(値, キー) in 配列orオブジェクト"** では、下記のようなイメージ。

◇参考　[Vue.jsのリストレンダリングを勉強する](https://qiita.com/Sthudent_Camilo/items/9936cc95c9bcff00fc35)

```
allData1

0.title ～
1.genre　～
2.image　～
3.time　 ～
4.description　～

allData2

0.title　～
1.genre　～
2.image　～
3.time　 ～
4.description　～
```

**:index="index"**　/　**v-bind:属性名="値"**では、下記のようなイメージ。

```
list： [title.genre.image.time.description]
index： [0.1.2.3.4]
```


```vuejs
<script>
export default {
  data() {
    return {
      allData: []
    };
  },

  created() {
    firebase
      .firestore()
      .collection("posts")
      .get()
      .then(snapshot => {
        //"posts"(参照先)のスナップショットを得る
        snapshot.forEach(doc => {
          //上記で得たデータをforEachでドキュメントの数だけ"doc"データに格納
          this.allData.push(doc.data());
          //更にallDataの空箱に格納した"doc"データを格納
        });
      });
  }
};
</script>
```
"posts"コレクションの全ドキュメントを取得し、get()でdoc"データに格納後、push()でallDataに格納してます。


#list.vue　/ 子コンポーネント

```vuejs
      <a href="#" class="small-font">{{user.name}}</a>
      </div>
      <div class="list-ttl">{{list.title}}</div>
      <div class="post-container">
        <p>{{list.description}}</p>
      </div>
      <div class="post-genre">{{list.genre}}</div>
      <div class="btn-inner">
      <button class="btn">ルームへ参加</button>
```
propsを使って親コンポーネントから値を取得したデータがlist内にデータが格納させているので、{{}}を使用してlist内のそれぞれの値を取得。

```vuejs
<script>
  props: {
    list: {
      type: Object
      //propsにより親コンポーネントから受け取ったデータをlist内にObject型で格納されてる
    },
    index: {
      type: Number
      //propsにより親コンポーネントから受け取ったデータをindex内にNumber型で格納されてる
    }
  }
</script>
```

親コンポーネントから取得したデータが下記になります。

```
list： [title.genre.image.time.description]
index： [0.1.2.3.4]
```

◇参考　[Vueのpropsの使い方](https://qiita.com/minuro/items/fa3ddd70ace5b99a1f90)
clasp環境構築に必要なもの

# claspとは
GoogleAppsScriptプロジェクトのコード管理が可能。

TypeScript対応可能。

# clasp環境構築手順

## npm バージョン
```bash:
$ npm --version
6.14.4
```

## npmでインストール
```bash:
$ npm install -g @google/clasp
```

## clasp バージョン
```bash:
$ clasp -v
2.3.0
```

## APIの有効化
オンにする
https://script.google.com/home/usersettings

## clasp ログイン
Googleアカウントへのアクセス許可をする
```bash:
$ clasp login
```

# サンプルプロジェクト
## プロジェクト作成
```bash:
$ clasp create --type standalone "hello"
```

## スクリプト作成
```bash:
$ echo 'function hello() {
     Logger.log("Hello, Apps Script!");
     }' >> hello.js
```

## push
```bash:
$ clasp push
```

## プロジェクトの確認
```bash:
$ clasp open
```

## deploy
```bash:
$ clasp deploy
```

# スクリプト実行
[事前準備](https://github.com/google/clasp/blob/master/docs/run.md)
## GCPにてプロジェクトの作成
作成したプロジェクト情報をメモ

- プロジェクトID
- プロジェクト番号

[GCP Console](https://console.cloud.google.com/cloud-resource-manager)

## プロジェクトIDの設定
```bash:
$ clasp setting projectId [project_id]
Updated "projectId": "" → "[project_id]"
```

## OAuth設定
[project_id]を任意の名前にして、アクセス
https://console.developers.google.com/apis/credentials/consent?project=[project_id]

必要入力項目

- アプリ名（公開ステータス:テスト）
- デベロッパーの連絡先情報
- テストユーザー（自分のメールアドレスを設定）

その他は、空欄でOK

保存する

## GASにプロジェクトIDを設定
```bash:
$ clasp open
```

+ 左のサイドメニューより
![左のサイドメニューより.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192019/1e5bc72f-f0be-cf1a-1cd7-ae09f7243602.png)

+ メモしたプロジェクト番号を入力し、プロジェクトを設定
![プロジェクト番号の設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192019/2fee50e9-c131-6663-fb13-49631628ea89.png)
![プロジェクト番号設定を確認.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192019/9965f102-b694-9438-34a5-fb8aae2c78ed.png)

## OAuth2クライアントを使用
```bash:
$ clasp open --creds
```

+ 認証情報を作成　＞＞　OAuth クライアントID
![OAuthclientID作成.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192019/341acd72-09a6-c65a-1da7-5bcf05ab2208.png)


+ デスクトップアプリを選択　＞＞　作成
![デスクトップアプリを選択.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192019/3d39c55e-591c-045a-cdea-7f6cd1b5a5ca.png)


+ ファイルをダウンロード（`creds.json`というファイル名で保存）
![creds.json保存.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192019/185b5426-484f-6314-0800-43ebe168f6ed.png)

```bash:
$ clasp login --creds creds.json
```

## スクリプトの実行権限を設定
+ `appsscript.json`に追記

```json:appsscript.json
  "executionApi": {
    "access": "ANYONE"
  }
```

```bash:
$ clasp push
```

## スクリプト実行
```bash:
$ clasp run hello
```

# 参考サイト
https://github.com/google/clasp
https://dev.classmethod.jp/articles/typescript-clasp-github-actions/
ERR_TOO_MANY_RETIRES - Chrome

## 現象

最近、Mac Chrome で Basic 認証がかかったページにある日突然アクセスできなくなりました。Safari や Firefox は大丈夫。エラーメッセージは、

```
ERR_TOO_MANY_RETIRES
```

## 原因と解決策

パスワード管理の機能拡張が悪さをしているようなので、それを無効にする。もしくは、Basic認証がかかっているページの自動補完を無効にする（パスワードとか設定してなくても何かしら Try するみたい）。

## 補足

私が使っている LastPass だけの問題なのか分かりませんが、LastPass は問題を認識していて、

> Hello, and I'm sorry for the problems there.  We have a fix for this behavior coming soon in an upcoming LastPass release that should set you straight when using the Chrome app.　
> via. [Twitter](https://twitter.com/LastPassHelp/status/1380576600572317699)

ということなので、すぐ対応されるんじゃないですかね。LastPass は料金プラン変えたばかりなので、頑張って欲しいですね。Safari Extension も復活して欲しい。

ERR_TOO_MANY_xxx 系のエラーでは、SSL 証明書周りで問題が発生することが多いみたいですが、Chromium の Open Issue に関連（すると思われる）項目があるようです。

▶ [Issue 488043: Socket pools should be aware of HTTPS certificate exceptions](https://bugs.chromium.org/p/chromium/issues/detail?id=488043)

1年近く放置されてるので、諦めたのかも。