OmniAICreator/Qiita-1.07M huggingface dataset:
Gatsby.js+TypeScript+VSCodeで絶対パスimportを使う

## 環境

- gatsby: 3.10.2
- gatsby-plugin-root-import: 2.0.7
- VSCode: 1.59.1

## やりたいこと

Gatsby.js+TypeScriptを使ったプロジェクトで、相対パスではなく絶対パスでimportしたい。

例えば、下記のようなディレクトリ構造のとき、

```
.
├── README.md
├── gatsby-config.js
├── node_modules
├── package-lock.json
├── package.json
├── public
├── src
│   ├── components
│   │   └── button.tsx  // これをimportしたい
│   └── pages
│       ├── index.tsx
│       └── hoge
│           └── fuga
│               └── page.tsx  // ここから
└── tsconfig.json
```

↓のように書いているのを、

```tsx:page.tsx
import Hoge from '../../../components/button'
```

↓のように書けるようにしたい、

```tsx:page.tsx
import Hoge from 'components/button'
```

というものです。

## gatsby-plugin-root-importを使う

絶対パスでimportできるように、モジュールとエイリアスを解決するようWebpackを設定してくれる便利なプラグイン[gatsby-plugin-root-import](https://www.gatsbyjs.com/plugins/gatsby-plugin-root-import/)を使います。

導入は簡単2ステップ。

### 1. プラグインをインストール

```sh
npm install -D gatsby-plugin-root-import
```

### 2. gatsby-configに追記

```js:gatsby-config.js
module.exports = {
  ...
  plugins: [
    ...
    'gatsby-plugin-root-import'
  ]
}
```

これだけで、 `src` 配下のファイルに対して絶対パスでのimportが可能となります。ちなみに、対象とするディレクトリを変更したい場合などは、プラグインのオプションで指定することも可能です。

JSの場合はこれで完了ですが、TypeScriptを使っている場合にはVSCode上でimportの箇所にエラーが出てしまうため、追加で設定を行います。

## VSCodeのエラーを消す

下記のように、 `tsconfig.json` に `baseUrl` を指定してやればOKです。

```json:tsconfig.json
{
  "compilerOptions": {
    ...
    "baseUrl": "./src/"
  }
}
```

また、この設定により、自動import時にも絶対パスで記述されるようになります。快適！

## おわりに

掲題の件で調べると `eslint-import-resolver-typescript` を使う方法などが見つかり、色々と試しましたが自分の環境ではなかなかうまくいかず、最終的にシンプルな方法でうまくいったのでメモとして残しておきます。
どんな画面幅でも同じ比率で拡大・縮小するサイトを作る【scss】

## はじめに
どんな画面幅でも同じ比率で拡大・縮小するサイトをHTMLとSCSSを使って作ります:writing_hand:
もちろん画像で作るパワープレイではないです:ok_hand:

### まずは完成品イメージ
![cap.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1322014/0701601b-c9f2-c2bc-d9fb-384f38d172d5.gif)

## 作り方
上記のようなサイトを作るには`vw`を単位として使うのですが
画面幅に対しての値なので`font-size: 3.73333vw;`というような指定が必要となり、可読性が悪く扱いにくいです。

scssの機能である`function`と`mixin`を使うことで
慣れ親しんだ`px`の値で書けるようにする関数を作り、可読性を良くして扱いやすくしましょう:thumbsup:

### `function`と`mixin`
```scss
// 基準にする画面幅（デザインデータの幅）
$defaultWidth : 375;

// px → vw
@function vw($size, $width: $defaultWidth) {
  @return (100 / $width) * $size * 1vw;
}

// fontsize px → vw
@mixin fontSize($size: 10, $width: $defaultWidth) {
  font-size: $size * 1px; // vw非対応用
  font-size: vw($size, $width);
}
```

「`$defaultWidth`をデザインデータの幅と合わせる」のがポイント:point_up:

### 実際に使ってみる
```scss
.catch {
  margin-bottom: vw(10); // margin-bottom: 10px
  padding-bottom: vw(5); // padding-bottom: 5px
  border-bottom: vw(2) dashed #ccc; // border-width: 2px
  @include fontSize(18); // font-size: 18px
}
```

余白や線の太さは`function`を呼び出し、文字サイズは`mixin`を呼び出して記述します。
カッコ内の値はデザインデータの`px`の値を入れればOK。勝手に`vw`の値に計算して出力されます。
ちなみに`%`も画面幅に依存するので`width: 40%;`といった指定も問題ありません！

## どんなタイミングで使う？
主にSPサイトや、装飾の多いLPなどで使うのが良いかと思います:ok_woman_tone1:
特に装飾の多いLPでは絶対配置を多用するので、画面幅による微妙なズレを調整する手間が省けて便利です:sunflower:

PCサイトは対応すべき画面幅が広いため、あまり向いてないと思っています。
同じ比率で拡大・縮小させてしまうと、あまりに表示コンテンツが小さい・大きいという現象が発生してしまい
メディアクエリで細かく値を調整する必要が出てきて冗長なコードになってしまう印象です。

## おわりに
LPを作りまくっていた時代にお世話になったので記事にしたかった！！
線の太さをついつい`px`で書いてしまって修正したことが何度もあります。手癖かな:joy:
plantFEMとImageJで葉っぱの3D有限要素メッシュを作る．

# 今道端で見かけた植物の葉っぱでシミュレーションやりたいそこのあなたへ！

### [plantFEM](https://github.com/kazulagi/plantFEM)では，こんな葉っぱのメッシュをすぐに作れます．
![7178ad19-5dbf-4836-a5e7-a729a0497630--concord-grape-leaves.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/489195/4f3611de-a0e2-fdec-aabd-076e82ad3ee1.jpeg)

さらに増やせます！
![grape.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/489195/0778dc06-476e-e65b-03f4-ff19e67be6b2.png)


### やりかた

環境：Ubuntu 20.04

### (1) [ImageJ](https://imagej.nih.gov/ij/)をインストール

### (2) 画像をImageJで開き，"Multi-Point"アイコンをクリックした後で，輪郭に点を打つ（どこからでもok)
![Screenshot from 2021-08-25 13-56-31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/489195/3113481c-079d-68e6-5f8e-9b1d2e42b540.png)

### (3) File > Save As > XY-Coordinates で```leafshape.txt```などとして保存

##　以下，plantFEMの作業になります．

### (4) 以下のコマンドでplantFEMをインストール

```copy

git clone https://github.com/kazulagi/plantFEM
cd plantFEM
python3 install.py

```

### (5) 以下のコードを```server.f90```に書き，```plantfem build```でビルド

```Fortran
use LeafClass

implicit none

type(Leaf_) :: leaf

call leaf%create(filename="path/to/leafshape.txt")
call leaf%vtk("leaf")

end
```
(※path/to/leafshape.txtの部分は先ほどファイルを保存した先のパスを指定してください．)


### (6) ```./server.out```を実行


### (7) 仕上がった```vtk```ファイルをparaviewなどで閲覧

![mesh.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/489195/d37462ee-3177-0c00-824d-c6e787d70c75.png)

### (8) 分割数を上げたい場合は，以下のように引数を追加．

```Fortran

use LeafClass

implicit none

type(Leaf_) :: leaf

call leaf%create(filename="path/to/leafshape.txt",x_num=30,y_num=30)
call leaf%vtk("grape")

end
```

すると細かくなります．
![mesh_high.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/489195/ffb4563a-6db1-8470-2e1f-9ee9543c5c23.png)

##　おまけ：
[個葉の熱拡散シミュレーション](https://qiita.com/soybean/items/48c25d4a793743b4f94f)そのうち加筆します．

ではこのあたりで．
Dockerコマンドで Windowsコンテナー一括削除


#
Docker初心者です。
色々と試行錯誤を繰り返していると、いつの間にかDockerコンテナや、Dockerイメージがたまってきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/518384/787ee053-01d8-5622-a063-685f9093c329.png)
１個ずつイメージを削除するのも、面倒なので下記のコマンドで一括削除をメモします。

#コンテナー一括停止＆削除
コンテナー削除コマンド
```docker rm -f コンテナーid
```
Linuxコンテナーだと、下記コマンドでできますが、
```docker rm `docker ps -a -q`
```
Windowsコンテナーの場合は違うコマンドでやります。
実行中のコンテナーあると、削除できないので、先にコンテナーをすべて停止します

```java:Docker
for /f %T IN ('docker ps -a') DO docker stop %T
for /f %T IN ('docker ps -a') DO docker rm %T
```
実行してみます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/518384/b0b21635-e5af-9ad9-227c-6d6bfbfac25a.png)
「docker ps -a」で確認してみます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/518384/25a1f4f8-8610-d49e-fc29-64e260f97477.png)
すっきり！

#イメージ一括削除

１つイメージ削除、複数削除イメージを削除コマンド
```docker rmi -f イメージid
docker rmi -f イメージid イメージid イメージid
```

イメージのサイズが大きくて、いっぱいたまるとやばくなります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/518384/669f7cef-6cf2-d0e8-e162-66e6adb3bb71.png)
下記コマンドより、イメージを一括削除できます（ご慎重に）

```
for /f %T IN ('docker images --format "{{.ID}}"') DO docker rmi %T
```
実行してみます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/518384/e589c30a-9854-c1d4-6516-6b092f57b4d6.png)
【Android Studio】com.android.applicationエラーが出たときの対処法

# はじめに

下記のようなエラーが出たので、対処法を自分用にメモ。

```
An exception occurred applying plugin request [id: 'com.android.application']
Failed to apply plugin 'com.android.internal.application'.
```

# 対処法
File→Project Strutcure→Gradle Settingsから、Gradle JDKを11に変更。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694762/6d0920bd-a057-3644-064c-20d375def8ec.png" width="80%">
2021.08 時点の .NET Framework のライフサイクル まとめ



.NET Frameworkのライフサイクルを忘れるため、自分のためにまとめ

## ライフサイクル
|Version|開始日|終了日|
|-|-|-|
|.NET Framework 4.8	|2019年4月18日|OSのライフサイクルポリシーに従う|
|.NET Framework 4.7.2|2018年4月30日|OSのライフサイクルポリシーに従う|
|.NET Framework 4.7.1|2017年10月17日|OSのライフサイクルポリシーに従う|
|.NET Framework 4.7|2017年4月11日|OSのライフサイクルポリシーに従う|
|.NET Framework 4.6.2|2016年8月2日|OSのライフサイクルポリシーに従う|
|.NET Framework 4.6.1|2015年11月30日|2022年4月26日|
|.NET Framework 4.6	|2015年7月29日|2022年4月26日|
|.NET Framework 4.5.2|2014年5月5日|2022年4月26日|
|.NET Framework 4.5.1|2014年1月15日|2016年1月12日|
|.NET Framework 4.5|2012年10月9日|2016年1月12日|
|.NET Framework 3.5| Service Pack 1 2007年11月19日|2029年1月9日|
|.NET Framework 3.0|2006年11月21日|2011年7月12日|
|.NET Framework 2.0|2006年2月17日|2011年7月12日|

テクニカルサポートおよびセキュリティアップデートを継続して受けるために、2022年4月26日までに.NET Framework 4.6.2以降へのインプレースアップデートを完了する必要がある。

## .NET Framework 4.6.2以降のバージョンを使用するには、アプリケーションを再コンパイル／再構築する必要があるか？
.NET Framework 4.6.2以降のバージョンは、.NET Framework 4、4.5、4.5.1、4.5.2、4.6、4.6.1の上に互換性のあるインプレース・アップデート。つまり、以前の.NET 4.xバージョンで構築されたアプリケーションは、.NET Framework 4.6.2以降のバージョンで引き続き動作する。これらのバージョンをターゲットにしてアプリケーションを再コンパイルする必要はない。

## .NET Framework 4.6.2以降の変更点
.NET Framework 4.6.2以降のバージョンには、以前の.NETバージョンとの完全な互換性がない、変更/修正がいくつかあるか、気にする必要はない。

## どのバージョンを使えばよいか？
パフォーマンス、信頼性、およびセキュリティを得るために.NET Framework 4.8へのアップグレードがおすすめ。

## 参考文献
[What is the Microsoft Lifecycle Policy for the .NET Framework?
](https://docs.microsoft.com/ja-jp/lifecycle/faq/dotnet-framework)
Next.jsの_app.tsxをTypeScriptで書く


このページではNext.jsの_app.tsxをTypeScriptで書くことを目的にします。
基本的にconstのあとの型は基本的にどのファイルでもReact.FCの型を使います。
Reactで必ず書く「import React from 'react'」 の記述は2021.8/25時点ではNext.jsでは必要なく省略できます。

- AppPropsの型(_app.tsxのみ)
- JSX.Elementの型(明示的に指定するのは_app.tsxのみ)
- React.FCの型(すべての.tsxに必要)

>参考
*[Next.jsでTypeScriptを導入する手順](https://js.excelspeedup.com/nextjs-typescript)
*[_app.tsx内のMyAppの型定義でエラーが出る](https://de-milestones.com/nextjs_typescript_app-tsx_myapp/)




```_app.tsx
import {AppProps} from 'next/app'
import Layout from '../components/layout'
import '../styles/globals.css'

const MyApp: React.FC<AppProps> = ({ Component, pageProps }): JSX.Element => {
  return (
    <Layout>
      <Component {...pageProps} />
    </Layout>
  );
}
export default MyApp;
```


Layout.tsxの中にHeader, Metatext当の全てのパーツを内包し、
このpageProps部分をLayoutタグで囲んであげることで全てのページにLayoutタグを記述する必要がなくなります。
またLayoutをネストする場合getLayout関数を使うことによって実装できます。

SSGを使うに当たって.
静的,静かなというコンセプトを崩してはいけないのかと思います。

10月29日追記
React.FCはchildrenにReactNodeを渡したくない場合VFCを使うといいみたいです。
使われなくなってきてるとはいえ型推論させないで明示的に定義した方がコンパイルが速いみたいなので現在はそうしています。
docker: Error response from daemon: driver failed programming external connectivity on endpointの対応

#状況
`docker run`したらエラーが出て、コンテナはステータスは`Created`で立ち上がりません。

```terminal:エラー文
docker: Error response from daemon: driver failed programming external connectivity on endpoint
```

#環境
* Ubuntu version "18.04.4 LTS (Bionic Beaver)"
* Docker version 19.03.12

#対応
エラー文で検索すると、

>Properly shutting docker down before restart worked for me

と言っている人がいたので、dockerを再起動した後に`docker run`したら上手く動きました。

```terminal:dockerの再起動
$ $ service docker restart
```

#参考

https://github.com/docker/for-win/issues/2722
Nginx で特定パスだけ Basic 認証をかける (Concrete CMS ログインページ等)


Apache だと、.htaccess に記述する方法があります。詳しくは以下の記事にて

https://qiita.com/katzueno/items/675865c2ee6d55755e87

さて、Nginx で PHP (php-fpm) な Concrete CMS (concrete5) の場合はどうでしょうか？
Nginx だと Conf に直接書き込む必要があり root 権限が必要です。

僕がよく使っている Config は Ansible にまとめてあります。
https://github.com/concrete5cojp/ansible-c5-ma/

Nginx はこちら： [nginx template](https://github.com/concrete5cojp/ansible-c5-ma/tree/master/prod-ansible-role/roles/nginx/templates)ディレクトリににまとめてあります


以下がサンプルです。

簡単に言うと、 $basic_auth 変数に off か on を location に応じて代入して、server の最後で basic auth の有効・無効にすると言う方法です。


```nginx
server {

# 省略
## server_name やログなど

## サブディレクトリの場合は location や rewrite 部分のパスを書き換えるのを忘れずに

## 基本は Basic 認証オフなので、変数のデフォをオフに設定
        set $auth_basic off

## ここで /login 配下は on に設定
## サブディレクトリに存在していたら適宜変えてください

    location ^~ /login {
        set $auth_basic on
        index index.php index.html index.htm;
        if (!-e $request_filename) {
            rewrite ^ /index.php last;
        }
    }

# 省略

# php-fpm に送る記述
## 他の表記にしているのなら合わせてください。パスの変更なども忘れずに。

    location ~ \.php($|/) {
    ## 省略
    }

# Basic 認証設定
## .htpasswd の保存場所が違ったら書き換えてください

    auth_basic $auth_basic;
        auth_basic_user_file /var/www/html/.htpasswd;

}

```

Nginx の記述方法は、多種多様だとおもいますので適宜変更してください。


## より技術的な解説

Concrete CMS や WordPress など、 .php 拡張子を隠して、URLクエリを、 URL そのものに見せる方法をとっているアプリがたくさんあります。

location に応じて変数を設定し、Nginx の Server の最後に Basic Auth の設定を加えることで、 rewrite や try_files (本 config は書いてないですが) などで .php が呼び出されたとしても大丈夫です。

まず location のところで変数が設定され、 最後 Basic Auth の部分に渡り、Basic Auth 有効・無効になる仕組みです。

fastcgi キャッシュを有効・無効にしたり、ロードバランサーや監視サーバーの Ping をログに残さないようにしたりと、 Nginx の if と変数を使って試行錯誤した結果でこうなりました。

この方法を使って、`auth_basic_user_file` 部分も変数化し、特定の URL だけ別の ID・PW を設定するなんて芸当もできます。


以上
Truffleのインストールに失敗する

# はじめに
TruffleをDockerのUbuntu環境にインストールしようとしたら、エラーが発生してインストールできなかったので、
解決策をメモ。

# 結論
`npm install`をrootユーザーで実施していたため、権限エラーが出ていました。
rootユーザーを許可して解決。

# 現象
[Truffleの公式](https://www.trufflesuite.com/docs/truffle/getting-started/installation)通りに`npm install -g truffle`を実行すると、下記エラーが出て、インストールに失敗しました。

### 環境
Docker: 20.10.8
Docker上のUbuntu: 20.04

### エラー

```
> node-gyp-build
sh: 1: node-gyp-build: Permission denied
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@~2.1.2 (node_modules/truffle/node_modules/chokidar/node_modules/fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@2.1.3: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: iso-constants@0.1.2 (node_modules/truffle/node_modules/iso-constants):
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: iso-constants@0.1.2 install: `node build.js > index.browser.js`
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: spawn ENOENT
npm ERR! code ELIFECYCLE
npm ERR! syscall spawn
npm ERR! file sh
npm ERR! errno ENOENT
npm ERR! bufferutil@4.0.3 install: `node-gyp-build`
npm ERR! spawn ENOENT
npm ERR!
npm ERR! Failed at the bufferutil@4.0.3 install script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR!     /root/.npm/_logs/2021-08-12T07_36_52_669Z-debug.log
```

# 解決策
下記コマンドでrootユーザーでのインストールを許可して、
再度`npm install -g truffle`を実行するとインストールに成功。

```
npm config set unsafe-perm true
```

デフォルトだと`unsafe-perm`の値がfalseになっているそうです。

※上記以外にも`npm install`のオプションに`--unsafe-perm`を付けて実行する手もあるようです。
　安全面を考えると一律rootユーザーでのインストールを許可するより
　一時的に許可する方が良さそうです。
　が、今回はローカルで勉強用にいじるTruffle環境を作っているだけなので、試していません。
※そもそも論で`npm install`は本来rootユーザーではなく、別途ユーザーを作成して実行するべきなのかも？（調べきれていません。。。）

# 参考
・【docker】npm installしようとしてnode-gyp: Permission deniedエラー
https://hatolabo.com/programming/docker%E3%81%A7npm-install%E3%81%97%E3%82%88%E3%81%86%E3%81%A8%E3%81%97%E3%81%A6node-gyp-permission-denied%E3%82%A8%E3%83%A9%E3%83%BC

以上ですー。
Raspberry Pi 4 (ラズパイ4) でユーザーIDとパスワードを変更する

# 概要
ラズパイは初期設定の状態では
ユーザーIDがPi
パスワードがraspberry
となっており，セキュリティ的によろしくない状態です．なので最初にこれを変更した方が良さそうです．
なおSSHでもGUIでもどちらでもできます．

# 手順
1. 仮のtmpユーザーを作成
2. 自動ログインを無効にする
3. 再起動しtmpユーザーでログインする
4. piユーザーIDの変更，ホームディレクトリの変更
5. 再起動し新しいユーザーIDでログイン後，tmpを削除する
6. パスワードを変更する

## 仮のtmpユーザーを作成
まずpiのユーザーIDを変更するためだけの目的で仮のtmpという名前のユーザーを作成します．
このtmpは後で削除します．

下記コマンドでtmpユーザーを作成し，sudo権限を追加します．
ユーザー作成時にパスワードを要求されます．tmpユーザーは一時的なものなのでなんでも良いですが後でパスワードが必要なので忘れないようにしてください．

```bash:terminal
sudo adduser tmp
sudo gpasswd -a tmp sudo
```

## 自動ログインを無効にする
#### SSHの場合

```bash
sudo raspi-config
```

コマンドを実行します．
「1 System Options」「S5 Boot / Auto Login」「B1 Console」を選択します．
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570280/51f93190-11cc-2120-9a6a-6079234d396f.png" width=70%>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570280/c4eb8039-bfda-f147-1fa1-8b52b8f2ef4b.png" width=70%>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570280/492c9f03-e5ec-a89d-77ad-3d90a5ff014c.png" width=70%>

最初の画面に戻るので右下の「Finish」を選択します．
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570280/490430cf-b8e7-ca1f-8780-90e898486e86.png" width=70%>

Would you like to reboot now?と聞かれるので「はい」で再起動します．
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570280/0bc27017-5b01-be3e-fc31-364aaf3fe49b.png" width=50%>

#### GUIの場合
「設定」から「Raspberry Piの設定」を開きます．
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570280/f8f91133-c7a9-cebb-e6d0-4426e2b04419.png" width=60%>

「システム」内の「自動ログイン」を無効にし「OK」.
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570280/a2140282-3473-fef2-5f1a-6e7fb38f48bb.jpeg" width=70%>
再起動します．


## 再起動しtmpユーザーでログインする
自動ログインを無効にしたので再起動時にログインを要求されます．
この時にpiではなくtmpユーザーでログインします．

## piユーザーIDの変更，ホームディレクトリの変更
piユーザーを変更し，現在piと名前がついているホームディレクトリ名も新しいユーザーIDに変更します．
ここでは新しいユーザーIDをnew_userとします．


```bash:terminal
sudo usermod -l new_user pi
sudo usermod -d /home/new_user -m new_user
sudo groupmod -n new_user pi
```

## 再起動し新しいユーザーIDでログイン後，tmpを削除する
tmpユーザーを削除します．
-rオプションをつけることでホームディレクトリごと削除することができます．

```bash:terminal
sudo userdel -r tmp
```

## パスワードを変更する
ここまででユーザーIDは変更できましたが，パスワードがまだ初期値の「raspberry」のままです．
以下コマンドでパスワードを変更しておきましょう．

```bash:terminal
sudo passwd new_user
```

##### 参考
https://www.souichi.club/raspberrypi/default-user-pi/
https://rs-techdev.com/archives/32
https://qiita.com/NakamoriSuganuma/items/e1bfeb6e46cf09ab1e89
osを作る その6

#概要

osを作る。
setjmpを使わない、ライブラリー使ってみた。

#参考にしたページ

http://okanoue50.my.coocan.jp/2_RTOS/10_RtosForArduiino.htm

#サンプルコード

```
#include "RTOS.h"

volatile uint8_t HandleOfTask1,
	HandleOfTask2,
	HandleOfTask3;

void task1(void) {
	Serial.print("task-1  ");
	Serial.println(millis());
}
void task2(void) {
	Serial.print("task-2  ");
	Serial.println(millis());
}
void task3(void) {
	Serial.print("task-3  ");
	Serial.println(millis());
}

void setup() {
	Serial.begin(9600);
	Serial.println("ok");
	HandleOfTask1 = Rtos.Loading(0, 500000L, task1);
	HandleOfTask2 = Rtos.Loading(0, 750000L, task2);
	HandleOfTask3 = Rtos.Loading(0, 1000000L, task3);
}

void loop() {
	Rtos.Control();
}



```


#結果

```
task-1  499
task-2  749
task-1  999
task-3  999
task-1  1499
task-2  1500
task-1  1999
task-3  1999
task-2  2249
task-1  2499
task-1  2999
task-2  2999
task-3  3000
task-1  3499
task-2  3749
task-1  3999
task-3  3999
task-1  4499
task-2  4499
task-1  4999
task-3  5000
task-2  5249
task-1  5499
task-1  5999
task-2  5999
task-3  5999
task-1  6499
task-2  6749

```


以上。
Python3: UDP を受信

こちらの記事を参考にしました。
[UDPでデータを受信する最も単純なPythonコード（Jupyter notebook版）](http://www.ams.eng.osaka-u.ac.jp/user/ishihara/?p=1942)

次のバージョンで確認しました。

>```text
$ python3 --version
Python 3.7.3
```

ポート 8092 の受信

```py:receive.py
#! /usr/bin/python3
#
#   receive.py
#
#                           Aug/25/2021
#
import socket
import sys

udp = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
udp.bind(("0.0.0.0",8092))

sys.stderr.write("*** start ***\n")

while True:
    try:
        rcv_byte = bytes() #バイトデータ受信用変数
        rcv_byte, addr = udp.recvfrom(1024) #括弧内は最大バイト数設定
        msg = rcv_byte.decode() #バイトデータを文字列に変換
        print(len(msg))
        print(msg)
        if msg.strip() == 'close':
            udp.close()
            break
    except KeyboardInterrupt:
        udp.close()
```

ポート 8092 に udp で送信するスクリプト

```bash
echo 'Good Morning' | ncat -4 -u -w 1 localhost 8092
```

終了させるスクリプト

```bash
echo 'close' | ncat -4 -u -w 1 localhost 8092
```
【キャッチアップ】nextjs

## レンダリング
通常はプリレンダリング方式で、静的生成(static generation ビルド時にHTMLが生成される)とSSR(server side rendaring リクエストの度にHTMLが生成される)をそれぞれのページで選択できる

## レンダリング方式とクッキー
通常cookieはクライアントに保持されているので、ssrの場合はサーバサイドにcookieを持っていいないので、cookieで認証を行っている場合は、エラーになる
【参考】

https://note.com/fz5050/n/n13898d5acf21

### 参考URL
https://nextjs-ja-translation-docs.vercel.app/docs/tag/v9.2.2/getting-started
久々にAndroidStudio/ IDEAを開いたら何故かエラーまみれな時の対処法

#この記事は
私は主にAndroid StudioやIDEAなどを好んで使用していますが、久々にアプリを開くと何故かエラーまみれな時が多いですのでその時の対処法をここに備忘録として書き記します。このエラーまみれというのは、以前に放置していたエラーなどではなく、むしろ前は何のエラーも出ていなかったのに！というシチェーションを想定しています。

# とりま再起動
「「 再起動は無敵 」」
一回`Cmd + Q`でIDEを閉じます。そしてもう一度プロジェクトを開きます。
これで上手くいくことが大体だと思っています。

# キャッシュをクリア
キャッシュをクリアにします。それぞれのエディタもしくはIDEによってキャッシュをクリアにする方法は違うと思いますので調べてください。

ちなみにAndroid Studioの場合は`Build->Clean project`
IDEAの場合は`File->Invalidate Caches`

# 信じてビルド
明らかに赤まみれのコードやけど信じて`Build -> Build Project`を実行してみましょう。何故か機嫌を取り戻すことができたりします。

他にも何か解決方法を発見した場合は随時解決方法を追加していきます。
【Big Sur11.6について追記】M1 MacBookのメモリ使用量が劇的に改善した件について

2021年9月21日　追記
アップデート後にSafariの仕様が変更されて、メモリ使用量の変化も気になったので試してみました。
結果として、タブを開きまくってもメモリ使用量が比較的上がりにくくなっていたので、下記の対応は今後不要かもしれません。
![スクリーンショット 2021-09-21 8.23.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1693676/8f4c98ea-e3d5-0fde-8ab6-636f2d5d4ba4.png)
新たなタブグループの機能で、使っていないグループのメモリ使用量が気になるところではありますが、いい確認方法があるようでしたら教えて頂けると幸いです。
2021年9月21日　追記ここまで

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

まず初めに、下記サイトの方に心より感謝を。
普段投稿とかしないけど、劇的に変わりすぎて滅茶苦茶感動しております。


https://blog.h-wd.info/2015/09/01/safariのメモリ使用量を劇的に減らす方法/

普段、M1のMacBookメモリ８GBを使っているのですが、Safariのメモリ使用量が重すぎて常にグラフの色が黄色になっている状態でした。
↓こんな感じ
![スクリーンショット 2021-08-25 12.39.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1693676/666f2a52-fe98-1786-666a-77e4eff0c31b.png)

それが、冒頭に感謝したブログの通り、Safariのデバッグメニューをオンにして「Disable Per-tab Web Processes」をオンにするだけで劇的に減りました！
↓こんな感じ
![スクリーンショット 2021-08-25 12.42.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1693676/4573a5b7-89e5-9929-9288-8c5639d2168f.png)

これで何とかMacBookの買い替えをせずに戦えそう。
【備忘録】ThinkStation S30の諸々の設定方法

#はじめに
これは私が今サーバーとして運用しているThinkStation S30についての備忘録です。
S30についてはネット上に情報が散見されるだけで（だいたい英語だし）、まとまった記事がないので、どなたかのお役に立てれば幸いです。

#この記事を参考にする前に
まずはCMOSクリアをしてください。だいたいの悩みはそれで解決します。
また、マザーボードのバージョンは4351~と0567~の二種類があります。自分のがどちらかを把握しておいてください（筆者のは0567~）

#各エラーコードごとの対応（またなにかあったら追記）
b2,b7,b9:だいたいメモリ関連。プライマリのスロットに一枚だけ挿して、うまくいってから増やしてください。
F2:ジャンパピンを2-3スロットにさしてると発生。このときはリカバリ用のディスクを探しているので、マザボのバージョンに合ったBIOSを焼いてください。
62:BIOSの破損？焼きなおしましょう

#おわりに
一回起動するとかなり安定します。それまで苦労しますが。
お名前ドットコム+AWS Route 53+S3でhttp静的サイト公開ハンズオン

今回は静的サイトのテスト環境として設定していく手順のメモです。
※コンソール画面の構成が変わりやすいので画面キャプチャは載せない形で書いてみました。(2021/8執筆)
構成やボタンなどは同じものも多いので適宜似た単語などを探して進めてみてください。

このハンズオンを最後まで進めると
お名前ドットコム　→ Route 53　→ S3の形式（http）で
静的なサイト公開までが実現できます。

# １．ドメインレジストラを決める
ドメインレジストラはお名前ドットコムにしました。AWSでも取得できますがここは好みで良いと思います。ドメインをまず取得します。
# ２．S3バケットを作成します
ウェブサイトをS3で公開する場合はバケット名とウェブサイトのドメインを合わせる必要があります。今回はwww.example.comという前提で進めます。
　１．S3コンソール画面から[バケットを作成]ボタンをクリックします。
　２．バケット名にwww.example.comと入力
　　　リージョンにap-northeast-1と入力
　　　あとはとりあえずデフォルトで[バケットを作成]ボタンをクリックします。
　３．ここからバケットの設定を進めます。作成した[バケット名]をクリックします。
　４．[プロパティ]タブをクリックします。一番下の静的ウェブサイトホスティングの[編集]をクリックします。
　　　[有効にする]にチェックを入れます。
　　　インデックスドキュメントに[index.html]
　　　エラードキュメントに[error.html]を入力します。
　　　index.htmlはドメインにアクセスした時に表示されるトップページのhtmlファイル名
　　　error.htmlは404エラーなどが起こった際に表示されるエラーページのhtmlファイル名で
　　　後ほどこの名前でファイルを作成してアップロードします。
　　　他の設定はデフォルトで[変更の保存]をクリックします。
　５．index.htmlを作成しアップロードします。
　　　S3コンソールからバケット名をクリックし[アップロード]ボタンを押します。
　６．パブリックアクセスブロックの設定を解除します。
　　　[アクセス許可]のタブからブロックパブリックアクセスの[編集]をクリックして
　　　パブリックアクセスをすべてブロックを[オフ]に設定します。
　７．バケットへのアクセス権（バケットポリシー）を編集します。
　　　[アクセス許可]のタブをクリックします。
　　　バケットポリシーの[編集]をクリックします。
　　　まずバケットARNをコピーします。
　　　ポリシージェネレータで以下のように設定します。
　　　
　　　バケットARNはコピーしたものを貼り付けます。
　　　貼り付けたら/*を追加し、"Resource": "arn:aws:s3:::www.example.com/*",　のような形にします。
　　　[Add Statement]　→　[Generate Policy]とクリックすると
　　　yamlが生成されるのでそれをコピーします。
　　　バケットポリシーの編集タブに戻ってポリシーの部分にyamlを貼り付けます。
　　　Sidの項目を後でわかりやすいように書き換えておきます。
　　　ここでは次の名前にしておきます。[PublicReadForGetBucketObjects]
　　　※Sidはポリシー内でかぶっていなければ自由につけても良い識別子です。
　８．[プロパティ]タブ最下部の[パブリックウェブサイトエンドポイント]のURLをクリックすると
　　　ひとまずhtmlの内容がブラウザから見られるはずです。
# ３．Route 53の設定で独自ドメインでS3のhtmlを表示
　１．https://console.aws.amazon.com/route53/を開きます。
　２．[ホストゾーンの作成] を選択します。
　３．[ドメイン名]を入力します。
　４．タイプで[パブリックホストゾーン]を選択します。
　５．[ホストゾーンの作成]をクリックします。
　６．ホストゾーンが一つ登録されます。[ホストゾーン] → 登録した[ドメイン名] → [レコード作成]と進みます。
　７．レコード名に[www]
　　　レコードタイプに[A]
　　　エイリアスを[オン]
　　　トラフィックのルーティング先に
　　　[S3ウェブサイトエンドポイントへのエイリアス]
　　　[ap-northeast-1]
　　　S3の[パブリックウェブサイトエンドポイント]（前述手順２-８で使用したもの）を設定し
　　　他はデフォルトで[レコードを作成]をクリックします。
※AliasレコードはAWS独自のレコードでCNAMEレコードと似た機能が使えますがAWSのサービスを使う際にはCNAMEレコードよりもパフォーマンスの面で向上が見込めるものになります。詳しくは以下の記事を参照してみて下さい。
[Aliasレコード](https://qiita.com/SwuBHj8aKGqBKHet/items/df9c567750166bdadd02#alias%E3%83%AC%E3%82%B3%E3%83%BC%E3%83%89)

# ４．お名前ドットコムのネームサーバを設定する
　　１．お名前ドットコムの管理画面にログインする。
　　２．メニューから[ドメイン]をクリック[ドメイン一覧]をクリックします。
　　３．変更するドメイン名をクリックします。
　　４．[ネームサーバの変更]をクリックします。
　　５．ここで一度Route 53の管理画面にいってNSレコード(ns-xxx.awsdns-xx.xxx)を４つコピーします。
　　６．お名前ドットコムの管理画面で２．ネームサーバの選択のところで[その他]を選択し[その他のネームサーバを使う]にチェックを入れ
　　　　NSレコードを１つずつコピーペーストしていきます。４つ目は＋ボタンを押すと追加できます。
　　７．[確認]ボタンをクリックししばらく待つとwww.example.comでS3の内容が表示されると思います。
　　　　（公式では反映まで２４時間〜７２時間とのことですが私の環境では３時間ほどで一回確認したら反映されていました。）

#CDNやSSLを組み込みたい
そんな方は続きをどうぞ
[Route 53 + CloudFront + ACM + S3でCDN＆SSL付き静的サイト公開](https://qiita.com/SwuBHj8aKGqBKHet/items/b419334187e12d546c06)

# 参考情報
[Route 53の開始方法](https://docs.aws.amazon.com/ja_jp/Route53/latest/DeveloperGuide/getting-started.html)
国際化エラー I18n::MissingTranslationData: translation missing: en.faker.name.first_name

#"Fakerを利用してseedファイルにデータを生成する##

Fakerとは、ランダムな値を生成するGemです。
Gemfile の中に gem 'faker' を追記して、 
bundle install コマンドを実行すれば準備完了
　
a = Faker::Games::Pokemon.nameというコードを記述すると、
変数aの中にポケモンの名前がランダムで一つ入ります。

seeds.rb

```rb
9.times do |n|
  name = Faker::Games::Pokemon.name
  email = Faker::Internet.email
  password = "111111"
  password_confirmation = "111111"
  User.create!(name: name, email: email, password: password, password_confirmation: password_confirmation, admin: false)
end
```
##I18n::MissingTranslationData: translation missing: en.faker.name.first_name##

Gemファイルを生成し、rails db:seedをを実行すると値を生成できるはずだが
以下のエラーが表示された。
"I18n::MissingTranslationData: translation missing: en.faker.name.first_name"
I18nと記載されているので国際化のエラーだと分かり、以下の修正案にたどり着く

config/initializers/locale.rb (修正前)

```rb
I18n.config.available_locales = :ja
I18n.default_locale = :ja
```

上記が日本語でしか対応していないため、英語表記にも対応させるよう修正します。
以下修正案

```rb
I18n.config.available_locales = [:ja, :en]
I18n.default_locale = :ja
```

上記に修正し、念の為rails db:resetをかけてからrails db:seedを実行
すると、以下のデータが生成されている

```
#<User id: 2, name: "コンパン", email: "vincent@pagac.org", password_digest: "$2a$12$jjcPvv7fLS4dwd7aVoTrDedMGhRGJHiZA8oRC/EWP6r...", created_at: "2021-08-25 02:46:31", updated_at: "2021-08-25 02:46:31", admin: false>, 
#<User id: 3, name: "ゴーリキー", email: "werner_conroy@luettgen-witting.info", password_digest: "$2a$12$mS84t4EHKkblZb1zBN5rvOA.rULv6dqKSj/qrCcx/RU...", created_at: "2021-08-25 02:46:31", updated_at: "2021-08-25 02:46:31", admin: false>, 
```

簡単にデータを生成できるため、テストデータを作る際は活用してみて下さい！
自由は大切ですか？

自由は大切ですか？ 家族は大切ですか？

同じように大切なものなら、何を選びますか？

//

息子が一家で英国に移住、うつ病の高齢者が過剰摂取で入院

息子の移住から3カ月後、昔からうつ病を患っていた祖母が、薬の過剰摂取で入院した。 精神的に耐えられないのではないかと心配した医師は、家に帰らず、リハビリテーションセンターに移ることを勧めた。 息子の実家に頼って生活していた祖母は、息子が移住したことで生活の主軸や本来の役割を失い、息子は海外にいることに罪悪感を感じていました。
//

香港人は一昨年から徐々に自由を失い、計画段階から行き当たりばったりの実行へと進み、おそらく家族の気持ちを無視し、ほとんどの人が不動産を売却して<a herf="https://www.fminvestment.com/properties_uk">買英國樓</a>を購入して以来、徐々に自由と家族の間で決断を下してきました。

この2年間で<a herf="https://www.fminvestment.com/upcoming">海外樓盤</a>がたくさん出てきましたが、<a herf="https://paper.hket.com/article/3005999/%E3%80%90%E8%8B%B1%E5%9C%8B%E8%B2%B7%E6%A8%93%E5%BF%85%E8%AE%80%E7%AF%87%E3%80%91%E8%8B%B1%E5%9C%8B%E8%B2%B7%E6%A8%93%E7%A8%8B%E5%BA%8F%E7%B8%BD%E8%A6%BD?mtc=b0033>英國買樓</a>、<a herf="https://www.fminvestment.com/properties_japan">買日本樓</a>、物件を買うには違いがあります。

しかし、過ぎたるは及ばざるがごとしで、別の方法で愛したほうがいい。

イギリスの不動産価格について知っておくべきことを説明します。


英国での住宅購入は、ほとんどの人にとって大きな投資となるため、不確実性による遅延や誤解を避けることが重要です。

<a herf="https://paper.hket.com/article/3005999/%E3%80%90%E8%8B%B1%E5%9C%8B%E8%B2%B7%E6%A8%93%E5%BF%85%E8%AE%80%E7%AF%87%E3%80%91%E8%8B%B1%E5%9C%8B%E8%B2%B7%E6%A8%93%E7%A8%8B%E5%BA%8F%E7%B8%BD%E8%A6%BD?mtc=b0033">英國樓價</a>

購入者は、売買予備契約書に署名し、手付金を支払う必要があります。

英国の弁護士に売買契約書を作成してもらう

売買予備契約書に署名した後、購入者は、売買契約書およびその他の関連文書を作成するために、英国の資格ある事務弁護士を任命し、権限を付与する必要があります。

売買契約書の締結と頭金の支払い

購入者は、物件価格の10〜25％の頭金を支払って契約することができます。 頭金は、買い手と売り手の両方を保護するために、事務局の口座に入金されます。

所有権の取得

引き継ぎ前のインスペクションにより、お客様は物件の問題点をタイムリーに把握することができます。
JavaScriptの非同期通信で422エラーが出たのでCSRFトークンの検証を検証しないようにした

#開発環境
- OS：macOS Big Sur 11.2.2
- Ruby：2.6.5
- Ruby on Rails：6.0.0
- テキストエディタ：Visual Studio Code

#課題
twitterのいいねボタンを押下したときのように、非同期通信でDB更新しつつWebページの見た目を変えたかった。
今回はXHRオブジェクトを作って実装。

```clip.js
~
XHR.open('POST', URL, true);
XHR.send();
```

このリクエストが422エラーになる。もう少し詳細を追ってみると、
「ActionController::InvalidAuthenticityToken」
というエラーだった。

# CSRFとrailsのCSRF対策について
**CSRF=クロスサイトリクエストフォージェリ**とは脆弱性のあるWebアプリケーションに対し悪意のあるリクエストを送り攻撃すること。

railsではCSRF対策メソッドとして[protect_from_forgery](https://github.com/rails/rails/blob/main/actionpack/lib/action_controller/metal/request_forgery_protection.rb#L14)が用意されている。
こちらrails5.2より前のverでは、アプリケーション生成した際に自動で`application_controller.rb`に記述されていたらしく、簡単に言うとリクエストに含まれたトークンを精査することで悪意のあるリクエストでないかチェックするというもの。(5.2以降のverでは継承元の`ActionController::Base`に記載されている。）

link_toやform_withなどのヘルパーメソッドを使った場合、またjQueryを使ったリクエストはこの認証に使うトークンを自動生成して付与してくれるらしいが、JavaScriptのみでリクエストを生成して送信した場合はこのトークンがないのでチェックに引っ掛かってしまう。今回のエラーはそれが原因。

#解決方法
検証そのものを完全無効化するやり方もあるらしいが、それは怖いので

```clips_controller.rb
class ClipsController < ApplicationController
  skip_forgery_protection
end
```

この一文を対象のコントローラーの最初に記載した。
`skip_forgery_protection`は名前の通り、トークン検証をここではskipしますというメソッド。これでエラー解消できた。
Linux (ubuntu) でRパッケージtidyverseをインストールしたときにでるエラーの対処法

Linux上に構築したR環境でtidyverseをインストールする際に毎度同じエラーが発生するのでその対処法を備忘録として書き残しておきます．
この記事ではUbuntuを想定します．

### 最初に出るエラーメッセージ
まず普通に

```R
install.packages("tidyverse")
```

でパッケージのインストールを試みます．
すると下記のようなエラーメッセージが表示されます．

```R
Warning messages:
1: In install.packages("tidyverse") :
  installation of package ‘xml2’ had non-zero exit status
2: In install.packages("tidyverse") :
  installation of package ‘rvest’ had non-zero exit status
3: In install.packages("tidyverse") :
  installation of package ‘tidyverse’ had non-zero exit status
```

どうやらxml2, rvestというパッケージのインストールが上手くいっていないことが原因のようです．

### エラーの原因になっているパッケージをインストールする

ではまずxml2のインストールを試みます．

```R
install.packages("xml2")
```

すると下記のようなエラーが出ます．

```R
------------------------- ANTICONF ERROR ---------------------------
Configuration failed because libxml-2.0 was not found. Try installing:
 * deb: libxml2-dev (Debian, Ubuntu, etc)
 * rpm: libxml2-devel (Fedora, CentOS, RHEL)
 * csw: libxml2_dev (Solaris)
If libxml-2.0 is already installed, check that 'pkg-config' is in your
PATH and PKG_CONFIG_PATH contains a libxml-2.0.pc file. If pkg-config
is unavailable you can set INCLUDE_DIR and LIB_DIR manually via:
R CMD INSTALL --configure-vars='INCLUDE_DIR=... LIB_DIR=...'
--------------------------------------------------------------------
```

rvestでも同じエラーが出ました．
<B>(重要) ここでエラーメッセージをちゃんと読みます．

今回はOSはUbuntuなのでdebに当てはまります．
*debの欄を見るとlibxml2-devと書いてあります．
つまりlibxml2-devをubuntuにインストールすればよさそうです．
ターミナルから以下コマンドを実行します．

```sh:bash
sudo apt install libxml2-dev
```

rvestパッケージも同様にエラーメッセージに従います．

これでR上でxml2やrvestパッケージもインストールできるようになり，tidyverseも無事インストールできます．
node.jsが動くローカル環境で動かした時のログ

node.jsが動く環境構築したら、移動
今回は*****-staticという所

$ cd git
$ cd *****-static
$ pwd
/Users/*****/git/*****-static
ローカル動かす時は、対象のローカルブランチに移動する


$ npm i
これはただの確認？

$ npm start　　
startで動くらしい

上記で動かして、
http://0.0.0.0:8000/の後に、ディレクトリのパスを貼り付ければページが見れる

control+cで停止できる。
IISでSSL設定時に証明書要求の完了後にサーバ証明書の表示が消える

IISでSSL設定時に証明書要求の完了後にサーバ証明書の表示が消える問題に直面したので、
解決した方法のメモ

mmcのコンソールで中間証明でcaファイルをインポートした後に、
IISのサーバー証明書で証明書の要求の完了でcerファイルをインポートし
設定が完了してリストに現れるが、別の画面に移動したりリストを更新すると表示が消えてしまった。


・mmcのコンソールから「証明書」を見ると、要求の完了をした同じ名称がリストにあるが鍵マークがついていない

・有効なものであれば鍵がついており、開いてみると「この証明書に対応する秘密キーを持っています。」の文字があるが、消える証明書には記載がありません。

・PowerShellを起動し下記を入力
シリアル番号は証明書の詳細タブ、シリアル欄にあります。

```certutil -repairstore my "シリアル番号"
```



・次のメッセージが出ると成功「成功すると暗号化のテストに合格しました。」

・mmcコンソールの証明書を更新すると消える証明書に鍵マークがつくことを確認

・IISのサーバー証明書の一覧を最新化すると、消えた証明書が表示される
MSLearn の Azure Functions を使用して Cosmos DB からデータを読み取る演習でつまった点

# はじめに

本記事MSLearnでつまった点をまとめることを目的としています。
今回は[こちら](https://docs.microsoft.com/ja-jp/learn/modules/chain-azure-functions-data-using-bindings/)のMicrosoftLearnに従って勉強会を行いました。

今回はAzure Functionsを使用して、CosmosDBからデータの読み取りをAzureのポータル上で実施する方法を学びました。その演習中につまってしまう人がいたため、共有します。

# 演習でつまった点

MSLearnの演習の以下の手順でつまってしまいました。
[試してみる](https://docs.microsoft.com/ja-jp/learn/modules/chain-azure-functions-data-using-bindings/5-read-data-with-input-bindings-portal-lab?pivots=javascript#:~:text=%E9%81%B8%E6%8A%9E%E3%81%97%E3%81%BE%E3%81%99%E3%80%82-,%E8%A9%A6%E3%81%97%E3%81%A6%E3%81%BF%E3%82%8B,-%E5%B7%A6%E5%81%B4%E3%81%AE%E3%83%A1%E3%83%8B%E3%83%A5%E3%83%BC)
ここまでの段階で、以下が行われています。

- CosmosDBの作成とそのデータベースとコンテナの作成
- 読み取り検証用のサンプルデータをCosmosDBに追加
- HTTPトリガーの設定をしたAzure Functions（関数）の作成
- HTTPトリガーの入力バインディングの作成（CosmosDBをバインド）
- 関数の実装
- 関数の実装の更新
- 入力バインディングの変更（入力バインディングの定義が記載されているFunction.jsonを変更）

試してみるの章では、これまでで作成したAzure Functionsが正常に動くかの検証を行います。
手順の通り、検証したところ、エラーが出てしまいました。

※（脱線）Azure Functionsにおけるバインディング
Azure Functionにおけるバインディングとは、アプリが実行する関数に対する入力と出力をAzure上のサービスやサードパーティーのサービスと結び付けることです。関数は自身が引き受けられる正しい入力を受け取れば、それを何らかの形で加工／整形して、出力を行います。入力元や出力先がどんなサービスかは知らずに作ることができ、柔軟な処理を行えるようにしています。

# 原因

演習の手順に、入力バインディングを変更する手順がありました。ここでは、入力バインディングでid と partitionKeyの値を変更し、{id}パラメータを受け取れるよう、Function.jsonを書き換えるという作業を行います。
前提として、入力バインディングを作成した時点で、バインド先のCosmosDBの情報などバインドに必要な情報はFunction.jsonに記載されています。
そのため、Function.jsonの中のid と partitionKeyの値のみを変更すればよかったのですが、以下の、MSLeaenの手順にあったjsonでFunction.jsonをすべて上書きしたために、必要ないパラメータまで変更されてしまい、エラーが起きました。

```json
{
  "bindings": [
    {
      "authLevel": "function",
      "type": "httpTrigger",
      "direction": "in",
      "name": "req",
      "methods": [
        "get",
        "post"
      ]
    },
    {
      "type": "http",
      "direction": "out",
      "name": "res"
    },
    {
      "name": "bookmark",
      "direction": "in",
      "type": "cosmosDB",
      "databaseName": "func-io-learn-db",
      "collectionName": "Bookmarks",
      "connectionStringSetting": "your-database_DOCUMENTDB",
      "id": "{id}",
      "partitionKey": "{id}"
    }
  ]
}

```

上記、Function.jsonの`connectionStringSetting`にはバインド先のCosmosDBの名前がすでに記載されていたのに、それを、`your-database_DOCUMENTDB`という間違った文字列で上書きしてしまったため、エラーが起きました。

# さいごに

最後までお読みいただき、ありがとうございました。
今回はAzure Functionsの用語や扱いに慣れておらず、今設定した項目がどこに効いてるのかの関連を意識できていないことがつまってしまった原因の一つだと思いました。
1つ1つ着実に理解するよう頑張っていきます。
Python + SendGrid APIでとりあえずメールを送ってみる

# はじめに
この記事は、
**「SendGrid APIを使ってPythonからメールを送ってみたい」**
という願いを持つ方に向けて執筆しています。

既に既出の内容ではありますが、
私の環境では以下の記事の通りにコードを打ってみても
メールが送信できずに、少しハマったので備忘録として残しておきます。

https://qiita.com/takuma-jpn/items/8acc7d3bcbe6ec606e0d

https://qiita.com/Dalice/items/cb51687aae4dba3b2b1e

# サクッと結論
※SendGridのAPI Key発行&pipでのsendgridのインストールは済んでいる前提で説明します。
　済んでいない方は、上記の記事を参考にしてください。

インストールしている**SendGridのverが6.8.0であれば**、
以下のように記述すればOKです。

```python:send_email.py
# using SendGrid's Python Library
# https://github.com/sendgrid/sendgrid-python
import os
from sendgrid import SendGridAPIClient
from sendgrid.helpers.mail import Mail

SENDGRID_API_KEY   = "xxxxx" # ご自分の取得したAPI_KEYを入れてくだされ

message = Mail(
    from_email='from_email@example.com', # メールの送信元
    to_emails='to@example.com', # メールの送信先
    subject='Sending with Twilio SendGrid is Fun', # タイトル
    html_content='<strong>and easy to do anywhere, even with Python</strong>') # メールの本文
try:
    # sg = SendGridAPIClient(os.environ.get('SENDGRID_API_KEY'))
    sg = SendGridAPIClient(SENDGRID_API_KEY)
    response = sg.send(message)
    print(response.status_code)
    print(response.body)
    print(response.headers)
except Exception as e:
    print(e.message)
```

ちなみにこれ、英語版の公式ドキュメントに載ってました。
英語にアレルギー反応がなければ、普通に見つけられるかと。

https://docs.sendgrid.com/for-developers/sending-email/v3-python-code-example

# 予想される検索ワード
以下、この記事を求めているであろう方が入力しそうな
（というか実際に私が必死で検索した）検索ワードです。

Python, SendGrid, SendGrid 6.8.0

# 実行環境
- Windows10
- Python 3.9.4
- sendgrid 6.8.0

# 原因
既出の記事通りに上手くいかなかった原因ですが、
どうやら**sendgridのverによって、記述方法が変わっている**らしいです。
（verによって記述方法がどう変わるのかとか細かいとこまでは調べてないです）

似たようなパターンでハマったという記事もあったので
ご参考にしてください。

https://hack-le.com/python-sendgrid/

sendgridについては記事によって記載方法が異なっているので
わりと混乱しがちですね。
基本的には**キチンと公式ドキュメントを確認する方が良さそうです。**

# おわりに
プログラミングに関わると、verに苦しめられることは多々あるのですが、
ここまで記述がころころ変わるのも珍しい気がします。
やっぱり公式ドキュメント（というか英語）とはちゃんと向き合わないとですね...
DatadogでLocal DB を監視する

## これは何

DatadogでEC2(CentOS7)内のLocal DB(MySQL5.7) を監視してみた、のメモです。

## はじめに

Datadog Agent は MySQL データベースから、次のような多数のメトリクスを収集できます (一例)。

``クエリスループット``
``クエリパフォーマンス (平均クエリ実行時間、低速なクエリなど)``
``接続数 (現在開かれている接続、中断された接続、エラーなど)``
``InnoDB (バッファプールメトリクスなど)``

カスタム SQL クエリを使用して、独自のメトリクスを作成することもできます。

## MySQLでセットアップ

MySQL サーバーで、Datadog Agent 用のデータベースユーザーを作成します。

```sql
$ mysql> CREATE USER 'datadog'@'localhost' IDENTIFIED BY '<一意のパスワード>';
```

Agent がメトリクスを収集するには、いくつかの権限が必要です。次のように、限られた権限のみをユーザーに付与してください。

```sql
mysql> GRANT REPLICATION CLIENT ON *.* TO 'datadog'@'localhost' WITH MAX_USER_CONNECTIONS 5;
mysql> GRANT PROCESS ON *.* TO 'datadog'@'localhost';
```

有効になると、追加の権限を付与することで、performance_schema データベースからメトリクスを収集できます。

```sql
mysql> show databases like 'performance_schema';
+-------------------------------+
| Database (performance_schema) |
+-------------------------------+
| performance_schema            |
+-------------------------------+
1 row in set (0.00 sec)

mysql> GRANT SELECT ON performance_schema.* TO 'datadog'@'localhost';
```

## Datadog設定ファイル編集

MySQL のメトリクスとログの収集を開始するには、/etc/datadog-agent/conf.d/mysql.d/conf.yaml ファイルを編集します。

datadog-agentをインストールすると、サンプルとして、mysql.d/conf.yaml.sampleがあると思います。
使用可能なすべてのコンフィギュレーションオプションについては、サンプルを参照してください。

MySQL メトリクスを収集するには、mysql.d/conf.yaml に次の構成ブロックを追加します。

```yaml
init_config:

instances:
  - server: 127.0.0.1
    user: datadog
    pass: "<YOUR_CHOSEN_PASSWORD>" # from the CREATE USER step earlier
    port: "<YOUR_MYSQL_PORT>" # e.g. 3306
    options:
      replication: false
      galera_cluster: true
      extra_status_metrics: true
      extra_innodb_metrics: true
      extra_performance_metrics: true
      schema_size_metrics: false
      disable_innodb_metrics: false
```

Agent を再起動すると、Datadog への MySQL メトリクスの送信が開始されます。

```
$ sudo systemctl restart datadog-agent
```

あとはGUIでdatadog-monitorを作成するか、Terraformなどでコードで立ち上げれば、監視できると思います。

## TCPで疎通確認する

3306ポートで接続できるか、監視したいので、その設定を入れていきます。

```
$ vi /etc/datadog-agent/conf.d/tcp_check.d/conf.yaml
```

```vim
init_config:
instances:
  - name: TCP-3306_check(例)
    host: 127.0.0.1
    port: 3306
    collect_response_time: true
```

```
$ sudo systemctl restart datadog-agent
```

Syntaxエラーがないかチェックします。

```
$ sudo datadog-agent configcheck
```

「tcp_check」 として、設定した内容が出ます。

```
$ sudo datadog-agent status
```

```
tcp_check (3.1.1)
    -----------------
      Instance ID: tcp_check:TCP-3306_check:XXXXXXXXXX [OK]
      Configuration Source: file:/etc/datadog-agent/conf.d/tcp_check.d/conf.yaml
      Total Runs: 12
      Metric Samples: Last Run: 2, Total: 24
      Events: Last Run: 0, Total: 0
      Service Checks: Last Run: 1, Total: 12
      Average Execution Time : 0s
      Last Execution Date : XXXXXXXXXX
      Last Successful Execution Date : XXXXXXXXXX
```


## 参考

```
https://docs.datadoghq.com/ja/integrations/mysql/?tab=host
```
Swift　キーチェーンメモ

キーチェーンとは
--
ユーザーIDやパスワード等の個人情報を集中管理する仕組みのことを指す。
ログインが必要な際に自動で番号の入力欄をうめることができる。
キーチェーンは[Icloudキーチェーン」と呼ばれ、自動的に作成されていて、AppleIdで共有されている。
アプリを削除してもデータは無くならない、データ自体はアプリの中ではなくデバイス自体に保存される。
暗号化もされており、セキュリティ面でもUserdefaultsより高い。

キーチェーンの使い分け
--

UserDefaults
・アプリが削除しても構わない
・他の端末と共有したくない

キーチェーン
・他の端末の共有したい
・セキュアな値である
・アプリが削除しても残したい

プロビジョニングファイルに連携しているので許可しなければ他のアプリと共有できないようになっている
→プロビジョニングファイルとは、、
プロビジョニングファイルは、アプリケーションID（アプリケーションを識別するID)、デバイス識別子（アプリを動かすデバイスを識別する識別子）、正規開発者証明書をまとめたファイル。
これを登録しておくことで、条件にあったアプリをインストールできる
SchemaSpyを使って、RDSのTable情報をER図まで自動的に作って欲しい

# 概要

SchemaSpyを使って、接続先のDBのTable情報を綺麗に抜き取り、あわよくばER図にしてくれるところまでしてほしい

# SchemaSpy

[GitHub - schemaspy/schemaspy: SchemaSpy code home](https://github.com/schemaspy/schemaspy)

# やった事

1. EC2にDockerを追加
2. SchemaSpy Dockerイメージの取得
3. schema生成
4. ローカルにSchemaデータをDL

## EC2にDockerを追加

```bash
$ sudo yum install -y docker
$ sudo service docker start
# ec2-userがdockerコマンドを実行できるように、ec2-userをdockerグループに入れる
$ sudo usermod -a -G docker ec2-user
```

## SchemaSpy Dockerイメージの取得

```bash
$ docker pull schemaspy/schemaspy
# インストール確認
$ docker images
```

このまま稼働させると、以下のエラーが発生

```bash
WARN - Connection Failure
Failed to connect to database URL [jdbc:mysql://mysql:3306/hoge] Unknown system variable 'query_cache_size'
```

MySQLJDBC ドライバのバージョンを上げれば解決するとのことなので、MySQL手に入れる

```bash
$ mkdir -p drivers
$ curl -L https://dev.mysql.com/get/Downloads/Connector-J/mysql-connector-java-8.0.16.tar.gz |
    tar xvzf - -C drivers --strip=1 mysql-connector-java-8.0.16/mysql-connector-java-8.0.16.jar
```

## schema生成

まずはDBの各環境変数をexport

```bash
$ export DB_HOST={HOST名}
$ export DB_PORT={Port番号}
$ export DB_NAME={DB名}
$ export DB_PASS={DBPass}
$ export DB_USER={DBUser}
```

Docker起動

```bash
$ docker run --rm --net="host" -v "$PWD/schema:/output" -v "$PWD/drivers:/drivers" -u root:root schemaspy/schemaspy:latest -t mysql -host ${DB_HOST}:${DB_PORT} -db ${DB_NAME} -u ${DB_USER} -p ${DB_PASS} -connprops useSSL\\=false -s ${DB_NAME}
```

## ローカルにSchemaデータをDL

まずはEC2先で、SchemaファイルをZip化

```bash
$ zip -r schema.zip schema
```

ローカルに戻り、EC2上のschema.zipを入手する

```bash
$ scp -i "$HOME/.ssh/{秘密鍵のPath}" ec2-user@{ipアドレス}:/home/ec2-user/schema.zip ./
```

Zipファイルを展開し、index.htmlをブラウザで開く

![スクリーンショット 2021-08-24 17.42.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142839/cb06f672-d497-5863-437a-d68e9ba6763a.png)


# 各コード

なるべくシェルでよしなににしたかったので、Gitsでまとめてみた

`install_docker.sh`: EC2上にDockerを入れる

[https://gist.github.com/kaionn/96056d2033d2b4ce409616e526a18388](https://gist.github.com/kaionn/96056d2033d2b4ce409616e526a18388)

`create_schema.sh` : SchemaSpyを用いてSchemaデータを作り、Zip化する (変数入力必須)

[https://gist.github.com/kaionn/4d15cbc7ba40e54699c548c84d6cbc31](https://gist.github.com/kaionn/4d15cbc7ba40e54699c548c84d6cbc31)

`download_schema.sh`:ローカル上からSchemaデータをカレントディレクトリにDL・解凍・index.htmlを展開するところまでやってくれる

[https://gist.github.com/kaionn/a796f63811ea5d49b3e30faa2eec0c593](https://gist.github.com/kaionn/a796f63811ea5d49b3e30faa2eec0c59)

# 参考サイト

[DockerでサクッとDBからER図を作成する - Qiita](https://qiita.com/kamukiriri/items/ab1669c19831c18db9ee)
[【SchemaSpy】手間をかけずにRDS(MySQL)からER図を生成したい - Qiita](https://qiita.com/maika_kamada/items/c23c2a3717168c3b8e7a)
[Docker でサクッと MySQL 8 からER図を作成する - Qiita](https://qiita.com/ngyuki/items/4efa0734e8d8582bfc16)
8-Elasticsearchのインストール及び設定　X-Packのライセンス登録

過去にはてなブログへ投稿した記事になります

# はじめに
Elasticsearchは基本的に無料です。
X-Packについては有償版があり、購入をするとライセンスが発行されますので登録をする必要があります。

# 製品版ライセンスのダウンロード
製品版ライセンスはサポートに登録したメンバーのメールアドレス宛にURL情報が送付されますので、そこからライセンスファイル(jsonファイル)のダウンロードを実施します。
※有償版の購入をすると、メールアドレスの登録が求められます。（メーリングリスト可）

# ライセンスの登録
ライセンスの登録方法はBASIC(無償版)と有償版の違いはありません。
事前にライセンスファイルをElasticsearchサーバにアップロードしてください。
※本手順ではRHEL#3の/root直下にアップロードした前提で記載をします。

```
# curl -XPUT -u elastic 'http://192.168.0.3:9200/_xpack/license?acknowledge=true' -H "Content-Type: application/json" -d @/root/ライセンスファイル名.json

{"acknowledged":true,"license_status":"valid"}
```

【ポイント】
　Elasticsearch6系からPUTの際は「 -H "Content-Type: application/json"」をAPI内に入れる必要があります。

# ライセンスの確認

下記のAPIを発行することでライセンスの確認ができます。

```
# curl -XGET 'http://192.168.0.3:9200/_xpack/license'
{
  "license" : {
    "status" : "active",  <================= 「active」であることを確認
    "uid" : "UIDが表記される",
    "type" : "gold", <=================== 購入した製品と合致しているか確認
    "issue_date" : "ライセンス有効日",
    "issue_date_in_millis" : 1518998400000,
    "expiry_date" : "ライセンスの期限日", <===== 基本1年更新なのでライセンスの期限日を確認します
    "expiry_date_in_millis" : 1550620799999,
    "max_nodes" : 8, <================== Master及びDataノードが対象で、総数以上であることを確認します
    "issued_to" : "登録者名",
    "issuer" : "Web Form",
    "start_date_in_millis" : 1518998400000
  }
}
```
ハッカソン情報（持続可能な未来のためのハック）


# 持続可能な未来のためのハック
Esri という会社と TechCrunch 主催のハッカソンがオンラインで開催されています。
日程は、2021年8月23日～9月13日 です。

https://hack-for-a-sustainable-future.devpost.com/

日本からの参加者はまだいないようなので日本からも参加してほしい。
自分は関係者なので参加できないですが、サポートする形で参加したい。

アイデアやデータとして以下のサイトが参考になりそうです。
https://coronavirus-esrijapan-ej.hub.arcgis.com/


## 入賞は以下の通り
第1位
$10,000. さらに、1位のチームにはTechCrunch Disrupt 2021へのチームパスが与えられ、世界中から集まった1万人以上のインフルエンサーの前でアプリを発表することができます。また、フィーチャード・ユーザー・プレゼンテーションと2022年のEsri Developer Summitへのチーム参加が無料となります。

第2位
$6,000. さらに、2位にはTechCrunch Disrupt 2021へのチームパスが与えられます。

第3位
$2,500. さらに、3位にはTechCrunch Disrupt 2021へのチームパスが与えられます。

## 提出条件
- こちらのDevPostにあるプロジェクト投稿フォームに記入してください。
- プロジェクトのソースコードへのリンク（GitHubリポジトリなど）。
- プレゼンテーション・ビデオを撮影し、YouTubeやVimeoなどの動画共有サイトにアップロードする。
- プロジェクトの最終提出物は、3分以上5分以下の長さで作成してください。
- アイデアを提示し、それが持続可能な未来にどのように適用されるのか、なぜそれが重要なのか、どのように対象者に訴えるのかを説明する。
- どのような技術を使用したかを含め、どのようにソリューションを構築したかの概要を説明する。
- 動作するアプリケーションのデモを含める
- DevPostにプロジェクトを提出する際に、ビデオを添付する。
MySQLが起動失敗による500エラーの解消

## 背景

ポートフォリオでMySQLを使用しているが、何故か自動で落ちてしまい500エラーがブラウザに表示されてしまう場合がある。

前提として、Nginx, Pumaの起動確認をするも問題なし。

## 対症療法

### 発生したエラー

ポートフォリオのURLにアクセスすると 500エラーが発生。

### 原因

本番環境のMySQLが起動失敗していた。
根本原因に対してはもっと下の「そもそもの根本改善」を御覧ください。

### 確認方法

sshでEC2インスタンスにログインしてから以下のコマンドでMySQLの確認

```:ターミナル
$ sudo service mysqld status

Redirecting to /XXXXX status mysqld.service
● mysqld.service - MySQL Server
   Loaded: loaded (/XXXXX/mysqld.service; enabled; vendor preset: disabled)
   Active: failed (Result: exit-code) since 日時
（略）

Stopped MySQL Server.
XXXXXXXXXX: Starting MySQL Server...
XXXXXXXXXX: mysqld.service: main process ...E
XXXXXXXXXX: Failed to start MySQL Server.
XXXXXXXXXX: Unit mysqld.service entered f....
XXXXXXXXXX: mysqld.service failed.
```

`Active: failed`になっているとMySQLが死んでる状態。


```:ターミナル
$ sudo service mysqld start
```
MySQLを起動すると改善。

## そもそもの根本改善

ググりまくっていると、<b>MySQLのメモリ</b>と<b>swap領域</b>の記事が出てくる。


### 1. MySQLのメモリ消費

この問題の対応は、 table_definition_cacheの値を変更する。

これは「定義キャッシュに保管できるテーブル定義の数」を定義するものです。
最小400~最大2,000で設定可能です。

参考: [MySQLドキュメント『table_definition_cache』](https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_table_definition_cache)

topコマンドでみると、以下のような感じで40%くらいメモリが消費されていた。

```
 PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND
 XXXX mysql     20   0 1389240 409792  30776 S  0.3 40.7   0:02.11 mysqld
```

```terminal:MySQLにログイン
$ mysql -u root -p
```

以下のコマンドで設定の確認。
デフォルトなら2,000(最大)になっていると思います。

```terminal
mysql> show variables like 'table_definition_cache';
```

値を以下のコマンドで変更しましょう。
変更後、`show~`コマンドで値が変更されていればOKです。

```terminal
mysql> SET GLOBAL table_definition_cache=400;
```

```:変更後
  PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND
 XXXX mysql     20   0 1376992 389860  31404 S  0.3 38.7   0:03.24 mysqld
```
うーん、あんまり変わっていないような。。。いや、少しは改善、、したのか、、？
まあ、ポートフォリオなのでそんなにテーブル数ないし、とりあえずは意味があったと思う！


2. swap領域の確保

<b>swap領域</b>とは、使っていないメモリの内容を一時的に保管しておく場所です。
参考: [「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典](https://wa3.i-3-i.info/word1721.html)

どうやらその他の記事的にこちらが原因のようです。

ec2インスタンスにログインし、`free`コマンドで見てみましょう

```
[xxxx@xxxx ~]$ free
              total        used        free      shared  buff/cache   available
Mem:        1006892      671264       65920         680      269708      180784
Swap:             0           0           0
```

この通り、swap領域がないので、以下の記事を参考に設定しましょう。

[AmazonAWSで、MySQL がよく落ちる？ そんな時はSWAP領域をチェック！](https://qiita.com/madaran0805/items/ae0532a7436e1c684e72)


経過観察

1週間経過...MySQLが全く落ちなくなりました！


## まとめ

【まずは以下を確認】
- error 500はWEBサーバー側の原因で引き起こされるもの
-　ポートフォリオが急に落ちたらサーバー周り(WEB/アプリサーバー, DB)をチェックしよう
-　Nginx, Puma, MySQLの起動ができているか確認しよう

【MySQLが原因の場合】
- メモリ消費を確認
- swap領域を確認

## 参考記事

- [MySQL公式ドキュメント](https://dev.mysql.com/doc/)
- [MySQLでtable_definition_cacheの値を変更する](https://blog.ybbo.net/2015/12/26/change-table_definition_cache-on-mysql/)
Pandas-Profiling

# 使用データ
### Kaggle(House Prices - Advanced Regression Techniques)
https://www.kaggle.com/c/house-prices-advanced-regression-techniques

```py
train_data = pd.read_csv("train.csv")
```
![スクリーンショット 2021-08-25 9.43.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1903093/a3bc39ab-103c-eb3e-b034-0c810b6167fd.png)

# Pandas-Profiling
### モジュールのインストール&インポート

```py
!pip install pandas-profiling
```

```py
import pandas_profiling as pdp
```

### Pandas Profiling Report の実施

```py
#2分ぐらいかかる
pdp_file = pdp.ProfileReport(train_data, title="Pandas Profiling Report")
```
![スクリーンショット 2021-08-25 9.50.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1903093/8f6d2d07-8f4e-d64b-bb18-3fd3c7ccc22f.png)

```py
#htmlやjsonファイルとして出力可
pdp_file.to_file("pdp_file.html")
```

###widget

```py
#実行時間が長くて試してはいない(1時間半くらい回しても終わらなかった)
pdp_file.to_widgets()
```

#あとがき
重たい処理になるとは思いますが、簡単に可視化できますし、htmlファイルにも書き出せるので非常に便利です。
個人的には最初にデータを確認し、仮説を立てることに使えるのではないかと思っています。
さすがに最終的なアウトプットにはmatplotlibやseabornを使う必要ありそうです。