OmniAICreator/Qiita-1.07M huggingface dataset:
TimeoutError: Navigation timeout of 30000 ms exceededの解消方法

Jestでpuppeteerを実行しているとTimeoutエラーが発生することがあります。

```
TimeoutError: Navigation timeout of 30000 ms exceeded
```

対策としてページ遷移系の命令のTimeout時間を無効化する方法が２つあります。

## スクリプト全体に設定する

全てのページ取得命令に対して一括でTimeoutを設定します

```javascript
await page.setDefaultNavigationTimeout(0); 
await page.goto('https://www.example.com');
```

スクリプト全体

```javascript:top.test.js
describe('Top', () => {
  beforeAll(async () => {
    await page.setDefaultNavigationTimeout(0); 
    await page.goto('https://www.example.com');
  });

  it('should be titled "Example Domain"', async () => {
    await expect(page.title()).resolves.toMatch('Example Domain');
  });
});
```

## ページ取得のオプションを設定する

個別のページ取得に対してTimeoutを設定します

```javascript

await page.goto('https://www.example.com', {
  waitUntil:'load',
  timeout:0
});
```

スクリプト全体

```javascript:top.test.js
describe('Top', () => {
  beforeAll(async () => {
    await page.goto('https://www.example.com', {
      waitUntil:'load',
      timeout:0
    });
  });

  it('should be titled "Example Domain"', async () => {
    await expect(page.title()).resolves.toMatch('Example Domain');
  });
});
```

## 参考

[page.setDefaultNavigationTimeout() のリファレンス](https://pptr.dev/#?product=Puppeteer&version=v5.2.1&show=api-pagesetdefaultnavigationtimeouttimeout)
[page.goto() のリファレンス](https://pptr.dev/#?product=Puppeteer&version=v5.2.1&show=api-pagegotourl-options)

## 最後に

30秒タイムアウトの出所ですが、コードを読むとデフォルト値として設定されていました

https://github.com/puppeteer/puppeteer/blob/main/src/common/TimeoutSettings.ts

```javascript:TimeoutSettings.ts
const DEFAULT_TIMEOUT = 30000;
```

そして同じデフォルト値を使う設定メソッドがもう１つあることを発見しました

```javascript
setDefaultTimeout(timeout: number): void {
  this._defaultTimeout = timeout;
}
```

マニュアルによれば、こちらはページ遷移メソッドに加えて、リクエスト時間などについてもTimeout値を変更できるようです
[page.setDefaultTimeout() のリファレンス](https://pptr.dev/#?product=Puppeteer&version=v5.2.1&show=api-pagesetdefaulttimeouttimeout)

案外読みやすいコードだったので、これからはソースコードも確認しようと思いました。
[初学者の備忘録]ReactとDjangoを組み合わせる

# 執筆背景
現在、就職活動用の成果物作成に取り掛かっています(文系実務未経験の大学生です)。そこで、私はバックエンドに`Django`、フロントエンドに`React`を使うこととしました。
しかし、一つ疑問が生じます。

_これどうやって組み合わせるんだ?_

初学者で情報系出身でもない学生です。知識は皆無です。`Django`,`React`それぞれでCRUDアプリケーションを作りましたが、それはどちらも片方のフレームワークのみで作成したものです。これを組み合わせるためにいろいろ調べたので、その結果を不確かかもしれませんがアウトプットとして残しておきたいと思います。

# Django Rest Frameworkについて
これを初めの見出しに持ってきたのは理由があります。
それは、私自身が「これは組み込まないといけないものなのか?」と一番はじめに疑問に思ったものだったからです。

私が調べた限りの結論では、
__`React`と`Django`を組み合わせるなら絶対`DjangoRestFramework`は必要__
となります。

これを説明するためには最近のモダンなJavaScriptの開発状況について説明をしなければいけません。

# モダンJavaScriptの開発状況
私の理解を助けるきっかけとなった記事が[こちら](https://qiita.com/klriutsa/items/7f6047485968c61b6a5d)。

私はここで2つの重要なことを知りました。

__1.モダンなWebページはJSONでデータをやり取りするようになった__
__2.仮想DOMを用いて、HTMLを細かく分けるようになった__

実はこの記事に辿り着く前に、`DangoRestFramework`はオブジェクトをJSONに変換できるということを学んでいました。そして、ここで一つのことがわかります。

__サーバー側からの情報をフロント側に伝えるためには、JSONに変換しなければいけない__
__>`DjangoRestFramework`は`React`と`Django`を組み合わせる上で必須__

`React`,`Django`の組み合わせという最初の話題だとこれで結論となります。
しかし、私はまだ終わりませんでした。

- __　仮想DOM__という概念が曖昧だったこと
- 「__バックエンドはフロントエンドにデータを渡すために、APIを作る__」という表現がうまく飲み込めなかったこと

この二つのモヤモヤが残ったので、より調べることにしました。

しかし、話が流れていきそうなので、記事を別に更新しようと思います。

# まとめ
__1.フロント、サーバー間は、モダンな技術ではJSONデータが交換される__
__2.`DjangoRestFrameWork`は`Django`の取得したデータをJSONに変化してくれる__
__3.`React`,`Django`を組み合わせるためには、JSONデータをパスするために,`DjangoRestFramework`を用いなければならない__

ということです。
拙く、知識不足、勉強不足が滲み出ている記事だとは思いますが、ご覧いただきありがとうございました。
この記事が、皆様の理解を少しでも助けられればと思います。
【備忘録】OpenPyXL　get_sheet_names()、get_sheet_by_name()のDeprecationWarning

# 事象
```python
import openpyxl

wb = openpyxl.load_workbook('example.xlsx')
sheet_names = wb.get_sheet_names()
print(sheet_names)

sheet = wb.get_sheet_by_name('Sheet1')
value = sheet.cell(row=1, column=1).value
print(value)
```

警告が表示される。
```DeprecationWarning: Call to deprecated function get_sheet_names 
(Use wb.sheetnames).sheet_names = wb.get_sheet_names()```

```DeprecationWarning: Call to deprecated function get_sheet_by_name 
(Use wb[sheetname]).sheet = wb.get_sheet_by_name('Sheet1')```

# 解決策
警告文の***Use***に従って下記のように書き換える。
```sheet_names = wb.sheetnames```
```sheet = wb['Sheet1']```

```python
import openpyxl

wb = openpyxl.load_workbook('example.xlsx')
sheet_names = wb.sheetnames
print(sheet_names)

sheet = wb['Sheet1']
value = sheet.cell(row=1, column=1).value
print(value)

```

#まとめ
非推奨！という警告なので、使えないという訳ではない。でも、警告でたら直したくなるよね。
[Swift]UIDocumentPickerViewControllerから.objファイルを読み込む

##結論
```
"public.geometry-definition-format"
```

##詳細
iOSはファイルを保存するデータ領域の1つに共有領域というものがあります。
この領域へのアクセスはデフォルトで入っているファイルアプリを使うのが一般的ですが、他のアプリからもこの領域にアクセスして例えば写真や動画などを取得することができます。

具体的にはUIDocumentPickerViewController(以下"PickerVC")を実装することになります。
例えば.txtファイルを取得したい場合は

```swift:
UIDocumentPickerViewController.init(documentTypes: ["public.plain-text"], in: .open)
```

という形になります。
ここでdocumentTypesの引数にしている"public.plain-text"が.txtファイル用のIdentifierです。
Identifierとはその名の通りファイルの識別子のことで、この識別子に該当するファイルのみ取得できるように制限しています。

[AppleはこのIdentifierの一覧を公開している](https://developer.apple.com/library/archive/documentation/Miscellaneous/Reference/UTIRef/Articles/System-DeclaredUniformTypeIdentifiers.html#//apple_ref/doc/uid/TP40009259-SW1)んですが、この一覧に無いものもあります。.csvとかも無いですね。
ただ、一覧に無いから読み込めないというわけではなく、管理元に行って自分で調べてね、というスタンスみたいです。
(ちなみに.csvのIdentifierは"public.comma-separated-values-text"です)

さて、最近はARが色々盛り上がっているみたいで、会社にもLiDAR付きの新しいiPad Proが届きました。
これからどんどんARが身近になっていくわけですが、ARで表示する3Dモデルにもいくつか種類があります。
その中でも.objファイルは昔から3Dモデルを表示するためによく使われてきました。

その.objファイルですが、こちらも例によってIdentifierはAppleの一覧には存在せず。
色々探したところ、下記のような形にすればアクセスできるとのことです。

```swift:
UIDocumentPickerViewController.init(documentTypes: ["public.geometry-definition-format"], in: .open)
```

※検証環境: Xcode11.6 Swift5.2

試してみましたが確かにPickerVCから.objファイルを選択することができました。
.glb(.gltf)や.usdzについてはまた今度検証してみたいと思います。
シローの定理の偉大さ

#最初に
プログラムの話題はありません。数学の話題のみです.

##シローの定理とは
シローの定理とはシローさんが発見した有限群論の定理たちの総称です.
その中で僕が一番好きなのは
$p_i\in \mathbb{P}$とする.$ |G|=p_{1}^{e_1}p_{2}^{e_2}\cdots p_{k}^{e_k}$であるとき
位数$p_{i}^{e_i}$である部分群が存在する
という存在定理です.
##なぜ存在定理がよろしいのか
逆ではないのですが定理の逆に似ているラグランジュの定理というのがあります

###ラグランジュの定理
群$G$に対して部分群が存在すればその部分群の位数は元の群の位数を割り切る
というのをラグランジュの定理といいます.
しかしこれはあくまで「存在すれば」であって存在性を言及しているわけではありません.
群に部分群が存在するかどうか。有限群論を分類するうえで避けては通れない問題のヒントにはなりますが解決にはならないんですね.

##シローの定理を使わずに部分群が存在することを示してみよう
実際やってみましょう
命題
$|G|=6$とする. 位数$3$となる部分群$H$が存在することを示せ.

pf
もし存在すれば$H$は巡回群である(素数位数のため)
なので$\operatorname{ord}(g)=3$となる$g \in G$が存在することを示せばよい.
$\operatorname{ord}(g)$は$|G|$の約数であるため可能性としては
$\operatorname{ord}(g)=1,2,3,6$のいずれかである

$\operatorname{ord}(g)=1$となるものは単位元しか存在しない
$\operatorname{ord}(g)=3$となるものが存在すれば解決
$\operatorname{ord}(g)=6$となるものが存在すれば,$\operatorname{ord}(g^2)=3$であるため解決
そのため
$G=\\{1,a,b,c,d,e\\}$
かつ
$\operatorname{ord}(a)=\operatorname{ord}(b)= \cdots =\operatorname{ord}(e)=2$
となる群$G$が存在しないことを示せばよい.

このような$G$が存在したとしよう.
単位元を除く各元の$\operatorname{ord}$は2なので
$ab=c$を満たすとする($a,b,c,d,e$は置換すればよろしいのでなんでもよい)
また
$a=a^{-1}, b=b^{-1}, \cdots, e=e^{-1}$なので
$a=cb, b=ac$を満たす.
さらに
$(ab)^2=c^2=1$より
$ab=b^{-1}a^{-1}=ba$が成立.同様に考えると$a,b,c$は任意の二元で可換である.
これを考えると
集合$\\{1,a,b,c\\}$は$G$の演算で群をなす.(可換なので結合則は良い.単位元はある.逆元は自分自身)

よって$\\{1,a,b,c\\}$は$G$の部分群だ.

しかし$|G|=6, |\\{1,a,b,c\\}|=4$であり4は6の約数ではない.

これは矛盾である

よってこのようなGは存在せず位数6の群には$\operatorname{ord}=3$となる$g \in G$が存在する.

そのような$g \in G$で生成された最小の部分群$\langle g \rangle$は位数3の$G$の部分群である

##シローの定理を使わない感想
マジでだるい.本当にだるい.
位数6という単純な群でこれです.
そりゃシローの定理はちやほやされますよね。

これだけですがシローの定理の偉大さがなんとなくわかった気がします.
2020.08振り返り


8月の開発期間を終了しての振り返りです。

## 振り返るにあたって

開発チームでは1か月毎に振り返りを行い、

- 失敗
- 問題、改善点
- そして成功、良かった点

を皆で前向きに発表して次に生かすということを行っています。


## 成功

[バッチサーバーを ”Fargate化”しました](https://qiita.com/e99h2121/items/cd0dea16b946869e1846)
en: [Batch server is now Fargated (バッチサーバーをFargate化しました)](https://qiita.com/e99h2121/items/513302e1cf1c9ad35367)

と、9月の準備 [SAMLと私](https://qiita.com/e99h2121/items/81c4557934dae1c0fe02)


## 失敗

- 相変わらず障害対応してる...

## 改善したい点

### LightningTalk文化

気軽にもっとQiita広めたいな
- [バッチサーバーを ”Fargate化”しました](https://qiita.com/e99h2121/items/cd0dea16b946869e1846)
- [Slack仕草](https://qiita.com/e99h2121/items/6a6f06cfaf4a74fca0f3)


## まとめ
- 機能強化と、保守と、私生活のバランスを取りたい。


## 履歴

2020.04 [2020年、（3歳1歳と）私のリモートワーク](https://qiita.com/e99h2121/items/c8878d027603745a6426)
2020.05 [在宅育児（と勤務）を支える技術](https://qiita.com/e99h2121/items/475045cabd005a7add57)
2020.05 [子連れで在宅育児（と在宅勤務）を開始して１か月が経ちました](https://qiita.com/e99h2121/items/cb7471fd833b086b7233)
2020.06 [緊急事態宣言が解除されてリモートワークはどうなるのか](https://qiita.com/e99h2121/items/086822c3f74ebca75364)
2020.07 [新しい開発様式](https://qiita.com/e99h2121/items/ae4f480cb074b3905749)
2020.08 [2020.07振り返り](https://qiita.com/e99h2121/items/c039bd281c7a62a19412)
Ubuntu 18.04 LTSにMoodleをインストールする

パッケージアップデート

```sh
sudo apt update
sudo apt upgrade -y
```

必要なパッケージを追加

```sh
sudo apt-get install -y zip lamp-server^ php7.2-curl php7.2-zip php7.2-xml php7.2-mbstring php7.2-gd php7.2-intl php7.2-xmlrpc php7.2-soap
```

パーミッションの設定

```sh
sudo usermod -a -G www-data ubuntu
sudo chown -R ubuntu:www-data /var/www
sudo chmod 2775 /var/www && find /var/www -type d -exec sudo chmod 2775 {} \;
find /var/www -type f -exec sudo chmod 0664 {} \;
```

コードを取得

```
cd /var/www/html
git clone -b MOODLE_39_STABLE git://git.moodle.org/moodle.git
```

パーミッションの設定

```sh
sudo chown -R www-data /var/www
sudo chgrp -R www-data /var/www
sudo chmod 2775 /var/www
find /var/www -type d -exec sudo chmod 2775 {} \;
find /var/www -type f -exec sudo chmod 0664 {} \;
```

Apacheの設定

```sh
sudo vi /etc/apache2/sites-available/000-default.conf # DocumentRootを `/var/www/html/moodle` に変更
sudo a2enmod rewrite
sudo systemctl restart apache2
```

データベースの設定

```sh
sudo mysql_secure_installation
sudo mysql
```

SQLを実行

```sql
CREATE DATABASE moodle DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'moodle'@'localhost' IDENTIFIED BY 'password';
GRANT ALL PRIVILEGES ON `moodle`.* TO "moodle"@"localhost";
FLUSH PRIVILEGES;
exit
```

Moodleの設定

```sh
mkdir /var/www/html/moodledata
sudo chown -R www-data /var/www/html/moodledata
```

`crontab -e`を実行し、以下の行を追加する。

```
* * * * *    /usr/bin/php /var/www/html/moodle/admin/cli/cron.php >/dev/null
```

ブラウザでURLにアクセスし、画面にしたがってインストールを完了する。
ディレクトリを指定してJupyter Lab（またはJupyter Notebook）を開く

# 環境
- Windows 10
- Anaconda 3.7.0

# こうする
次のようにPowerShellでディレクトリを指定して開きます。
（Anacondaのパスが通っていないとJupyter Labが起動しないようです）

```powershell
> jupyter-lab.exe --notebook-dir "C:\users\yama\desktop\新しいフォルダー"
```
EC2 + NginxでCSRキーを作成する

## 秘密鍵作成するディレクトリに移動する

```bash
cd /etc/pki/tls/private
```

## 秘密鍵を生成する

```bash
sudo openssl genrsa -out custom.key
```

## 新しいプライベートキーに、所有権とアクセス権を設定する

```bash
sudo chown root:root custom.key
sudo chmod 600 custom.key
ls -al custom.key
```

### 次のような結果になる

```bash
-rw------- root root custom.key
```

## CSRキーを作成する

```bash
sudo openssl req -new -key custom.key -out csr.pem
```

## CSR生成情報を入力する

|  項目名  |  説明  |  例  |
| ---- | ---- | ---- |
|  Country Name※  |  国を示す2文字のISO略語  | JP  |
|  State or Province Name※  |  組織が置かれている都道府県  | Tokyo  |
|  Locality Name※  |  組織が置かれている都道府県  | Minato-ku  |
|  Organization Name※  |  組織名  | Appre inc.  |
|  Organization Unit Name  |  部署名  |    |
|  Common Name※  |  申請するサーバ証明書のコモンネーム  | example.com |
|  Email Address  |  入力不要  |    |
|  A challenge password  |  入力不要  |    |
|  An optional company name  |  入力不要  |    |


### 参考記事
https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/SSL-on-amazon-linux-2.html
IBM Cloud IAMのアクセス・グループの設定

# はじめに

システムを管理するうえで、管理を担当するユーザに対して適切な権限を付与し、システムに対する不正な操作や、誤操作による事故を防ぐことは非常に重要です。

IBM CloudのIAM（IBM Cloud Identity and Access Management）サービスでは、アカウントに参加するユーザに対して個別にアクセス権限を設定することが可能ですが、ユーザが増えてきた場合に、ユーザ単位にアクセス権限を設定することは非常に煩雑な処理になり、権限設定のミスが発生する可能性が高くなります。

そのためIBM CloudのIAMでは、「アクセス・グループ」という仕組みを提供しています。アクセス・グループに1人あるいは複数のユーザを所属させ、アクセス・グループに対して権限を付与することで、そのアクセス・グループに所属するユーザは、アクセス・グループに付与された権限を持つことになります。

これにより、新たなユーザを追加する場合、そのユーザをアクセス・グループに追加するだけで必要な権限を与えることが可能になります。


# アクセス・グループの設定手順

IBM Cloudの[アクセス・グループ管理のページ](https://cloud.ibm.com/iam/groups)にアクセスします。

「作成」ボタンをクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386149/f33c163b-08dc-9940-9a5f-cd705df43543.png)

ダイアログが表示されるので、アクセス・グループの名前を入力し、「作成」ボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386149/7d24dade-bcff-f146-8e63-eb2dc2093362.png)

以下のようにアクセス・グループが作成されます。
この状態ではアクセス・グループは何の権限も持たないので、作成したアクセス・グループに対して権限を設定していきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386149/daeab9bc-d6e0-e9e4-16d9-ca7dc2b0f9c7.png)

ここでは、このアクセス・グループにアカウント管理（ユーザ追加や支払い情報の参照など）の権限を付与していきます。
「アクセス・ポリシー」タブを選択し、「アクセス権限の割り当て」ボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386149/280de863-0d2c-07e1-d903-498215b3ab2d.png)

「アカウント管理」をクリックし、「すべてのアカウント管理サービス」を選択します。
その後、「ビューアー」「オペレーター」「エディター」「管理者」にチェックを付け、「追加」ボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386149/50649b26-f653-d3be-3f92-0a7a412379ee.png)

アクセス・サマリーに先ほど追加した権限が表示されるので、「割り当て」ボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386149/e09a97ff-e5b3-f672-31fc-62c5b8fa59b9.png)

アクセス・グループに対して、先ほど追加した権限が割り当てられました。
次にこのアクセス・グループに所属するユーザを追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386149/e087a5eb-0fb2-dde5-4e3a-cceffc82fb8f.png)

「ユーザー」タブを選択肢、「ユーザーの追加」ボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386149/743daecd-b604-8a80-4ff2-14aba9e8e5cd.png)

追加するユーザーにチェックを付け、「グループに追加」ボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386149/cf0195bf-1d7e-76c6-4b46-685b266cfa0c.png)

これでアクセス・グループにユーザーが追加されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386149/840c393c-db32-523e-b282-5958a015875e.png)

このアクセス・グループに所属するユーザーはアカウント管理の権限を持ちます。例えば、アカウント管理者を追加したい場合はこのアクセス・グループに追加するだけでよく、役割の変更によりアカウント管理者を外れる場合はアクセス・グループから削除するだけでよい、といったように運用がスッキリします。
【PowerAutomate】Teamsへフローボットとしてチャネルに投稿

#Teamsへフローボットとして投稿
##注意
注意事項ですが､本記事が唯一絶対の方法とは限りません｡
また記載に間違いがあるかもしれません､何卒ご了承くださいませ｡

##PowerAutomateとは(めっちゃ簡単に)
Microsoft社が提供している4つのPowerPlatformの内の1つです｡
PowerAutomateは積み木やレゴをする感覚で視覚的に自動化がすることが可能でして､
使い方さえマスターしてしまえばあんなことやそんなことも自動化できちゃいます｡

##Teamsへフローボットとして投稿
####はじめに
本記事はインスタント(手動)フローで作成しています｡
また局所的な説明となっておりますのでご了承ください｡

####全体
![fff.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700727/cf7d8ae2-3f4b-d593-d785-86b84520dfae.png)

####１．アクションの検索
検索欄に｢teams｣を入力するとTeamsに関するアクションが表示されます｡
![aa.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700727/5f3ffe6a-dc4e-5729-af40-461f3ef1036d.png)

####２．アクションの選択
ここではチャネルに投稿verを選択します｡
![bb.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700727/6d2d6059-212c-d4d3-3a5a-99af637edcee.png)

####３．アクションの設定
チャネルへ投稿するためには､まずそのチャネルが含まれているチームを設定します｡(必須)
![ccc.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700727/f9f61b06-c66c-bbbb-6808-d85780d67327.png)


次に先ほど選択したチームの配下にあるチャネルを選択します｡
![ddd.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700727/21b13548-e541-dfed-e44d-ea4f72c40376.png)

####４．メッセージの作成
ここはHTML形式で入力可能ですが､タグつけなくても大丈夫です｡
メッセージを入力したら､｢保存｣ボタンを押下してください｡
![eee.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700727/95388501-ace0-0ea8-4d98-ef69e4e6f4cd.png)

####５．動作確認
テスト実行して､｢ご利用のフローが正常に実行されました｡｣と表示されていればOKです｡
あとはチャネルに投稿されてるか確認してみましょう｡
![hhh.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700727/97057484-18bc-5a37-0af5-f23c00274b80.png)
![ggg.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700727/ba5f7d52-0a0f-1999-fbf7-bda9173ab07e.png)
アイコンが自身のプロフィール画像になっていなければ､成功です｡
![iii.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700727/c3a5a1b6-9c67-1edc-561f-ad1e8eb30246.png)

##おまけ
◆メンションについて
１．個人へメンション　
　　メッセージ内でメンションしたい方のメールアドレスを｢\<at>\</at>｣で囲むだけです。
　　例:\<at>quitta@qitta.com\</at>

２．チーム・チャネルへメンション
　　上記の｢\<at>\</at>｣で囲む方法ではメンションできません｡これは仕様です｡
　　ただ別の方法でチーム・チャネルへメンションする方法があるにはありますが
　　RestAPIとjsonに関する知識が多少なりとも必要となるためちょっと難しいです｡
　　
　　詳細はこちら　→　https://qiita.com/kaitomate/items/e681cfe19cb9fb496ef2

##最後に
質問や要望がございましたら､可能な範囲で記事を書きます｡
お気軽にコメントください｡
AA de Knight #4の『 Find the Knight 』でA2019チャレンジ

# はじめに
Automation Anywhere A2019を勉強中のtakです。
社内ではAA Version11を使用しており、A2019は私物PCにCommunity Editionを入れています。
さて、先日AA de Knight #4というオンラインイベントに参加しました。その中の『Find the Knight』にチャレンジしてのA2019感想です。
いろいろ苦戦したので次戦に向かっての私的備忘録。

# AA de Knight #4と『Find the Knight』って？
AA de KnightはSB C&S株式会社が主催されているRPAの勉強会です。
その第4回目の中で『Find the Knight』というコーナーがありました。これはA2019を使ったロボット開発コンテストです。
- 制限時間30分でお題に沿ったロボットを作る
- 早く作れた人、ロボットの実行時間が短い人、が表彰される

# 苦戦した点（１）レコーダー
最初にお題の動作をレコーダーで全体記録して編集しようとしました。
すると「レコーダー：キャプチャ」のボックスがいっぱいできて、どのボックスで何をやっているのか探すのにひと苦労。フロー表示のボックスだと説明文があまり見えないんです。
プレビューの画像で判断しようとしたのですが、表示が少し遅くて苦戦。
以下、反省点。
- レコーディングは全部を1回ではなく、いくつかの部分に分けて取るべきだった
- リスト形式で見ればよかった（なぜここに気づかなかった）

# 苦戦した点（２）通信
レコーダーのプレビュー部分もですが、通信が遅くてテストに苦戦。Bot実行前のダウンロードに時間がかかり、心は焦るけど手が出せない（笑）。
通信の遅さが自分の環境にあるのか、Community Editionだからなのか、わかりませんが次回あるなら以下は試してみたい。
- PCはwifiでなく有線LAN直結
- 会議開始前に最新パッケージをプレロードしておく

# さいごに
通常業務ではタイムアタックなんてしないと思いますし、初めての体験でしたがおもしろかったです。また、自分の力不足を痛感した30分でした。次回があればがんばろう（今回は惨敗）。
Laravel MailCatcherでメールを受け取る

# 目的

- Macに直接作成したローカル開発環境のLaravelアプリから送信したメールをMacに直接立てたMailCatcherで受け取る方法をまとめる。

# 実施環境

- ハードウェア環境

| 項目 | 情報 |
| --- | --- |
| OS | macOS Catalina(10.15.5) |
| ハードウェア | MacBook Pro (13-inch, 2020, Four Thunderbolt 3 ports) |
| プロセッサ | 2 GHz クアッドコアIntel Core i5 |
| メモリ | 32 GB 3733 MHz LPDDR4 |
| グラフィックス | Intel Iris Plus Graphics 1536 MB |

- ソフトウェア環境

| 項目 | 情報 | 備考 |
| --- | --- | --- |
| PHP バージョン | 7.4.3 | Homwbrewを用いて導入 |
| Laravel バージョン | 7.0.8 | commposerを用いてこちらの方法で導入→[Mac Laravelの環境構築を行う](https://qiita.com/miriwo/items/adaaaeecae69d6392e08) |
| MySQLバージョン | 8.0.19 for osx10.13 on x86_64 | Homwbrewを用いてこちらの方法で導入→[Mac HomebrewでMySQLをインストールする](https://qiita.com/miriwo/items/ef6a064bc545fbea29d9) |

# 前提条件

- 下記またはそれに準ずる方法でLaravelの環境構築が実施されていること。
    - [Mac Laravelの環境構築を行う](https://qiita.com/miriwo/items/adaaaeecae69d6392e08)

# 前提情報

- 筆者はLaravelの環境をMacに直接構築して実施した。
- Laravelの環境は下記の方法で実施した。下記の環境においてLaravelのアプリを作成して実施する。
    - [Mac Laravelの環境構築を行う](https://qiita.com/miriwo/items/adaaaeecae69d6392e08)
- Laravelアプリからのメール送信処理は下記の方法で処理を実装した。
    - [Laravel7 ユーザ認証時にメールアドレスを確認する処理を追加する]()

# 読後感

- Laravelから送信されたメールをMailCatcherで受け取ることができる。

# 概要

1. MailCatcherの導入と起動
1. .envファイルの記載
1. 確認

# 詳細

1. MailCatcherの導入と起動
    1. 下記コマンドを実行してMailCatcherをインストールする。

        ```terminal
        $ sudo gem install mailcatcher
        ```
    1. 下記コマンドを実行してMailCatcherを起動する。

        ```terminal
        $ mailcatcher
        ```
    1. 下記にアクセスする。
        - [http://127.0.0.1:1080](http://127.0.0.1:1080)
    1. 下記のページが表示されることを確認する。

        ![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f3330363431372f39633163623538302d383264352d623939322d316433652d6336323034666432623038392e706e67.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/1dd5db58-f578-7895-7a55-d1a2ecc35f92.png)

1. .envファイルの記載
    1. .envファイルのMail設定部分を下記の様に修正する。

        ```.env
        MAIL_DRIVER=smtp
        MAIL_HOST=127.0.0.1
        MAIL_PORT=1025
        MAIL_ENCRYPTION=null
        MAIL_FROM_ADDRESS=admin@gmail.com
        MAIL_FROM_NAME=admin
        MAIL_USERNAME=null
        MAIL_PASSWORD=null
        MAIL_PRETEND=false
        ```
1. 確認
    1. Laravelアプリからメールを送信する。
    1. 下記の様にブラウザでMailCatcherを表示しメールが受信できていることを確認したら作業完了である。

        ![MailCatcher__1_.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/8480112f-6ff7-82c0-174c-4bd96bde48ea.png)
Error: JS interop classes do not support non-external constructors　の解決法

#環境
macOS Catalina 10.15.4
dart sdk 2.9.2
Homebrew 2.4.14

https://dart.dev/get-dart
を参考にdart sdkをbrewでインストールしている状況。
#解決法
下記を参考にdart sdkのバージョンを2.6.0に下げる。
https://qiita.com/nghryuki/items/7d65d8f55ea65b95310d

以下参考までに自分の実行コマンド。

```terminal
cd /usr/local/Homebrew/Library/Taps/dart-lang/homebrew-dart
```
↑個人によって場所が違うかもしれません。dart.rbがあるフォルダを探してください。

```
git log dart.rb
```

```
git checkout <commitID> dart.rb
```

```
brew unlink dart
```

```
brew install dart
```

```
**-Pro:DeepIE3D_Frontend katayamashunsuke$ brew info dart
Warning: Calling 'devel' blocks in formulae is deprecated! Use 'head' blocks or @-versioned formulae instead.
Please report this issue to the dart-lang/dart tap (not Homebrew/brew or Homebrew/core), or even better, submit a PR to fix it:
  /usr/local/Homebrew/Library/Taps/dart-lang/homebrew-dart/dart.rb:32

dart-lang/dart/dart: stable 2.6.0, devel 2.6.0-dev.8.2
The Dart SDK
https://www.dartlang.org/
/usr/local/Cellar/dart/2.6.0 (474 files, 473.9MB) *
  Built from source on 2020-08-31 at 00:19:03
/usr/local/Cellar/dart/2.9.2 (509 files, 523.7MB)
  Built from source on 2020-08-30 at 19:12:42
From: https://github.com/dart-lang/homebrew-dart/blob/HEAD/dart.rb
==> Options
--devel
	Install development version 2.6.0-dev.8.2
==> Caveats
Please note the path to the Dart SDK:
  /usr/local/opt/dart/libexec
```

brew info dartで上のように2.6.0の横に*がついてれば完了です。
【AWS EC2】ec2-userと同様にsudo可能なユーザーを追加する

# 概要
Amazon Linux2のデフォルトユーザーec2-userの他にsudo可能なユーザーを追加する

# 環境
- EC2 Amazon Linux2
- Windows10
 - Ubuntu(WSL: Windows Subsystem for Linux)
 - RLogin(sshクライアント)

# 手順
## 1. AWSマネジメントコンソールからキーペアを作成する
1. EC2 > ネットワーク&セキュリティ > キーペア
2. キーペアを作成
![key_pair.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265229/a3c0cd53-9149-cd8e-1df2-49cd0fd68c38.png)
3. 名前にキーペア名を入れて、pem形式でキーペアを作成
4. pemファイルがダウンロードされるので、ローカルPCの適切な場所に保管

## 2. キーペアから公開鍵を取得する
1でダウンロードしたpemファイルから公開鍵を取得する。
`ssh-keygen`を使いたい&ダウンロードしたファイルにアクセスしたいので、私はWSLのUbuntuを使いました。

```
# 公開鍵を取得したいだけなので、適当なdirを作成
$ mkdir sshkey

# Windowsのダウンロードフォルダから1でダウンロードしたpemファイルをコピー
$ cp /mnt/d/Users/tamorieeeen/.ssh/ec2_keypair.pem sshkey/

# 権限がガバガバだとこんな感じで怒られる
$ ssh-keygen -y -f sshkey/ec2_keypair.pem
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@         WARNING: UNPROTECTED PRIVATE KEY FILE!          @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions 0777 for 'sshkey/ec2_keypair.pem' are too open.
It is required that your private key files are NOT accessible by others.
This private key will be ignored.
Load key "sshkey/ec2_keypair.pem": bad permissions

# pemファイルの権限を変更して公開鍵を取得
$ chmod 400 sshkey/ec2_keypair.pem
$ ssh-keygen -y -f sshkey/ec2_keypair.pem
ssh-rsa AAAABBBBCCCC…
```

## 3. サーバー上でユーザーを追加してssh鍵を登録する

```
# ec2-userでsshログインして
$ sudo adduser tamorieeeen
$ sudo su - tamorieeeen
$ mkdir .ssh
$ chmod 700 .ssh/
$ touch .ssh/authorized_keys
$ chmod 600 .ssh/authorized_keys
$ vi .ssh/authorized_keys
# 2で取得した公開鍵を貼り付けて:wqで保存
$ exit
```

wheelグループに所属させてsudoをノンパスで行えるようにする

```
$ sudo usermod -aG wheel tamorieeeen
$ sudo visudo
# %wheelのコメントアウトを外して:wqで保存
## Same thing without a password
%wheel        ALL=(ALL)       NOPASSWD: ALL
```

追加したユーザーでsshで接続できることを確認して完了

# 参考
- [Amazon EC2 キーペアと Linux インスタンス](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/ec2-key-pairs.html)
- [Amazon Linux インスタンスでユーザーアカウントを管理する](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/managing-users.html)
- [SSH アクセスを行える新しいユーザーアカウントを Amazon EC2 Linux インスタンスに追加するにはどうすればよいですか?](https://aws.amazon.com/jp/premiumsupport/knowledge-center/new-user-accounts-linux-instance/)
SQSの可視性タイムアウトよりもLambdaのタイムアウトを長く設定したい

## 概要
CDKにてSQSキューをトリガーに実行するLambdaを初回deployする際、
キュー側の可視性タイムアウト時間よりもLambda実行のタイムアウト時間の方が長いと、

```
Invalid request provided: Queue visibility timeout: X seconds is less than Function timeout: X seconds
```

のエラーがでて、deployに失敗する。

エラー文言に従い可視性タイムアウト時間を長くすれば良いのだが、
Lambda側でキューを取得後にすぐに削除して別で処理のステータス管理をするケースなど、可視性タイムアウトを長くする必要がない場合がある。

また、ドキュメントでも
https://docs.aws.amazon.com/ja_jp/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-visibility-timeout.html
> 通常、可視性タイムアウトは、アプリケーションがキューのメッセージを処理して削除するまでの最大所要時間に設定します。

となっており、Lambdaの実行タイムアウト時間に必ずしも合わせる想定ではなさそう。

## 環境
* `aws-cdk@1.61.1`

## 対処方法
ワークアラウンド的な対応だが、一度
可視性タイムアウト時間 >= Lambda実行のタイムアウト時間
でdeployした上で、
可視性タイムアウト時間 < Lambda実行のタイムアウト時間
に設定変更してdeployするとうまくいく。

可視性タイムアウト時間のデフォルト値は30秒のため、
https://docs.aws.amazon.com/ja_jp/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-visibility-timeout.html
> すべての Amazon SQS キューの可視性タイムアウトはデフォルトで 30 秒に設定されています。

Lambda側のtimeoutを30秒に設定すればひとまずはdeploy可能となる。

CDKコードとしては

```ts
import * as lambda from '@aws-cdk/aws-lambda';
import * as path from 'path';

const fn = new lambda.Function(this, 'MyFunction', {
  runtime: lambda.Runtime.GO_1_X,
  handler: 'main',
  timeout: 30, // Lambdaの実行タイムアウト（秒）を設定
  code: lambda.Code.fromAsset(path.join(__dirname, 'lambda')),
});
```

のような形。

一度deployした後に、例えば15分にしたければ

```ts
import * as lambda from '@aws-cdk/aws-lambda';
import * as path from 'path';

const fn = new lambda.Function(this, 'MyFunction', {
  runtime: lambda.Runtime.GO_1_X,
  handler: 'main',
  timeout: 15 * 60, // Lambdaの実行タイムアウト（秒）を設定
  code: lambda.Code.fromAsset(path.join(__dirname, 'lambda')),
});
```

のようにして再度 `cdk deploy` することで、Lambdaのタイムアウト時間のみ更新できる。
HHKBをMACとWindowsでシームレスにつかいたい！！

# 概要
私のメイン環境はMACなのですが，業務上どうしてもWindowsを使わなければならないときはあります．そのとき，最近愛用しているHHKB btをどちらのOSでも使っていたのですが，bluetoothの繋ぎ変えは仕方がないとして，キー配列が変わってしまう上，キーボード裏のピン（MACモードとWindowsモードを切り替えるスイッチ）も毎回変えないといけないのは不便だと思っていました．そのため，なんとかキー配列の入れ替えで，bluetoothの接続切り替えのみで（見た目上）シームレスにMACとWindowsを使えるように設定をしてみました．

# 以下の条件で設定を行います
- メイン環境はMACなので，キー配列はMAC準拠にします．MACとWindowsで同じHHKBをつかっていても，かな英数入力切り替えの方法は異なります．そのため，かな英数切り替えがWindowsでもMACと同じようにスペースキー横の2つのキー(Windowsでいう変換/無変換キー)で行えるようにすることをめざします．他のキーの入れ替え(Ctrlキーの位置など)は原則行いません．お好みでどうぞ．
- キーボードはHHKB bt(JIS配列)を用います．おそらく，Windows配列のキーボードなら同じ設定で動くと思われます．MAC配列のキーボードをwindowsで用いるのは，さらに追加の設定が必要と思われ，今回は扱っていません．
- サポート外の方法になると思われるので，自己責任でお願いします．
- ~~私は宗教上(?)Windowsは使えない人間です．~~Windowsがメイン環境の方にはおそらくこの記事の設定は合わないと思われます．　~~MAC or Windows論争はここではしません．~~

# HHKB bt側の設定
- キーボード裏のDIPスイッチのうち，SW1(MACモードとWindowsモードの切り替えスイッチ)をOFF(Windowsモード)にします．
- WindowsとMACの両方にペアリングしておきます．

# MAC側の設定
- Karabiner-Elements (https://karabiner-elements.pqrs.org/) をインストールします．
- Karabiner-Elements の設定で以下の画像のようにキーマッピングの設定を行います．grave_accent_and_tildeキーは，HHKBの左下のFnキーの一つ右側のキー(HHKBのロゴが印字されているキー．Windowsでいうwindowsキー)にマッピングされていますが，これはお好みで入れ替えてください．私はよく使うlaunch padに設定しています．必要な方はCaps lockなどに設定すると良いかもしれません．
![スクリーンショット 2020-08-31 11.33.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317046/6f65c6a6-c40c-15a8-ef4e-90953da71ffa.png)


# Windows側の設定
- google日本語入力(https://www.google.co.jp/ime/) をインストールします.
- google日本語入力のキー設定で，以下の画像のように変換/無変換キーに対してキーマッピングの設定を行います．

![screenshot2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317046/8baad381-2c86-7048-70b9-03d4049aa64c.png)

- この設定の場合、全角半角キーもMACのかな英字切り替えと同様の動作をすることになります。お好みで他のキーに入れ替えても良いでしょう．

# まとめ
Windowsをほとんど使わないので，ひらがな/カタカナ/ローマ字切り替えのキーの動作がよくわからず，今回は触らないことにしたのですが，本当は何に使うんですかね…

# 参考サイト
https://exanano.com/howto/eikana-mac-windows/
負荷試験ツールのLocust1.1をDockerに構築

#はじめに
Webシステムの開発では、想定どおりの動きをするかだけでなく、どれくらいの負荷にたえられるのかについても、事前に把握しておく必要があるのではないかと思います。

今回は、負荷試験ツールであるLocustをDockerに構築して、まず動かしてみるところを行いたいと思います。

#Locustの特徴
+ シナリオをPythonスクリプトで記述するため、柔軟なシナリオを作成可能
+ 試験シナリオがスクリプトであるため、ソースコード管理が可能
+ 必要なサーバリソースが少ないため、少ない攻撃サーバで負荷をかけやすい
+ 結果表示がシンプル

#環境
+ Dockerのversionは19.03.12です。
+ Locustのversionは1.1です。

クライアントのPCはWindows10Proになります。

#公式ドキュメント等
公式ドキュメント等は以下となります。

[Locust公式ドキュメント](https://docs.locust.io/en/stable/index.html)
[Locust github](https://github.com/locustio/locust)

#構築手順

１．DockerDesktopをインストール
以下からDockerDeskTopをインストールします。
https://www.docker.com/products/docker-desktop

２．docker-compose.ymlファイルの入手
任意の場所にフォルダを作成し、以下から、docker-compose.ymlファイルをダウンロードします。
https://github.com/locustio/locust/tree/master/examples/docker-compose

masterのコマンドの-Hの部分はテストを行うページに変更します。

```yml
version: "3"
services:
  web:
    build:
      context: ./apache-php
    ports: 
      - 80:80
    privileged: true
    links:
      - db
    volumes:
      - "./lara-d/:/var/www/html"
      - "./apache-php/apache.conf:/etc/httpd/conf/httpd.conf"
    container_name: "apache-php"
version: '3'

services:
  master:
    image: locustio/locust
    ports:
     - "8089:8089"
    volumes:
      - ./:/mnt/locust
    command: -f /mnt/locust/locustfile.py --master -H http://master:8089
  
  worker:
    image: locustio/locust
    volumes:
      - ./:/mnt/locust
    command: -f /mnt/locust/locustfile.py --worker --master-host master
```

３．locustfile.pyの作成
locustfile.pyはシナリオを記述するファイルで、docker-compose.ymlと同じ場所に配置します。

今回は、簡単なHTTPリクエストを行うためのスクリプトを作成します。

```python
from locust import HttpUser, task, between

class MyUser(HttpUser):
    wait_time = between(5, 10)  #userを立ち上げるタイミングを指定

    @task(1)
    def index(self):
        
        url = '/api/test.php' #負荷をかける箇所を指定
        params = {'id':'0001'} #必要に応じてパラメータを指定

        headers = {'x-api-key':'***********'} #必要に応じてheader項目を付与

        self.client.get(url=url,params=params,headers=headers) #GETリクエストを送信

```

#実行方法

１．Dockerの起動

コマンドプロンプトを開き、docker-compose.ymlを配置したフォルダに移動し、以下のコマンドを実行します。

```cmd
docker-compose up -d
```

Workerを増やして、負荷を並列に行いたい場合は、起動時に指定します。
ymlファイルに書いても大丈夫だと思います。

```cmd
docker-compose up -d --scale worker=3
```

２．パラメータ設定
Dockerを起動したら、ブラウザでLocustを表示する。
http://localhost:8089/

![コメント 2020-08-31 115336.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/603100/a24925fb-7f82-3859-f2a0-d6dd3bed902a.png)

ユーザ数と、ユーザが立ち上がる速度を入力し、Startを押すと実行されます。（ホストはymlに設定したものが表示されます）
Firebase Crashlyticsに不足しているdSYMをアップロードする

Firebase Crashlyticsに不足しているdSYMをローカルマシンからアップロードする方法です。

基本的に[こちら](https://firebase.google.com/docs/crashlytics/get-deobfuscated-reports?platform=ios&authuser=0)に書いてある手順を参考にしています。

## 不足しているdSYMを探す

```.sh
mdfind -name .dSYM | while read -r line; do dwarfdump -u "$line"; done | grep <dSYMのUUID>
```

不足しているdSYMのUUIDはFirebase CrashlyticsのdSYMの欄から探すことができます

![スクリーンショット 2020-08-31 11.30.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117503/d37864f4-9140-b0b5-a756-358e6129538c.png)

## dSYMのアップロード

Firebase Crashlyticsに内包されている`upload-symbols` というスクリプトを使います。

Carthageを使ってFirebaseCrashlyticsを入れている場合など、upload-symbolsスクリプトがない場合には以下からDLも可能です。
https://github.com/firebase/firebase-ios-sdk/blob/master/Carthage.md

```.sh
/path/to/pods/directory/FirebaseCrashlytics/upload-symbols -gsp /path/to/GoogleService-Info.plist -p ios /path/to/dSYMs
```

`/path/to/dSYMs` については `.dSYM` ファイルを指定します。

`Successfully uploaded Crashlytics symbols` と表示されて不足しているdSYMから該当のUUIDが消えていれば完了です。
Redashでグラフを作成してみたが正しく集計されていない（クエリを修正してみる）

今回は、前回作成したクエリ結果をグラフ表示してみたいと思います。

① 前回作成したクエリを表示し、「New Visualization」ボタンを押下します。
![クエリ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691277/d176e82e-bd0b-5afd-d84f-cbd4084d6381.png)
② Visualization  Editorが表示されます。
![Visualization Editor表示](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691277/807815d5-d2d1-a937-0317-29ca2c4ce2a6.png)
③ 地域毎の売上および利益を表示するグラフを作成したいと思います。
　 X軸に「地域」、Y軸に「売上」と「利益」を設定します。（チャートタイプは棒グラフのまま）
![プロパティ設定1](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691277/b7436797-5bf2-0f01-1a21-e1f35a22c2c0.png)
④ 地域別の売上と利益が表す棒グラフが作成されました。
![グラフ表示1](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691277/d0ae9282-9634-443c-a84d-969852be234b.png)
⑤ グラフが表示されましたが、どうも表示されている値やグラフが正しく表示されていないようです。
![グラフ表示不良](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691277/c786141b-af4f-8d20-4ffd-b60d34bc0163.png)
⑥ 少し調べてみると、**クエリが同じX軸の値（ここではArea）を持つ複数のレコードを返す場合は、うまくグラフが表示されないようです。**
　　[https://redash.io/help/user-guide/visualizations/chart-visualizations](https://redash.io/help/user-guide/visualizations/chart-visualizations)
　 そこで、エリア毎の売上と利益を集計した値を取得するようにクエリを変更します。
⑦ クエリ画面を表示し、SQLを修正します。
![クエリ修正](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691277/022b3fdb-942a-76c8-5299-61755fa85791.png)
⑧ SQLを修正後、クエリを実行します。
![クエリ実行](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691277/d6ef732f-0ba2-d2c0-5e56-b93d6f7e7b2a.png)
⑨ 再度、「New  Visualization」ボタンを押下します。
⑩ X軸に「地域」、Y軸に「売上」と「利益」を設定し、グラフを表示します。（チャートタイプは棒グラフのまま）
![グラフ表示2](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691277/a44738d3-d239-d4f2-68f1-93d05edd1ea5.png)
どうやら正しく表示できたようです。

⑪ 作成したグラフを保存して終了です。

株式会社メソドロジック
赤尾　一優　@Kaz_akao
Video Indexer を使って文字起こし

streampackのminsuです。

今回はMSのAzure Video Indexerの音声分析情報を使う機会があったので情報を共有します。
今回は日本語で話している動画から日本語を文字起こししました。

https://azure.microsoft.com/ja-jp/services/media-services/video-indexer/

## 動画のアップロード
まずはVideoIndexerの利用はにログインします。
googleアカウントでログインしてみましたが、無料アカウントでも最大40時間分まで試せるようです。

ログイン後はアップロード画面へ移動し、動画をブラウザ常にドラッグするだけでアップロード可能です。
![スクリーンショット 2020-08-31 10.39.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399734/c4885837-a622-bf0c-2b10-c4bef24655e2.png)
今回は日本語の動画なのでビデオのソース言語は日本語に変更します。
![スクリーンショット 2020-08-31 10.39.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399734/727df860-1dd1-fba1-5917-c9735937a035.png)

動画アップロード後に分析が開始されますので処理完了を待ちます。

## 音声分析情報

動画を選択し、タイムラインタグで文字起こしされた情報を確認します。
![スクリーンショット 2020-08-31 11.00.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399734/5c3f5317-b4a0-66f4-f0cf-e7c24571a47b.png)

ダウンロードからvttファイルなどでDLすることも可能です。
ニュース番組でキャスターが原稿を読み上げている動画など、一人が聞き取りやすく話している場合では高い制度で文字起こしされていました。

```
台風9号は、このあとさらに発達しながら北上し、月曜日から火曜日にかけて非常にしい勢力で沖縄に接近しそうです。
そのあとは東シナ海を北上し、暴風域を伴ったまま九州など西日本にも接近する恐れがあります。
```
↓

```
台風9号は、このあとさらに発達しながら北上し、月曜日から火曜日にかけて非常にしい勢力で沖縄に接近しそうです。
そのあとは東シナ海を北上し、暴風域を伴ったまま9州など西日本にも接近する恐れがあります。
```

ダウンロードタグの右隣の日本語タグから字幕情報を他言語に翻訳可能です。
![スクリーンショット 2020-08-31 11.00.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399734/99fa96bf-155b-99dc-0b50-4b3479deab7b.png)

英語

```
Typhoon No. 9 is likely to go north as it develops further, approaching Okinawa with very heavy forces from Monday to Tuesday.
After that, it is possible to go north over the East China Sea and approach western Japan such as nine states while accompanied by a storm zone.
```
韓国語

```
태풍 9호는 월요일부터 화요일까지 매우 무거운 힘으로 오키나와에 접근하면서 북쪽으로 갈 가능성이 높습니다.
그 후, 동중국해를 통해 북쪽으로 가서 폭풍 지대와 함께 9개 주와 같은 일본 서부에 접근할 수 있습니다.
```

英語、韓国語にしてみたところ、日本語で`9州`と誤認識されている箇所は他言語に翻訳した場合も`nine states`,`9개`のように同じ箇所が誤っていました。

誤ってる箇所は編集タグで修正できます。
![スクリーンショット 2020-08-31 11.01.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399734/0fd83f55-f3fb-7b44-0565-b437680e3ef0.png)

上記のようなニュースを読み上げるような場合では高い制度で文字起こしされた一方で、
人物の発言中に効果音の混じっている場合や、複数の人数が同時に会話しているような状況では精度は高くはありませんでした。
下記のように実際に人間の耳で聞いても認識し辛いような箇所は精度も低めでした。

```
A: なんぼのもんじゃい
B: この話知ってるってこと?
A: だってこれ前にも聞いたよ、結構有名じゃない
C: あーそうじゃん
D: 僕これにします
```
↓

```
ガンモ飲んでじゃないわよ。知ってるってだってこれ前に聞いたよ、結構有名なんですね。じゃあこれでします。
```

### カスタム言語モデル
Video Indexerはモデルの一部をカスタマイズすることが可能で、
音声認識の部分でも特定の単語を学習させたり言語認識の精度を上げる目的でカスタム言語モデルを使用することができます。

https://docs.microsoft.com/ja-jp/azure/media-services/video-indexer/customize-content-models-overview
https://docs.microsoft.com/ja-jp/azure/media-services/video-indexer/customize-language-model-with-website

使用してみたところベストプラクティスに沿ったトレーニング用データを用意する必要があります。
私の方で用意したデータが適切であったかは不明な点もあるので精度については置いておきますが、
カスタム言語モデルを利用して日本語を文字起こししたところ、
日本語の場合は読点、句読点がなぜか出力されなくなったので少し使い勝手はよく無い印象を受けました。

##感想
音声認識に関しては、
スピーチ形式であったり自分用の音声メモを文字に起こす場合などは高い精度が発揮される一方で、
複数人数の討論形式や雑談などの場合はまだ難しいようです。

ですがVideoIndexerが複数人数が登場する動画に不向きという訳ではなく、
動画内で誰がどのシーンに出演しているかのユーザー分析情報も得ることができるので、ケースバイケースで必要な分析情報に応じて使えそうです。
【Mac・VSCode】よく使うショートカット (カーソル移動, 矩形選択, 置換)

#はじめに

VSCodeには色々と便利なショートカットがあります。
もっと早く知っておきたかったなぁと思うショートカットをいくつか書いていきたいと思います。

今回の記事の内容をおおまかに分けると、

- カーソル移動・範囲選択系
- 矩形選択
- 置換

という感じです順に解説します。

## カーソル移動・範囲選択系

####単語単位でのカーソル移動
`option` + `← or →`
![単語の移動.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559794/dfdc8b72-5835-d121-e209-3871ecc9e2d7.gif)

####行頭、行末のカーソル移動
`command` + `← or →`
![行頭、行末の移動.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559794/f2e97a6d-d8b7-206b-6914-e5568ed41bf1.gif)

#### 1文字ずつ範囲選択 

`shift` + `← or →`

![範囲選択.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559794/4c48fc3d-ff3a-6504-6379-ff126ecb71bf.gif)


####単語単位での範囲選択
`option` + `shift` + `← or →`
![単語単位で範囲選択.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559794/cb376f6e-9b3e-72a2-2bc4-5e5548833e06.gif)


####現在のカーソル位置か行頭 or 行末までの範囲選択
`command` + `shift` + `← or →`
![行単位で範囲選択.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559794/2726ddc6-1f67-6ddf-a6f8-2e084f2916c1.gif)


####上下の行の入れ替え
`option` + `↑ or ↓`
![上下の行の入れ替え.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559794/f5030caf-539c-5c91-03f8-f03d4d2c6c33.gif)



#####ファイルの先頭と最後の移動
`command` + `↑ or ↓`
![ファイルの先頭と最後の移動.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559794/ac283eef-f46e-b5ce-040b-8f8a66b976b7.gif)



## 矩形選択, マルチカーソル

次は矩形選択, マルチカーソルです。
複数のカーソルを同時に扱うことができ、カーソル移動で紹介したコマンドと組み合わせることで絶大な威力を発揮します!

#### 任意の箇所をマルチカーソルに
`option` + クリック
![好きな場所を選びたい.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559794/40e7de16-248f-4ce6-d7c4-fe11028cf32f.gif)



#### ファイル内検索を利用したマルチカーソル
ファイル内検索( `command` + `F` ) → `option` +  `Enter`
検索結果全体にマルチカーソルが適用されます。
![ファイル内検索をした単語全体を選択.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559794/e09b12cf-1788-28e1-93f6-0d2c845e2684.gif)


#### 矩形
`command` + `option` + `↑ or ↓`
長方形型で選択したい時などに便利です。
![矩形.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559794/9b9d9f90-7868-198e-39ab-c7cc0b0b9d8e.gif)



## 正規表現による置換

#### 残しておきたい部分を変数に入れて置換
(※こちらは少し正規表現の勉強も必要ですが使えるとすごく便利です!)
変数にしたい部分を( )で囲むと、囲んだ順に\$1, \$2, \$3...に代入される
![置換.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559794/84ec6dfc-f121-d853-7358-3b7f7867cadb.gif)
Jupyter Notebookのインストール方法

自分のメモとしてインストール方法を書き残します。
JupyterNotebookはインタラクティブなユーザインタフェースをブラウザ上で提供するアプリケーション。pythonのpipと呼ばれるパッケージ管理システムで簡単にインストールすることが可能になる。
#MacOS
###インストール方法
ターミナルを開いて以下のコマンドを実行する
```pip3 install jupyter```
###起動方法
```jupyter notebook```

#Windows
コマンドプロンプトを開いて以下のコマンドを実行する
###インストール方法
コマンドプロンプトで以下のコマンドを実行する
```pip3 install jupyter```
###起動方法
```jupyter notebook```

#jupyter notebookの基本説明
開いたブラウザページからノートブックを新規に作成する。
"New"->"Python3"をクリックする
pythonのインストール方法

自分用のメモとしてpythonのインストール方法を書き残します。
#MacOS
###パッケージマネジャ(Homebrew)をインストール
```/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"```
###pythonをインストール
```brew install python```

#Windows
###インストーラーをダウンロード
[公式ページ](https://www.python.org/ "公式ページ")にアクセスしてDownloads->All releasesと進む。使用コンピュータのビット版に応じて、インストーラーをダウンロードする。
###ダウンロード先を指定する。
Custumize install locationを"C:\Python\Python36"と指定する。
SQLAlchemyでmysqlのjson_containsを使うのに文字列で検索する方法

`json_contains`使って文字列で検索しようとしたら少しハマった。

## 成功例

`""`で囲む必要がある。実際mysqlで直接selectするときも`json_contains(fuga, '"piyo"')`とする必要がある。

```success.py
from sqlalchemy import func

search_str = 'piyo'
db.session.query(Hoge).filter(func.json_contains(Hoge.fuga, f'"{search_str}"'))
```

## 失敗コード例

```fail.py
from sqlalchemy import func

search_str = 'piyo'
db.session.query(Hoge).filter(func.json_contains(Hoge.fuga, search_str))
```

## エラーメッセージ

```
sqlalchemy.exc.OperationalError: (pymysql.err.OperationalError) (3141, 'Invalid JSON text in argument 2 to function json_contains: "Invalid value." at position 0.')
```
フリーターでも分かる、jQuery基礎

どうもこんにちは、




今日はjQueryについて、

僕が学んだ基礎知識を共有していきたいと思います。







まずはじめに

簡単な公式を知らないと、

始まらないので公式から覚えましょう。






```
＄（’HTML要素').メソッド（引数）;

```








です。







短っ！

と思った方もいると思いますが、

こっから色々と付け足していくのです。

もちろんコレで終わりなわけはありません。










簡単解説




HTML要素




というのは例えば、、







index.html
```
<h1 >こんにちは<h1>
```






のところで言うh1です




あと、最後の　　;（セミコロン）　　　は忘れずにつけましょう。




コレが基本の構文ですね。










ではこの公式を使って、jQueryで何ができるのかを話していきます。







アニメーションを付けられる




はじめ見た時コレはすごいと思いました！




ほんの二行jQueryの記述を加えるだけでこんな変化を生み出せるのか、、

と感動して、子供のようにしばらく画面を見つめていました。







書き方は、、



```
＄（’HTML要素').fadeOut（アニメーションが起こるスピード指定）;
```



です。




こうすることで、指定した場所のhtml要素が消えます！



```
＄（’HTML要素').fadeIn（アニメーションが起こるスピード指定）;
```



にすると現れます




簡単解説




スピード指定する際に、1000で一秒だということを知っておいてください







fadeOut 　　のところは　 　slideUp　　でも大丈夫です。













指定先の色を勝手に変えられるだと、、、




コレも非常に簡単に作れます




こちらが公式です。



```
＄（’HTML要素').css（'プロパティ(colorとか)' ,  '値（blueとか)'）;

```





コレで指定したHTML要素の色が変えられます。




楽しいですね。










clickイベントを使って、
「あ〜、コレよく見るわ〜。」
という動きを作れる







簡単なアニメーションの次は

少し記述量を上げてクリックイベントを使った、

「あー、コレよく見るやつだわ。」

というものを作ってみましょう







公式はこんな感じです。



```
＄（’HTML要素').イベント名（function(){
イベント内容
}）;

```





今回のイベント名には「click」を使っていきたいと思います。



```
＄（’HTML要素１').click（function(){
＄（’HTML要素２').slideUp
}）;
```





こうすることで、

HTML要素１を　ｃｌｉｃｋ　すると

HTML要素２が消えます。




素晴らしいですね。。

jQueryすげー、、、










以上で簡単な説明は終わりです




またお会いしましょう。
GPT-3とは？


#OpenAIのNLP

GPT-3(Generative Pre-Training3)はOpenAI(人工知能研究所)が作った言語AIの名前です。

#何がすごい？
人間作家の初期メッセージを基にテキストを自動的に完成できます。例えば、多言語通訳や文章を生成して短文の作成、またはニュースなどを書ける自然語処理モデルです。3という数字からわかるように、その前にもGPT-1、GPT-2が存在しました。GPT-3も他のAIのようにデータからパターンを探して作成します。パラメータ数約1750億個、学習にも約3000億個のテキストデータセットで学習を進めました。(GPT-2は、学習パラメータ数が約15億個、学習データセットには約800万個のテキストデータを利用して学習させました。)

このような学習を基に、いくつかの単語や文章を入力すると、次に出てくる適切な文章が何かを予測して提示します。論文によるとGPT-3が書いた記事を見て人達の半分だけがGPT-3は人工知能が書いたものだという事実を認知していないほどでした。
GPT-3の最大の特徴はフューシャットラーニング(few-shot learning)といいます。一般的にマシンラーニングモデルは、あることを遂行するためにそれに該当するデータを学習させなければなりませんでした。しかし、GPT-3はいくつかのサンプル例題だけを示し、次の結果が何なのかを予測する方式のピューシャットラーニング（few-shot learning）で、新しい言語タスクのためにあえてデータを作らなくてもかなり高い性能を見せることができます。

#限界点
GPT-3が非常に汎用的に優れた言語能力を見せたので、APIを初めて使った人は人間レベルのAIが目の前にあるのではないかと言ったりもしました。 しかしGPT-3を作ったOpenAIの代表サム·アルトマン(Sam Altman)氏の考えは違います。

>
「GPT-3は過大評価されています。 印象的な性能を見せるのは確かな事実ですが(褒めてくださってありがとうございます)、相変わらず深刻な弱点があり、時にはとても愚かな失敗をすることもあります。 AIは世界を変えるのですが、GPT-3は非常に初期の型であるだけです。 私たちはまだ調べなければならないことがたくさんあります」。
>

彼が言う限界点の中でいくつかだけ選んでみました。

📌　物理に弱い
GPT-3が特に弱い領域は現実の物理的な常識を扱う言語の問題でした。 たとえば「チーズを冷蔵庫に入れたら溶けるかな？」といった問題に、人なら当然溶けないと答えますが、GPT-3は溶けると答えます。

📌　膨大なモデル
上で述べた1,750億個のパラメータを誇っているだけに、モデルが大きいと学習させるのに時間と費用がかかります。 GPT-3を学習させるのにかかる費用を正確に試算することはできませんが、約50億ウォンほどかかると試算されます。 これは、単にGPT-3の最終モデルを学習させるのにかかる費用を計算したもので、その過程において付加的にかかる費用を正確に計算することも困難です。 どうしても簡単に試みることは難しいです。
#事例
このように作られた人工知能モデルをAPIの形で提供し、いくつかの事前体験申請者を募集しました。その結果物を
SNSで共有された共有した事例は以下となります。

アプリを作った事例  https://twitter.com/sharifshameem/status/1284095222939451393

検索エンジンを作った事例 https://twitter.com/paraschopra/status/1284801028676653060

ギター演奏楽譜を作った事例 https://twitter.com/AmandaAskell/status/1283900372281511937

事業アイデアを作った事例  https://twitter.com/joshu/status/1283466801028857856

👉 より多くの事例は以下のリンクからご確認いただけます。
[GPT Crush](https://gptcrush.com/)


📚 参考：[OpenAI](https://openai.com/blog/openai-api/)
📚 参考：[Awesome GPT-3](https://github.com/elyase/awesome-gpt3)
📚 参考：[MIT Technology Review about GPT-3](https://www.technologyreview.com/2020/08/22/1007539/gpt3-openai-language-generator-artificial-intelligence-ai-opinion/)
データ構造とアルゴリズム Vol.2


#Vol.2: Linked List
この版ではLinked Listの必要性とその使い方について学びます。

#Linked Listの必要性
👌 一般的には、配列を使用してデータを順次保存し、一覧表示できます。
👌 排熱を使用する場合、メモリ容量が不要な場合があるからです。


#既存の配列ベースリスト
データを順番に保存し、処理するときは配列ベースのリストを簡単に利用できます。

**例）**

```C
#include <stdio.h>
#define INF 10000

int arr[INF];
int count = 0;

void addBack(int data) {
  arr[count] = data;
  count ++;
}

void addFirst(int data) {
  for (int i = count; i >= 1; i--) {
    arr[i] = arr[i - 1];
  }
  arr[0] = data;
  count++;
}
```

```C
void show() {
  for (int i =0; i < count; i++) {
  printf("%d", arr[i]);
  }
}

int main(void) {
  addBack(5);
  addBack(8);
  addBack(7);   
  addFirst(3);
  addFirst(4);
  show();
  system("pause");
  return 0; 
}
```
``result-> 4 3 5 8 7``

🤔 では、特定の位置の元素を削除する関数はどうやって作成しますか？
``特定の位置の元素を削除するremoveAt()関数は以下の通りです。``

```C
void removeAt(int index) {
  for (int i = index; i < count -1; i++) {
    arr[i] = arr[i + 1];
  }
  count--;
}
```

✍ 　**配列ベースリストの特徴**
- 配列しているので、特定の場所の元素にすぐにアクセスできるというメリットがあります。
- データが入るスペースをあらかじめメモリに割り当てておかなければならないという短所があります。
- 任意の位置への挿入や削除が非効率です。 ➡ 特定の位置に挿入する時、または削除する時は既存の値を一つずつ全部移動させなければならない。

#ポインタベースのLinked List
-　一般的にLinked Listは構造体とポインターを一緒に使用して実現します。
-　Linked Listは、リストの中間地点にノードを追加したり削除したりできなければなりません。
-　必要なたびにメモリ容量の割り当てを受けます。

![LinkedList.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619479/fce56397-6a47-8839-7b52-9748a497aeb6.png)

📌 Singly Linked List
単一接続リストは以下のような形で表すことができます。
ポインタを利用して単方向的に次のノードを指します。
一般的に、接続リストの開始ノードをヘッド(Head)といい、別に管理します。
次のノードがない最後のノードの次の位置の値には、NULLを入れます。

**例) Linked Listに特定の元素を挿入する方法**

```C
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>

//一つの構造体にデータとその次ノードを指すnext変数を入れる。
typedef struct Node{
    int data;
    struct Node *next;
} Node;

Node *head; 
//Linkedは常にヘッドノードから出発
//ノードは常にポインタ変数で動的割り当てを利用して変数を作ることができるようにするのが一般的

void addFront(Node *root, int data) {
    Node *node = (Node*)malloc(sizeof(Node));
    node->data = data;
    node->next = root->next;
    root->next = node;
}

void removeFront(Node *root) {
    Node *front = root->next;
    root->next = front->next;
    free(front);
}

void freeAll(Node *root) {
    Node *cur = head->next;
    while (cur != NULL) {
        Node *next = cur->next;
        free(cur);
        cur = next;
    }
}

void showAll(Node *root){
    Node *cur = head->next;
    while (cur != NULL) {
        printf("%d" , cur->data);
        cur= cur->next;
    }
}

int main(void) {
    head = (Node*) malloc(sizeof(Node));
    head->next = NULL; //常にLinked Listの最後はNullでなければならない。
    addFront(head, 2);
    addFront(head ,1);
    addFront(head, 7);
    addFront(head, 9);
    addFront(head, 8);
    removeFront(head);
    showAll(head);
    freeAll(head);

    return 0;
}
```
🤔 結果は？
``result-> 9 7 1 2``

#Linked List実装における注意点
❗ 挿入および削除機能での例外事項を処理する必要があります。
❗ 削除する元素がないのに、削除する場合、頭(Head)ノード自体を間違えて入れる場合などをチェックする必要があります。

✍ 　**Linked Listの特徴**
- 挿入と削除が配列に比べて簡単であるという長所があります。
- 配列と違って特定インデックスに直ちにアクセスできず、元素を順番に検索しなければならないという短所があります。
- 追加的なポインタ変数が使用されるため、メモリスペースが無駄になります。

#まとめ
👌 Linked Listはデータを線形に保存して処理する一つの方法です。
👌 従来の配列よりも挿入と削除が多い場合に有効です。
👌 ただ、特定のインデックスにすぐに参照することが多い場合は配列を利用するのが効率的です。

📚参考講義：コンピューター工学専攻必須オールインワンパッケージOnline
👆 上記の講義はCとC++を言語を前提に説明しています。
Nuxt.jsでsassにAutoprefixer（Pollyfil for IE）を導入したときに躓いたメモ

Nuxt.jsにAutoprefixerを下記方法にて導入しました。

https://ja.nuxtjs.org/faq/postcss-plugins/#%E6%8E%A8%E5%A5%A8%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95

```nuxt.config.js
export default {
  build: {
    postcss: {
      preset: {
        autoprefixer: {
          grid: true,
        }
      }
    }
  }
}
```
ここまではよかったのですが、[Autoprefixerのドキュメント](https://github.com/postcss/autoprefixer#does-autoprefixer-polyfill-grid-layout-for-ie)にgrid-layoutのIEに対応させる＆将来的に `true` が廃止されるとのことで 'autoplaceに変更したところ下記ワーニングがでてしまいました。


```
Module Warning (from ./node_modules/postcss-loader/src/index.js):
Warning

(3:3) Autoplacement does not work without grid-template-columns property
```

検索してみると同じよなことが結構起きているぽいけど、下記はすでに修正されている様子。これは関係ないのか。
https://github.com/postcss/autoprefixer/issues/1166#issuecomment-444476182


Nuxt.jsで呼ばれているバージョンが古いのかも見てみましたが、問題なさそうです。
```
"@types/autoprefixer": "^9.7.2",
```

色々試した結果、webpackの大本での設定はあきらめ、
sassのgridで `grid-template-columns` を利用するところで、 `/* autoprefixer grid: autoplace */` のコメントを利用するしかなさそうです。

```vuejs
<style lang="scss" scoped>
.grid {
  /* autoprefixer grid: autoplace */
  display: grid;  
  grid-template-rows: repeat(3, 250px);  
  grid-template-columns: repeat(3, 1fr);  
  gap: 10px;
}
</style>
```
VBAで処理開始前の確認メッセージを出す

##メッセージボックスで処理を開始していいか確認する
ボタンを押したらすぐ処理が始まるのではなく
確認メッセージを表示して、本当に開始するかやっぱり辞めるか選択させる。


```

sub 処理開始ボタン_Click()
  If MsgBox("処理開始しますか？", vbYesNo + vbQuestion, "確認") = vbYes Then

    Call 実際の処理  '「はい」を選んだ場合は処理開始
    MsgBox "処理が終了しました"  '終了時メッセージ

  Else
    MsgBox "処理をキャンセルします"  '「いいえ」を選んだ場合はキャンセルメッセージ
  End If
End Sub
```
__確認メッセージ__
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700414/b2caba76-281e-c743-8ff0-01709bfeaa81.png)

__Noを押したときのメッセージ__
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700414/b68fa72b-e484-f539-95b4-b9ffaf723cad.png)


##ワタシ流こだわり
実際の処理は別に書いてCallで呼び出す
ARオブジェクトを常にカメラの方向を向いた状態で配置する

##できるもの
配置する場所に依存することなく、オブジェクトは常に立方体の側面が見えていない状態で生成されます。
Regardless of where it is placed, the object is always created with the sides of the cube not visible.
<img width="200" alt="IMG_8FA76380F0EA-1.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549093/f7045783-fd6f-34fd-beac-25764908cb3b.jpeg"> <img width="200" alt="IMG_F9BBA852BDCA-1.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549093/8c8cde7e-7467-5d3a-fd9e-187cb30c5812.jpeg">


##前提となる知識
- ワールド座標は起動時に生成される
- SCNNode.eulerAngles = SCNVector()で回転を行うことができる

##実装方法

SCNNodeを作成する関数の中で、nodeに対して回転を行います。

```Swift
if let camera = self.sceneView.pointOfView {
            boxNode.eulerAngles = SCNVector3(0,camera.eulerAngles.y,0)
        }
```


##参考にしたサイト
[[iOS11][ARKit] オブジェクトの位置と回転「常にこっちを向いている怪獣」](https://dev.classmethod.jp/articles/ios11-arkit-pointofview/)