OmniAICreator/Qiita-1.07M huggingface dataset:
【Rails】ActiveRecord::ConnectionNotEstablished を解消する

### 1.はじめに
railsでアプリを作成し、サーバーを立ち上げ`rails s`を行い、`http://localhost:3000/XX`にアクセスしました。
すると、`ActiveRecord::ConnectionNotEstablished`と表示されました。

### 2.使用環境
* mac.os バージョン10.15.6
* Ruby 2.6.6
* Rails 6.0.3.5
* psql (PostgreSQL) 12.6

### 3.実際のエラー
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689555/e053763d-43dc-3bfa-8df0-1d8cc52843f5.png" alt="ActiveRecordのエラー" size="500">

### 4.試したこと

#### 4.1 データベースの確認

```error.rb
# 利用可能な全てのデータベースを一覧表示する
hogehoge@hogenoAir sample_app % psql -l
psql: error: could not connect to server: No such file or directory
        Is the server running locally and accepting
        connections on Unix domain socket "/tmp/.s.PGSQL.5432"?
```

#### 4.2 postmaster.pidの削除

```
hogehoge@hogenoAir sample_app % rm /usr/local/var/postgres/postmaster.pid
```
こちらを試すと、うまくいきました。

##### 補足 /usr/の場所
macの場合、Finderの移動タブから、`フォルダへ移動`を選択し、`/usr/`と入力すると表示されます。

#### 4.3 データベースを起動させているか確認する

```
# 起動
hogehoge@hogenoAir sample_app % pg_ctl -l /usr/local/var/postgres/server.log start
waiting for server to start.... done
server started
# 停止
hogehoge@hogenoAir sample_app % pg_ctl stop
waiting for server to shut down.... done
server stopped
```

起動するとエラーが解消されました。


### 5.まとめ
今回は[リンクの5番](https://techracho.bpsinc.jp/hachi8833/2017_12_21/48661)に近い状況で、
① パソコンがフリーズ
② 全て保存・終了して再起動
③ 表題のエラーが表示される　...という流れでした。

②で全て終了していたはずが、うまく終了されなかったようです。
傷がついてしまった`postmaster.pid`を削除することで、解決できました。


### 6.参考リンク
1:[PostgreSQL 9.1.5文書](https://www.postgresql.jp/document/9.1/html/app-psql.html)
2.[Postgresqlに接続できなくなった時](https://qiita.com/ms2sato/items/a0f7d32a3ecda76a7be3)
3.[Postgres could not connect to server](https://stackoverflow.com/questions/13410686/postgres-could-not-connect-to-server)
4.[【Mac】Finderから /usr / local ディレクトリを参照する](https://pointsandlines.jp/env-tool/mac/usr-pass)
5.[Mac+HomebrewでPostgreSQLが起動しない場合の対応](https://techracho.bpsinc.jp/hachi8833/2017_12_21/48661)

### 7.最後に
記事の感想や意見、ご指摘等あれば伝えていただけるとありがたいです。
読んでいただき、ありがとうございました。
【Django】Cloud9でSQLIte3のアップデート

AWS Cloud9で　ライブラリを色々アップデートしていると以下に遭遇。

```
django.core.exceptions.ImproperlyConfigured: SQLite 3.8.3 or later is required (found 3.7.17).
```

というエラーが出たのでアップデートをする方法

参考：https://qiita.com/rururu_kenken/items/8202b30b50e3bfa75821

```
# SQLite3を最新化する
# ソースを取得 (ホームディレクトリで実行してます)
$ cd

# バージョンは「https://www.sqlite.org/download.html」で確認して、
# 新しいバージョンのファイル名を指定してください (2019/12/06追記)
# 例) SQLite 3.31.1の場合

$ wget https://www.sqlite.org/2020/sqlite-autoconf-3310100.tar.gz
$ tar xvfz sqlite-autoconf-3310100.tar.gz

# ビルドしてインストール
$ cd sqlite-autoconf-3310100
$ ./configure --prefix=/usr/local
$ make
$ sudo make install
$ sudo find /usr/ -name sqlite3

# コマンド結果
# /usr/lib64/python2.7/sqlite3と/usr/lib64/python3.7/sqlite3はディレクトリ
/usr/bin/sqlite3
/usr/lib64/python2.7/sqlite3
/usr/lib64/python3.7/sqlite3
/usr/local/bin/sqlite3

# 不要なファイル、ディレクトリ削除
$ cd 
$ rm sqlite-autoconf-3310100.tar.gz
$ rm -rf ./sqlite-autoconf-3310100

# バージョン確認
$ /usr/local/bin/sqlite3 --version

3.31.1 2020-01-27 19:55:54 3bfa9cc97da10598521b342961df8f5f68c7388fa117345eeb516eaa837bb4d6

$ /usr/bin/sqlite3 --version

3.7.17 2013-05-20 00:56:22 118a3b35693b134d56ebd780123b7fd6f1497668

$ sqlite3 --version

3.31.1 2020-01-27 19:55:54 3bfa9cc97da10598521b342961df8f5f68c7388fa117345eeb516eaa837bb4d6

$ sudo mv /usr/bin/sqlite3 /usr/bin/sqlite3_old
$ sudo ln -s /usr/local/bin/sqlite3 /usr/bin/sqlite3

# 共有ライブラリへパスを通す
# vi ~/.bashrcで設定を追加(すぐに反映する場合 source ~/.bashrc)しないとターミナルを起動するたびに実行することになります
$ export LD_LIBRARY_PATH="/usr/local/lib"

# PythonのSQLite3バージョン確認
$ python
Python 3.7.4 (default, Dec 13 2019, 01:02:18) 
[GCC 7.3.1 20180712 (Red Hat 7.3.1-6)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import sqlite3
>>> sqlite3.sqlite_version
'3.31.1'
>>> exit()
```
Prometheus Pushgateway に プログラムからメトリクスをpushする [Text format編]

## 概要

Pushgateway にプログラムからメトリクスをpushする方法を紹介します。

push可能なメトリクスのフォーマットは`Text`と`Protocol buffer`の2種類あります。
本記事では`Text`フォーマットでpushする方法を紹介します。

`Protocol buffer`フォーマットでのpushについては以下記事をご参照ください。
[Prometheus Pushgateway に プログラムからメトリクスをpushする [Protocol buffer編]](https://qiita.com/loftkun/items/80b81ad340fd93aafdec)

## 各言語向けライブラリ

「Prometheus」のクライアントライブラリに「Pushgateway」へのメトリクスpushメソッドがしれっと実装されていますので若干盲点ですが、各言語向けのライブラリがあります。
以下ドキュメントで紹介されています。

- [Pushing metrics | Prometheus](https://prometheus.io/docs/instrumenting/pushing/)

サンプルコードも記載されているので取り入れやすいです。
通常は上記のライブラリを使うのが良いと思います。

以下は車輪の再発明をしたい方向けの情報です。
メトリクスをPOSTする処理を実装するだけなのでわざわざライブラリ使わなくても、、という方には参考になるかも知れません。

## Prometheus Client Data の仕様

以下ドキュメントにPrometheus Client Dataのフォーマットが記載されています。

- [Prometheus Client Data Exposition Format - Google ドキュメント](https://docs.google.com/document/d/1ZjyKiKxZV83VI9ZKAXRGKaUKK2BIWCT7oiGBKDBpjEY/edit)

POSTリクエスト送信処理を実装するには、リクエストボディの最後に改行(空行)を付与することに気をつけると良いです。
この仕様については`The last line must end with a line-feed character.`と記述されています。

最後に改行がないとレスポンスコード`400 Bad Request`が返り、レスポンスメッセージは `text format parsing error in line 1: invalid metric name\n` となっていました。

## curl によるPOST手順の確認

[README.md](https://github.com/prometheus/pushgateway)に以下のように記載されています。
このcurlコマンドで送信されるPOSTリクエストと同じPOSTリクエストをプログラムで生成することを考えると良さそうです。

```sh
  cat <<EOF | curl --data-binary @- http://pushgateway.example.org:9091/metrics/job/some_job/instance/some_instance
  # TYPE some_metric counter
  some_metric{label="val1"} 42
  # TYPE another_metric gauge
  # HELP another_metric Just an example.
  another_metric 2398.283
  EOF
```

以下、サンプルコードです。

## Pythonによるメトリクスpush処理の実装例

```python
import requests
import textwrap

def push():
    some_metric = 42
    another_metric = 2398.283
    data = textwrap.dedent('''
        # TYPE some_metric counter
        some_metric{label="val1"} {some_metric}
        # TYPE another_metric gauge
        # HELP another_metric Just an example.
        another_metric {another_metric}
        '''.format(some_metric=some_metric, another_metric=another_metric ))  # 最終行に改行を入れないと400が返るので注意
    res = post(data)


def post(data):
    headers = {'Content-Type': 'application/x-www-form-urlencoded'}
    res = requests.post(
        "http://pushgateway.example.org:9091/metrics/job/some_job/instance/some_instance", headers=headers, data=data)
    if res.status_code != 200:
        raise Exception("failed : {}".format(res.status_code))
    return res
```

なお、curlコマンドによるPOSTリクエストヘッダは、`Content-Type` が `application/x-www-form-urlencoded` でしたので、このプログラムでも合わせていますが、この指定は特になくても良いようです。
[Unity3D] ゲームデザインの作成

1, PCのペイント機能を使いゲームデザインを考えて書き出す

2, aseet内にドラッグする
![48B6CCA7-7EC5-42E0-A7BD-B2D0E92A21B6_4_5005_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940521/f97413b7-e4c1-a648-100f-df0a7adcf199.jpeg)

3, Materialを作成し、Albedoを選択し、ペイント画像を選択する
![4CC8AE05-0795-4E05-9333-BD23C0B56D8E_4_5005_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940521/30baf60f-32ff-0ff4-7673-23ef20fd0b97.jpeg)

4, ヒエラルキーにQuadを作成し、sizeを５０、５０、５０に変更する
![49562100-AF68-453F-8A8E-E3EA520886B3_4_5005_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940521/df2baf26-8799-7ed9-5a53-7e35c9ee24f8.jpeg)

5, MaterialをQuadにドラッグし、ShaderをUnit→Textureにする
![403EDC03-EF2E-4C22-AD94-C119ADE58080_4_5005_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940521/a68c80b8-4155-68a1-51e8-ceac6e3b7768.jpeg)
VAE极简解析： 摆脱概率论的幽灵

### 前言

AE = Autoencoder
VAE = Variational Autoencoder

本文假定读者拥有AE的知识。从直观上，我们可以把AE理解成一个压缩器，事实上据我所知谷歌就有用AE来压缩文件，效率非常之高。

AE的缺点是： 不同的输入被映射到潜在空间中离散的点，点与点之间没有任何联系，白白浪费了大片的潜在空间，如下图。

而VAE的引入恰恰是为了填补点与点之间的真空。为了达到这一目的，只需要简单的两步操作，下面逐一解析。

#### 扩大离散点范围

为了填补点与点之间的真空，很简单，扩大离散点的范围就可以了。那么，要怎么扩大一个点的范围呢？答案就是引入随机扰动，如下图：

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227568/47905284-89bd-0e7d-4877-8ed198ae9bd8.png)

上帝赐予我们的随机数，将初始手枪变成了散弹枪。

关于VAE的解释，我强烈推荐一篇博客：《Intuitively Understanding Variational Autoencoders》。谷歌一下就能找到，在我找到窍门之前花了很长时间翻了许多博客，这篇绝对是讲的最好的（写有Intuitive的总是好的）。

可是几乎所有人，都遵循原论文的步骤引入随机数——使用mean和varian来模拟概率分布。这就是使用VAE的最大门槛。

事实上，要使用随机数可以很简单——直接使用随机数就好了，没必要人为模拟概率分布，随机数本身就是符合正态分布的。示例代码如下，效果完全符合上图。

```py
def add_disturbance(self, z):
  epsilon = torch.randn(z.shape)
  return z + epsilon
```

可是，加入随机变量之后，各个点还是可以分的很开，因为潜在空间是无限大的，在没有加入限制的情况下，各个点没有理由聚合到一起，所以我们必须引入下一步，也是最后一步：

#### 聚合离散点

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227568/e94625ee-bd98-c8cb-e386-0d74ebba95f6.png)

如上图所示，左边是我们想要的，可是如果没有聚合限制，经过步骤一我们只能得到右图的结果。

那么怎么才能聚合离散点呢？ 很简单，我们只要引入一个锚点就好了。这个锚点可以是潜在空间的任意一个点，直接用torch.randn就能得到——或者，我们可以直接用坐标原点。接下来我们可以计算各个点到锚点的距离，将这个距离定义为我们的loss，接下来只要减小loss就好了。事实上唬人的KL Loss做的正是这样一件事。

```py
KL = z.pow(2).sum().sqrt() # Force z decay to zero
```

如果只有KL loss，各个点只要落到原点就完事了，这不是我们想要的，可是因为我们还有重建Loss（不要忘了，这是AE的主要目标），只要将两个loss加起来一起优化，就会达到一个平衡。

这就是VAE。

再说说重建Loss，原论文的重建Loss也显得非常吓人，所以下面我再将重建loss简化一下作为收尾。

#### 简化重建Loss

```py
# Pre define
self.MSE = nn.MSELoss(reduction='sum') # Sum is important
# ...
# x from input
z = self.get_z(x)
y = self.get_y(z)
reconstruction = self.MSE(y, x)
# sum up loss
loss = reconstruction + KL
```

以上就是VAE。

以下是结果示意图。第一行是原图，第二行是重建后的图，第三行是第一个数字到第二个数字的变迁图。

![dd.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227568/9371a39e-ae85-d46a-c80d-e59d91606e69.png)


我们可以看到要实现VAE根本不需要概率论，少一点概率论，我们能够活的更好。我将这个实现命名为poor man's VAE，如果有人在论文里用到了这个实现，请至少告知我，谢谢。

#### 代码

代码托管在github: https://github.com/zhuobinggang/poor-man-VAE 主要部分如下：

```py
class My_VAE_V2(nn.Module):
    def __init__(self, z_dim):
      super().__init__()
      self.fw1 = nn.Linear(28*28, 28*14)
      self.z_layer = nn.Linear(28*14, z_dim)
      self.fw2 = nn.Linear(z_dim, 28*14)
      self.recover_layer = nn.Linear(28*14, 28*28)
      self.MSE = nn.MSELoss(reduction='sum')
    
    def _encoder(self, x):
      z = self.add_disturbance(self.z_layer(F.sigmoid(self.fw1(x))))
      return z
    
    def add_disturbance(self, z):
      epsilon = torch.randn(z.shape)
      return z + epsilon
 
    def _decoder(self, z):
      o = F.sigmoid(self.recover_layer(F.sigmoid(self.fw2(z))))
      return o

    def forward(self, x):
      z = self._encoder(x)
      o = self._decoder(z)
      return o, z
    
    def loss(self, x):
      z = self._encoder(x)
      KL = z.pow(2).sum().sqrt() # Force z decay to zero
      y = self._decoder(z)
      reconstruction = self.MSE(y, x)
      return KL + reconstruction
```
Python AWS Lambda でmultipart/form-dataのファイルをS3にアップロードする

# Python AWS Lambda でmultipart/form-dataのファイルをS3にアップロードする

##### 概要

AWSのLambda経由でmultipart/form-dataできたものを、S3にアップロードする。

##### 小言
clientでそのままS3に送る実装や、Blob化してファイルを送信しているのはよく見るが、めんどくさいし通常のApiならmultipart/form-dataを利用する方が多く(~~多いと思ってる~~)、なんでClientがApiとLambdaで変更しないといけないか不思議に思ったため。

##### Dependent

- [multipart/form-dataをLambdaで利用する](https://qiita.com/Gma_Gama/items/858f32181ef288ba8d8d)

##### Result

- [レポ](https://github.com/Ntakuya/sam-multiple-form-data-sample/tree/feature/multipart-form)

## TL;DR

1. multipart/form-dataできたものをcgi moduleを利用してFormに変更
2. Form化したデータからresponseBodyのfield名でファイルを取得

## 0. app.pyは最初こんなイメージ

```app.py
import json

def lambda_handler(event, context):
    return {
        "statusCode": 200,
        "body": json.dumps({
            "message": "hello world",
        }),
    }

```

## 1. multipart/form-dataできたものをcgi moduleを利用してFormのデータに変更


```app.py
import json
import cgi
import io 
import logging # これは個人的に入れているのでほっておいていい
import base64

def get_file_from_request_body(headers, body):
    fp = io.BytesIO(base64.b64decode(body)) # decode
    environ = {"REQUEST_METHOD": "POST"}
    headers = {
        "content-type": headers["Content-Type"],
        "content-length": headers["Content-Length"],
    }

    fs = cgi.FieldStorage(fp=fp, environ=environ, headers=headers) # FieldStorageを利用してForm Dataとして扱う

def lambda_handler(event, context):
    return {
        "statusCode": 200,
        "body": json.dumps({
            "message": "hello world",
        }),
    }

```

## 2. Form化したデータからresponseBodyのfield名でファイルを取得

requestの形が以下のようになっていいる想定です。

```request.ts
{
    "file": File
}
```

```app.py
import json
import cgi
import io 
import logging # これは個人的に入れているのでほっておいていい
import base64

def get_file_from_request_body(headers, body):
    fp = io.BytesIO(base64.b64decode(body)) # decode
    environ = {"REQUEST_METHOD": "POST"}
    headers = {
        "content-type": headers["Content-Type"],
        "content-length": headers["Content-Length"],
    }

    fs = cgi.FieldStorage(fp=fp, environ=environ, headers=headers) # FieldStorageを利用してForm Dataとして扱う
    return [fs["file"], None]

def lambda_handler(event, context):
    ## ここから追記
    file_item, file_item_error = get_file_from_request_body(
        headers=event["headers"], body=event["body"]
    )
　　 ## ここまで追記
    return {
        "statusCode": 200,
        "body": json.dumps({
            "message": "hello world",
        }),
    }

```

こんな感じで適当に対応しましたが、多分もっといい書き方がある気がする...
Rails 6.0 でカラムの型を string -> integer に変更する方法

ググったら`'integer USING CAST(column_name AS integer)'`みたいなやり方がでたけどこれは古い書き方のようでエラーが出た。Rails6で上手く行ったのは下記。

```20210219164606_change_user_id_in_posts.rb
class ChangeUserIdInPlatforms < ActiveRecord::Migration[6.0]
  def change
    change_column :posts, :user_id, :integer, using: 'user_id::integer'
  end
end
```
https://stackoverflow.com/questions/3537064/rails-migration-to-convert-string-to-integer

## 役立ちそうなコマンド
ただしrollbackやマイグレーションファイルの削除は特にチーム開発ではご法度。やらないことを推奨する。

```console
# 戻したいとき
## マイグレーションのバージョン確認
$ rails db:version
## バージョンを戻す（ただし非推奨）
$ rails db:rollback step=2
$ rails db:rollback 20210219164606_change_user_id_in_posts.rb
```
ただし`change`メソッドで定義した操作のうち`remove_column`や`change_column`はrollbackすることはできない。そのときは`up`メソッドと`down`メソッドの2つ（migrateはup, rollbackはdown）にマイグレーションファイルを置き換える必要がある（`rails db:migrate`した後にマイグレーションファイルを変更して`rails db:rollback`するみたい‥怖すぎるけど）。

```ruby
class removeColumnHoge < ActiveRecord::Migration
  def change
    remove_column :hoge, :fuga
  end
end
```

```ruby
class removeColumnHoge < ActiveRecord::Migration
  def up
    remove_column :hoge, :fuga
  end

  def down
    add_column :hoge, :fuga, :string
  end
end
```
http://tanihiro.hatenablog.com/entry/2014/01/10/182122

##その他
投稿とユーザーを紐付ける場合、投稿モデルに持たせるuser_idはintegerじゃなくてreferrenceで持つべきというQiitaもあった。Progateではintegerになってたけど
Windowsデバイスドライバプログラミング　勉強記録2

__※本記事は勉強しつつ書いていますので、不正確な情報が含まれる可能性がありますので予めご了承ください。__

#Windowsデバイスドライバの変遷

①95系⇒仮想デバイスドライバ（VxD） NT系⇒NTカーネルドライバ  __まったく異なるドライバモデル__
↓
②2000(NT系)  NTカーネルをベースに__WDMを導入__
98/Me　従来の仮想デバイスドライバ＋ WDMに対応
※NT系と98/MeでWDMデバイスドライバは__ソースコードレベル互換__
↓
③XP　__WDMに統一__
↓
④Vista　WDMに加えて__WDF(Windows Driver Foundation；UMDF、KMDF)を追加__
↓
⑤7,8,10　__基本部分はVistaと同様__

<!--参考資料　

https://interface.cqpub.co.jp/wp-content/uploads/interface/2016/03/if03_064.pdf

https://e-words.jp/w/%E4%BA%92%E6%8F%9B%E6%80%A7.html#Section_%25E3%2582%25BD%25E3%2583%25BC%25E3%2582%25B9%25E4%25BA%2592%25E6%258F%259B

https://ja.wikipedia.org/wiki/Windows_Driver_Foundation

-->

#カーネル構成とモード

###カーネルモード/ユーザモード
Windowsシステム構成においてソフトウェアは管理者権限の有無によりカーネルモード/ユーザモードに分けられる
「権限」とはリソース（メモリ、周辺機器）へのアクセス権

###MMU(Memory Management Unit)
仮想メモリを空間を提供するIntel CPU機能。メモリマネージャが行う。
⇒仮想メモリ-実メモリ変換テーブルで変換を行う。
MMU変換ができなかったときに「〇〇は動作を停止しました」とメッセージが出る

ユーザモード属性のソフトウェアは仮想メモリしかアクセスできない。
デバイスドライバは外部の周辺機器とデータ通信を行うため、MMUを使用しないで実メモリにアクセスできるカーネルモードで
ある必要がある。（周辺機器は仮想メモリアドレスでアクセスできないため）

<!-- ###カーネル構成図
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1067094/46032436-b801-d49a-8071-fa679ca4c5c8.png)
-->

<!-- #デバイスドライバ開発に必要な知識

・制御対象のハードウェアについて
・上位のデバイスドライバを管理するシステム（I/Oマネージャ）の仕様を把握
・下位のバスドライバの仕様
-->

#Windowsデバイスドライバフレームワークの種類

###WDM
WDM(Windows Driver Model)
・従来からある基本的なデバイスドライバーのフレームワーク

###KMDF
KMDF(Kernel Mode Driver Model Framework): 
WDMを使いやすく定型処理をライブラリとしてより高度な機能を提供するフレームワーク
イメージとしてはWin32 APIに対するMFCのような認識。

###UMDF
UMDF(User Mode Driver Model Framework): 実際のデバイス制御をおこなうカーネル部と通信を行うことにより機能を実現する、ユーザモードのフレームワーク

・実際の実行はカーネル側のKernel Driver for UMDFで行われる
・低速
・Driver Manager提供するフレームワーク上でC++,COMで実装を行う。
・バグがあってもシステム安定性に影響を与えない

#次回から記録について
箇条書きレベルでもまとめるのは大変であるし、下手すると丸写しに近いものなってしまうのでやり方を変えます。
学習した内容を一部内容をピックアップしての記載とします。具体的には特に難しかったこと、印象に残ったこと、さらに調べたこと、気になったこと、疑問点、感想等を書ければと思います。ただ、部分的にはまとめもします。

#参考文献
[Windows Vistaデバイスドライバプログラミング ](https://www.amazon.co.jp/Windows-Vista%E3%83%87%E3%83%90%E3%82%A4%E3%82%B9%E3%83%89%E3%83%A9%E3%82%A4%E3%83%90%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0-%E6%B5%9C%E7%94%B0-%E6%86%B2%E4%B8%80%E9%83%8E/dp/4797343222)

<!-- [ASCII.jp 基礎から覚える 最新OSのアーキテクチャー 第4回 Windowsを動かすデバイスドライバーの仕組み 前編](https://ascii.jp/elem/000/000/633/633118/) -->
PHPでエラーの内容をブラウザに表示させる方法

##背景
開発するときにエラーの内容がブラウザに表示されると開発しやすいので共有します。

##サマリ
エラー内容の表示非表示の設定はphp.iniで管理されており、「display_errors=On」に設定することでエラー内容の表示が可能になります。

##設定方法（概要）
１、php.iniのdisplay_errorsをOnに設定
２、apacheを再起動

##設定方法（詳細）
０、設定前の状況を確認

```php5:index.php
<?php
//文末の「セミコロン（；）」をあえてつけずエラーにする
echo "This is study.localhost page"

```

index.phpにアクセス↓（http erroe 500は。phpエラーなどが原因のwebサーバーに起因するエラーなので、想定するエラーが出されています。）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/499617/169c1b17-a699-37cf-69f2-0820734bc87f.png)


１、php.iniのdisplay_errorsをOnに設定
①php.iniの場所を探す
　find関数でファイルの場所を探します。

```bash:
[xxx@localhost /]# find / -name php.ini
/etc/php.ini
```

②php.iniを開く

```bash:
[xxx@localhost /]# vi /etc/php.ini
```
③vi内で/display_errosを入力し該当箇所を検索
※viの検索の仕方はググってみてね

```bash:/etc/php.ini
;   On or stdout = Display errors to STDOUT
; Default Value: On
; Development Value: On
; Production Value: Off
; http://php.net/display-errors
display_errors = On
```

④保存後、apacheを再起動
※viの上書き保存方法は「/wq」
※設定ファイルのバックアップはご自由に

```bash:
[xxx@localhost /]# systemctl restart httpd
```

⑤エラーが表示されることを確認
Parse error: syntax error, unexpected end of file, expecting ',' or ';' in /var/www/html/study.localhost/index.php on line 3
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/499617/53def223-9c8c-a628-db0c-dd6db8d7f1a6.png)

3行目にエラーがあると記述があり、正しいエラーが表示されているとわかります。

```php5:index.php
<?php
//文末の「セミコロン（；）」をあえてつけずエラーにする
echo "This is study.localhost page"　//←3行目のセミコロンが無いためエラーになる

```
MCP のススメ

この記事は、[Azure Rock Star イベント](https://azurerockstar.connpass.com/event/202301/) 用です。

---

# MCP とは

Microsoft が提供する資格試験。

---

# 自己紹介

https://mcp.microsoft.com/Anonymous/Transcript/Validate

- Transcript ID: 756564
- Access Code: kenakamu

Since 2001 Aug

---

# MCP Tips

- [勉強のツールとして使う](勉強のツールとして使う)
- [費用対効果](費用対効果)
- [会場で直面するかもしれない課題](会場で直面するかもしれない課題)

---

# 勉強のツールとして使う

---

## ガイドラインとして

自分が必要な分野を網羅する目的で受ける。この場合、受ける試験と順番を決めておく。

---

## 視野を広げるツールとして

普段関わらない分野に触れる目的で受ける。この場合、先に毎月第 3 日曜日など予定を決めて置き、受ける試験は都度決める。

---

## 英語の練習として

技術系の勉強は英語が必要になることが多いので、勉強も試験も英語で受けることで、英語の文章に慣れる。

# 費用対効果

---


## 会社とまず相談
- 既に資格取得支援の仕組みがあるか
- 無い場合もあきらめず上長と相談してみる
- 部活形式で部費が出た例もある

---


## 個人で払う場合
- イベント配布の無料で受験できるバウチャーを狙う
- 2 回目受験無料イベントなどもある

---


## LinkedIn プロファイルに活用

- 取得した資格は必ず LinkedIn などのプロファイルに入れる
- ブログなどにも載せておく
- 自分のブランディングに使う（人によるが）

---

# 会場で直面するかもしれない課題

---

## モニターサイズ

### **問題**

AZ 試験では Azure ポータルの操作があるが、モニターの解像度が低いと「作成」や「はい」ボタンが隠れてしまう。

### **対策**

大体ボタンが下の方にあるので、```Tab``` キーを使ったり、マウスにスクロールロックボタンがあればそれを使う。
そこにボタンがあると知っている事が大事。

---


## ポケットティッシュ

### **問題**

会場には基本、身分証くらいしか持ち込めないので、ポケットティッシュを持ち込めない場合がある。花粉症は辛い。

### **対策**

会場で用意しているティッシュがもらえる場合がある。あとは透明な袋に入ったものは許可されたことがある。

---


## 眼鏡クリーナー

### **問題**

会場には基本、身分証くらいしか持ち込めないので、眼鏡拭きを持ち込めない場合がある。曇ったり汚れると辛い。

### **対策**

無地のものであれば文句言われることは少ないので、持ち込むなら無地。持ち込まないなら曇るかもしれない事を留意。

---


## ロッカーが狭い

### **問題**

カバンが大きいとロッカーに入らない場合がある。また荷物だけ先にいれて、直前まで必要なものは手元に置いておく。

### **対策**

PC を持っていくよりタブレットの方が無難。

---

# まとめ

MCP は必要な時に受けるより、普段から受ける方が効率も効果も高いので、まずは四半期に一度くらい受けてみてください。
パソコンとジャンケンゲーム

//じゃんけんの手の番号を設定
const GU = 1;
const CHOKI = 2;
const PA = 3;

let msgStr = '半角数字で１～３の数字を入力してください。\n\n';
msgStr += GU + ':グー\n';
msgStr += CHOKI + ':チョキ\n';
msgStr += PA + ':パー';
let hum = prompt(msgStr);
hum =parseInt(hum);
//入力値のチェック
if(hum !== GU && hum !== CHOKI && hum !== PA) {
	alert('入力値をうまく認識できませんでした。ブラウザを再読み込みすると、もう一度挑戦できます。')
} else {
	//正しい入力値の場合、コンピューターの手を作る
	let com;
	com = Math.random() * 3;
	com = Math.floor(com) + 1;
	//コンピューターの名前
	let comHandName = '';
	switch (com) {
		case GU:
			comHandName = 'グー';
			break;
		case CHOKI:
			comHandName = 'チョキ';
			break;
		case PA:
			comHandName = 'パー';
			break;
	}
	//結果の判定
	let msgResult = '';
	if(hum == com){
		msgResult = '結果はあいこでした';
	} else {
		if((com == GU && hum == PA) || (com == CHOKI && hum == GU) || (com == PA && hum == CHOKI)){
		msgResult ='あなたの勝ちです';
		} else {
			msgResult = 'あなたの負けです';
		}
	}
	//最終的な結果表示
	msgResult += 'コンピューターの出した手は「' + comHandName + '」でした。';
	alert(msgResult);
}
C# Word フィールドを更新

<p><strong>フィールドはフィールドコードと呼ばれるWordへの命令を文書内に記述するための入れ物です。Wordのフィールドを自由自在に使える方はWord上級者と呼んでも過言ではないと思います。今回はSpire.Docを使ってWord フィールドを更新する方法を紹介します。</strong></p>
<h4><strong>下準備</strong></h4>
<p><strong>1.E-iceblueの公式サイトから<a href="https://www.e-iceblue.com/Download/download-word-for-net-free.html">Free Spire.Doc for .NET</a>無料版をダウンロードしてください。</strong></p>
<p><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/l/lendoris/20210220/20210220120858.png" alt="f:id:lendoris:20210220120858p:plain" title="" class="hatena-fotolife" itemprop="image" /></p>
<p><strong>2.Visual Studioを起動して新規プロジェクトを作成してから、インストールされたファイルにあった相応しいSpire.Doc.dllを参照に追加してください。（Net 4.0を例としたら、デフォルトパスは“Bin→NET4.0→Spire.Doc.dll”というようです。）</strong></p>
<p><strong> </strong></p>
<p><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/l/lendoris/20210220/20210220122305.png" alt="f:id:lendoris:20210220122305p:plain" title="" class="hatena-fotolife" itemprop="image" /></p>
```C#
using Spire.Doc;

namespace ConsoleApplication31
{
    class Program
    {
        static void Main(string[] args)
        {
            
            Document doc = new Document();

            //ファイルテンプレートをロードします。
            doc.LoadFromFile("リスト.docx");

            //リストのデータに更新します。
            doc.Replace("a.price", "5.5", true, true);
            doc.Replace("b.price", "11.9", true, true);
            doc.Replace("c.price", "5", true, true);
            doc.Replace("a.quantity", "1", true, true);
            doc.Replace("b.quantity", "2", true, true);
            doc.Replace("c.quantity", "4", true, true);

            //フィールドを更新します。
            doc.IsUpdateFields = true;

            //保存します。
            doc.SaveToFile("output.docx", FileFormat.Docx2013);
        }
    }
}
```
<h4><strong>実行結果</strong></h4>
<p><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/l/lendoris/20210220/20210220122319.png" alt="f:id:lendoris:20210220122319p:plain" title="" class="hatena-fotolife" itemprop="image" /></p>
<p><strong> </strong></p>
<p><strong> </strong></p>
<p><strong> </strong></p>
<p><strong> </strong></p>
【備忘録】html上の改行を挿入する

# 概要
下記のようなケースの対処法

- ESLintでHTMLに直接改行したら怒られる<br/>
こんな時

```html
<div>
おはようございます。
今日もいい天気ですね
</div>
```
- Javascript側に変数用意しても直接改行しても怒られる<br/>
こんな時

```javascript

<script>
const s = 
"おはようございます。
今日もいい天気ですね"
</script>
```
- `<p></p>`で括ってもformatterで改行が解除されてしまう<br/>
こんな時

```html
<p>
おはようございます。
今日もいい天気ですね
</p>
```

# 対応
1. JavaScriptに変数を用意する<br/>
この時、改行したい時に改行文字`\n`を入れる
2. 上で生成した変数をhtmlで読み込む<br/>
この時`<p>`で囲む
3. CSSに`white-space: pre-line`を挿入

#動作
<p class="codepen" data-height="265" data-theme-id="dark" data-default-tab="js,result" data-user="ishikawa-takumi" data-slug-hash="BaQdRGe" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="改行">
  <span>See the Pen <a href="https://codepen.io/ishikawa-takumi/pen/BaQdRGe">
  改行</a> by ishikawa takumi (<a href="https://codepen.io/ishikawa-takumi">@ishikawa-takumi</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>
【Golang】文字列を固定幅（固定長）で改行する。全角文字列の WordWrap

> UTF-8 マルチバイト文字列を**全角 n 文字（半角 n*2 文字）の固定長で改行させたい**。
>
> ```text:対象文字列
> あいうえおかきくけこさしすせそたちつてと
> 123456789012345678901234567890
> ```
> ↓
>
> ```text:n=6で改行
> あいうえおか
> きくけこさし
> すせそたちつ
> てと
> 123456789012
> 345678901234
> 567890
> ```

大前提として、<font color=darkorange>**等幅フォントでない限り、画面上で「`全角 1 文字 == 半角 2 文字`」の文字幅にならないのは当然**</font>として、それでも CLI アプリやコマンドのヘルプ表示など、なるべく等幅（1 行が固定長）になるように折り返したいのです。

つまり Golang の `WordWrap` がしたい。

しかし[「"golang" 文字列 固定幅 改行」でググって](https://www.google.com/search?q=%22golang%22+%E6%96%87%E5%AD%97%E5%88%97+%E5%9B%BA%E5%AE%9A%E5%B9%85+%E6%94%B9%E8%A1%8C)も、なかなかヒットしなかったり、ルーンをゴニョゴニョしろとは言うもの具体的なものがなかったので、自分のググラビリティとして。

## TL; DR <sub><sup><sub><sup>（今北産業）</sup></sub></sup></sub>

1. <code>[github.com/mattn/go-runewidth](github.com/mattn/go-runewidth)</code> パッケージの `runewidth` を使う。 `go-runewidth` は @mattn さんによる [awesome-go](https://github.com/avelino/awesome-go#text-processing) なパッケージです。
2. <code>[runewidth.Wrap(s string, w int) string](https://pkg.go.dev/github.com/mattn/go-runewidth#Wrap)</code> メソッドで文字列 `s` を `w` 文字幅で改行した文字列が取得できる。
3. 全角 3 文字の場合は `result := runewidth.Wrap(myString, 3 * 2)` と 2 倍にする。

## TS; DR

```go:sample.go
package main

import (
	"fmt"
	"strings"

	"github.com/mattn/go-runewidth"
)

// WrapZenkakuString は文字列を固定幅で折り返します。幅の指定（width）は全角文字数を指定します。
// 半角文字は、その倍の文字数で折り返されます。主にヘルプ表示などに使われ、フォントによっては必ずし
// も固定幅になるとは限りません。
func WrapZenkakuStringSample(input string, width int) string {
	replacer := strings.NewReplacer(
		"\n", "",
		"\r", "", // Windows
		"。", "。\n",
	)

	replaced := replacer.Replace(input)

	return runewidth.Wrap(replaced, width*2)
}

func main() {
	var msgHelp string = `
これはサンプルのヘルプです。
アイウエオかきくけこサシスセソたちつ
てとナニヌネコ。`

	fmt.Println(WrapZenkakuString(msgHelp, 6))
}

```
```shell-session:実行結果
$ go run .
これはサンプ
ルのヘルプで
す。
アイウエオか
きくけこサシ
スセソたちつ
てとナニヌネ
コ。
```

- [オンラインで動作をみる](https://play.golang.org/p/O1jPEfhdWS1) @ Go Playground
- [オンラインでテストをみる](https://play.golang.org/p/9lYi9Lv014E) @ Go Playground

### 参考文献

- [Text Processing](https://qiita.com/tashxii/items/52cfd2a36eadc7b225c0#text-processing) | Awesome-go(golangのライブラリリスト)のスター数まとめ-全部編(2018/10/9版) @ Qiita
- [awesome-go](https://github.com/avelino/awesome-go#text-processing) @ GitHub
- [Goでマルチバイトが混在した文字列を文字幅でtruncateする](https://qiita.com/mattn/items/df8faba2abadab2eee51) @ Qiita
- [コメント](https://qiita.com/dai2k/items/350b705edf34b9cf6c3d#comment-d7eac429b914301527c2) | Golang で指定した幅で文字列を丸める方法 @ Qiita

### 関連文献

- `github.com/mattn/go-runewidth`
    - リポジトリ: https://github.com/mattn/go-runewidth @ GitHub
    - API ドキュメント: https://pkg.go.dev/github.com/mattn/go-runewidth @ pkg.go.dev
    - ライセンス: [MIT](https://mattn.mit-license.org/2013)
Pardot のプロセスオートメーション (Salesforce Classic) ⇒ オートメーションルールの使用

１．一致するプロスペクトを継続的に検索するオートメーションルールは、どのような自動化に適していますか?
２．オートメーションルールの次の演算子のうち、完全一致を要するものはどれですか?
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634241/e191fd82-afe0-afe5-0d43-986f0e89a562.png)
Jetson Nanoの動画録画サンプル "10_camera_recordings"を実行した際のメモ

# 要約
Jetson nanoにて、JetPack SDKに含まれているサンプル "10_camera_recordings"を実行した際、実施したことを記載します

# 前提
Jetson本体: Jetson Nano 4G
jetpack： jetpack 4.3-b134
カメラ: Sony IMX219

なお、カメラは、/dev/video0 として自動で認識済

# 実施内容
Jetsonにログインし、以下のサンプルフォルダに移動するか、サンプルフォルダをコピーする
/usr/src/jetson_multimedia_api/samples/10_camera_recordings/
ここでは、サンプルフォルダに移動して実行

ビルドする
sudo make all

実行する
sudo ./camera_recording 

オプション等を指定しない場合は、以下の設定で動画ファイルが作成される
ファイル名: output.h264
録画時間: 5 秒

■ビルド時にエラーが発生した場合
以下のビルドエラーが出る場合は、ライブラリv4lsがインストールされていないため、後述する回避策を実施し再度ビルドする

■ビルドエラー
/usr/bin/ld: cannot find -lv4l2

■回避策
ライブラリv4l2をインストールする
sudo apt-get install lv4-utils

ライブラリv4l2がインストールされたディレクトリを確認する
ldconfig -p | grep v4l2
ここでは、仮に、以下にライブラリがインストールされたと仮定
/usr/lib/aarch64-libx-gnu/libv4l2.so.0

ビルド時に参照する"libv4l2.so"が /usr/libにない場合は、以下のコマンドでシンボリックリンクを作成する
sudo ln -s /usr/lib/aarch64-libx-gnu/libv4l2.so.0 /usr/lib/libv4l2.so
BridgePointのMac版は壊れている？

Mac版のBridgePoint（BridgePoint.app）を起動しようとしたら、
> 「Eclipse.app は壊れているため開けません。ゴミ箱に入れる必要があります。」

というメッセージが表示されて起動できないという現象が生じました。


![sc_2021-02-20_10.30.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3221/49600a72-898c-ddc1-1fbc-2624b2209cd3.png)

調べてみたところ、下記のような記事が見つかりました。

* [Mac で「壊れているため開けません。 ゴミ箱に入れる必要があります。」と弾かれたときの対処法とは？](https://dyny001.net/mac-broken-file/)
* [【Mac】Eclipse.app は壊れている？](https://qiita.com/cannot_any_more/items/af1fce11640a8fdd0027)
* [Mac 版 Eclipse Pleiades All in One リリース](https://qiita.com/cypher256/items/233795f4fc58a704ee47)



内包するファイルに変更があった状態で起動すると、MacのGatekeeperが働いてくれ、書き換えられたアプリケーションかもしれないというチェックに引っかかってしまうようです（そのような働き自体は悪いことではないです）。

これら記事の指摘通り、次の対処を実施したところ動作するようなので、同じ現象に遭遇したらこの方法を試してみてください。

対処の概要（詳しい手順は各記事を参照してください）：

* Gatekeeper を一時的に停止させて全てのアプリケーションのインストールや実行を許可した状態でBridgePointを実行してみる（そのあとで許可は禁止に戻すしておく）。
* xattr属性を削除する
Beautifulsoupを使ってJリーグの順位表をcsvファイルに出力

<h1>beautifulsoupを使ってJリーグの順位表をcsvファイルに出力</h1>

<h2>最終目標</h2>
最終的には機械学習を使って勝敗予想をするものを作りたいと思っています。

<h2>今回行うこと</h2>
Jリーグの公式サイトにある過去の順位のデータを取得します。

<h2>importするモジュールたち</h2>
```
#WEB上のデータ(HTML)にアクセスするために使用
import urllib
#HTMLからデータを抽出するために使用
from bs4 import BeautifulSoup
#表形式でデータ格納するために使用
import pandas as pd
```

<h2>beautifulsoupのインスタンスを生成</h2>
```
url = 'https://data.j-league.or.jp/SFRT01/?competitionSectionIdLabel=%E7%AC%AC%EF%BC%91%E7%AF%80&competitionIdLabel=%E6%98%8E%E6%B2%BB%E5%AE%89%E7%94%B0%E7%94%9F%E5%91%BD%EF%BC%AA%EF%BC%91%E3%83%AA%E3%83%BC%E3%82%B0&yearIdLabel=2019%E5%B9%B4&yearId=2019&competitionId=460&competitionSectionId=1&search=search'
html = urllib.request.urlopen(url)
soup = BeautifulSoup(html, 'html.parser')

```
今回取得するのは2019年第一節のデータです。
Beautifulsoupのインスタンスはそのページのhtmlが入っています

<h2>ファイル名を決める</h2>
```
#ファイル名の取得
h3 = soup.find_all('h3', class_='standings-title')[0]
filename = h3.get_text().strip() + '.csv'

```

<h2>データの取得</h2>
```
#データ格納用
headData = []
teamData = []

for i, row in enumerate(rows):
    #一行目
    if i == 0:
        for headerValue in row.find_all('th'):
            headData.append(headerValue.get_text())
        #最初と最後から三つを削除
        del headData[0]
        del headData[-4:]
            
    elif(i > 0) and (i  < len(rows)):
        #明細部取得
        teamrow = []
        for teamValue in row.find_all('td'):
            text = teamValue.get_text()
            teamrow.append(text.strip())#\nや\rを削除
        #最初と最後から三つを削除
        del teamrow[0]
        del teamrow[-4:]
        teamData.append(teamrow)

```
文字列データのstrip()メソッドは\nとか空白とかを削除してくれます

<h2>csvファイルに出力</h2>
```
#表にする
df = pd.DataFrame(data = teamData, columns = headData)

df.to_csv(filename, sep = ',', header = True, index = False, encoding='utf_8_sig') #ファイルに出力
```
encodingを指定しないと文字化けするので注意してください

<h2>終わりに</h2>
初めてquitaの記事を書いたので難しかったです（笑）
これからも自分のoutputを書いていくので参考になれば幸いです
【拡張子別まとめ】フォントの拡張子っていろいろあるけど結局どれがどういいの？

制作するにあたりWebフォントを使う。
よくある場面だと思いますが、じゃあどうやって何を導入するのか？を決めたい。
何を基準にどう選ぶのがいいのかがフワッとしていたのでメモとして残したいと思います。

## 拡張子別の特徴

ざっくり理解だとこんな感じです。

### ttf
- TrueTypeフォントベースの形式
- 歴史が古く、広く普及しているフォント形式
- 対応環境も多い

### otf
- フォント界のトレンド
- ブラウザ上でWebフォントとして利用することもできる
- TrueTypeフォントとPostScriptフォントの技術を統合して作られた新しいフォント形式
- TrueTypeフォントに比べて膨大な収録字体数、合字機能、異体字の制御、柔軟な文字詰めと機能が多い
- OpenTypeフォントの字形をSVG画像形式で表現しているフォント形式
- 「カラーフォント」とも呼ばれ、複数カラーや筆で書いたような濃淡、模様、グラデーションが表現できる

### ttc, otc
- フォントコレクションとも呼ばれ、複数のTrueTypeフォントを一つのファイルにまとめたもの
- OpenTypeをまとめた物で「.otc」という仕組みもあるけどのOpenTypeでも「.ttc」が使われることがある

### eot, woff, woff2
- Webフォントには、TrueTypeフォントやOpenTypeフォントも使える
- ブラウザによって対応しているフォント形式は異なる
- フォントのライセンスによってはWebフォントに利用すると違反することがあるので要注意
- ファイル容量が小さいため、ストレージの節約になる
- 読み込み時間を短縮できる

## もっと詳しく
### ttf
MicrosoftとAppleが共同で開発した形式で古くから使われている。
無料フォントに使われることが多い。
Office等のMicrosoft製品をよく使う人に特にオススメで、特に古いアプリケーションを利用する場合はtff形式のフォントを選ぶと良いとされています。
MicrosoftとAppleが共同で開発とのことですが、WindowsとMacの互換性はないそうです。
なんでやねん…

### off
AdobeとMicrosoftが主体で共同開発した、TrueTypeフォントとPostScriptフォントの技術を統合して作られた新しいフォント形式だそう。
拡張子が「.otf」だとPostScriptフォントベースの形式、
拡張子が「.ttf」もしくは「.otf」はTrueTypeフォントベースの形式だけど、「.ttf」の場合はTrueTypeかOpenTypeかの区別が付かない…のが難点。
Windows-Mac間での互換性があるのでデータのやりとりで文字化けする心配が少ないため、社内で利用PCのOSが違うときなんかが便利かも。

### ttc, otc
「.ttc」は複数のTrueTypeフォントを１つのファイルにまとめたもの、「.otc」はOpenTypeフォントを一つにまとめたもの。
ただし、OpenTypeをまとめた物であったとしても拡張子に「.ttc」が使われることもある…ややこしい。
1つにまとめるというのは、類似のフォント…字間が均等な等幅フォントや、字詰めされたプロポーショナルフォントをまとめることです。
ちなみに、プロポーショナルフォントとは「文字毎に文字幅が異なるフォント」のことをいい、反対に幅が均等なフォントのことを「等幅フォント」というそうです。

### eot, woff, woff2
eotは「Embedded OpenType」の略でEmbeddedは「埋め込み」の意味とのこと。
Web表示を目的としたOpenTypeのコンパクトな形式が必要だ！とMicrosoftが開発したそうなのでIEのみに対応している独自の規格…。

woffは「Web Open Font Format」の略で代わる新しいWebフォント形式。
Mozilla社が中心となって2009年に最初のバージョンが開発されたフォント形式です。
IE6～8以外の最新ブラウザの多くには対応しているとのこと
[Can I use…](https://caniuse.com/?search=woff)で調べたところ下記のような感じでした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146612/02bb4621-4f9e-f325-d5a5-47f7ed8d6a55.png)

woff2は「WOFF File Format 2.0」の略でWOFFのバージョンアップ版。
woffよりもフォントファイルの圧縮率が高い&読み込み時間をより短縮できるそうで現在各ブラウザの対応が進められている模様。
主要ブラウザの最新バージョンには対応済みみたいですが、IEは非対応…ほんとに厄介。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146612/b03cdc0d-b1a6-269c-9f37-219b61368350.png)

## まとめ
今回Webサイトで利用するにはどの形式フォントがいいのかを調べていました。
個人的な結論としては、最新ブラウザだけならwoff2の形式を使うことがWebページのパフォーマンスなどを考慮しても良さそう。
ただIEの古いバージョンまで対応したい場合はwoffやeotの利用を考えるのが無難だと思いました。

何かの参考になりましたら幸いです。
puppeteerでDOM取得したい場合

```javascript
let table = document.querySelector('form[action="mtr1010.asp"] table:nth-of-type(2)');
```

```
ReferenceError: document is not defined
```

puppeteerのスクリプト内でDOM要素の取得がしたい場合
直接document.querySelector()では取得できない。

下記のように page.evaluate()経由で取得する。

```page.evaluate(pageFunction[, ...args])```

```javascript
const bodyHandle = await page.$('body');
const html = await page.evaluate(body => body.innerHTML, bodyHandle);
await bodyHandle.dispose();
```
参考：[公式APIドキュメント_puppeteer/puppeteer · GitHub](https://github.com/puppeteer/puppeteer/blob/v2.0.0/docs/api.md#pageevaluatepagefunction-args)
Pardot のプロセスオートメーション (Salesforce Classic) ⇒ 完了アクションの使用

１．完了アクションが最も適しているのは、どのような種類の条件に基づいて自動化する場合ですか?
２．1 つのマーケティングアセットに完了アクションが複数ある場合はどうなりますか?
３．ページアクションにワイルドカード URL を使用すると、どのようなことができますか?
４．ページアクションを使用するためには Web サイトに何を設定する必要がありますか?
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634241/be3fa7b9-b785-4708-a08d-d9a6804c3b0b.png)
特定のディレクトリを除外して、pythonファイルのオートフォーマットする

```command
find . -type d -name [除外するディレクトリ] -prune -o -type f -name '*.py' -print | xargs autopep8 --in-place --aggressive --aggressive
```

例えば仮想環境とか作って

```
.
├── __init__.py
├── __pycache__
├── a.py
├── b.py
├── c.py
├── d.py
└── venv
    ├── bin
    ├── include
    ├── lib
　　　　└──ここにめちゃめちゃpythonファイルある!!
    ├── pyvenv.cfg
    └── share
```

仮想環境下のファイルは別にフォーマットしなくてよくて、  
a,b,c,d.pyだけフォーマットしたい
みたいなときに役立つコマンド

具体例としては

```command
find . -type d -name venv -prune -o -type f -name '*.py' -print | xargs autopep8 --in-place --aggressive --aggressive
```
最も基本的なオンラインスロットゲームをプレイする方法

スロットゲームに参加するとき、プレーヤーは、プレーヤーが賭けをしたときにのみ、各支払いが賞金を支払うことに注意する必要があります。たとえば、プレーヤーは25のペイアウト行のうち10のみを賭けます。勝った組み合わせはあなたが賭けなかった列に落ちません、そしてあなたは結果を数えません。

今すぐVn88ディーラーにログインして、お気に入りのスロットゲームの1つを選択してください。次に、スロットゲームをプレイする方法を次のように詳しく説明します。

賭けをする：スロットではゲームの賭けが必要です。合計ベットを選択するだけです。この賭け金はすぐにすべての決済行に分割されます。
スピンボタン（画面上のスピン記号）を押します。
次に、このスロットマシン画面のリールがランダムに回転します。
同じシンボルが3つ以上のオブジェクトで表示されたときにプレーヤーが勝った場合。この結果は、プレーヤーが最初に選択したペイアウト行で計算されます。
スピンが終了するとすぐに、報酬を受け取ります（勝った場合）。
新しいスピンを続けると、必要に応じてベットをリセットできます![Xổ Số tan tan 2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1084555/a1df89ff-fbe4-0864-6e42-be80f9c591af.png)
Transformer系、CNN系の主要？論文の引用数遷移(ViT,SAN,Transformer,DETR,BiT,,,YOLO,,,VTAB,,XAI)


#Transformer系、CNN系の主要？論文の引用数遷移

**Google Scholar**で確認しました。

https://scholar.google.com/

|分類/番号|略称|名称|日付毎の引用回数|||||||
|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
||||2021/2/20|2/28||||||
|Transformer系|||||||||||
|(1)|ViT|AN IMAGE IS WORTH 16X16 WORDS: TRANSFORMERS FOR IMAGE RECOGNITION AT SCALE|48|
|(2)|Visual Transformers|Visual Transformers: Token-basedImage Representation and Processing for Computer Vision|4|
|(3)|SAN|Exploring Self-attention for Image Recognition|30||
|(4)|Transformer|Attention Is All You Need|17,724||
|(5)|Point Transformer|Point Transformer|3||
|CNN-Transformer系|||||||||||
|(6)|DETR|End-to-End Object Detection with Transformers|123||
|CNN系|||||||||||
|(7)|BiT|Large Scale Learning of General Visual Representations for Transfer|41||
|(8)|Efficient-net|EfficientNet: Rethinking Model Scaling for Convolutional Neural Networks.|1,662|
|(9)|ResNet|Deep Residual Learning or Image Recognition|70,138|
|CNN 個別技術要素系|||||||||||
|(10)|CNN 位置情報|HOW MUCH POSITION INFORMATION DO CONVOLUTIONAL NEURAL NETWORKS ENCODE?|27|
|Segmentation系|||||||||||
|(11)|U-net|Convolutional Networks for Biomedical Image Segmentation|23,248|
|(12)|DeepLab v3+|Encoder-Decoder with Atrous Separable Convolution for Semantic Image Segmentation|3,014|
|その他（YOLO)系|||||||||||
|(13)|YOLO|You Only Look Once:Unified, Real-Time Object Detection|14,175||
|(14)|YOLO v3|YOLOv3: An Incremental Improvement|5,754||
|(15)|YOLO v4|YOLOv4: Optimal Speed and Accuracy of Object Detection|422||
|その他系|||||||||||
|(16)|GPT-3|Language Models are Few-Shot Learners|566||
|データセット系|||||||||||
|(17)|ImageNet(Done)|Are we done with ImageNet?|7||
|(18)|JFT-300M|Revisiting Unreasonable Effectiveness of Data in Deep Learning Era|735||
|(19)|VTAB|The Visual Task Adaptation Benchmark|20||
|説明（性）系|||||||||||
|(20)|LIME|" Why should i trust you?" Explaining the predictions of any classifier||4,802|
|(21)|Grad-CAM|Grad-cam: Visual explanations from deep networks via gradient-based localization||3,912|
|(22)|XAI|A survey of the state of explainable AI for natural language processing||4|



#2021/2/20調査結果に関するコメント
初回なので、よくわからない。論文が出された日付は書いたほうがいい気が。。。

#補足
（どうでもいい内容なんですが、、、）データの記載間違いがあると嫌なので、一応、魚拓を保存しています。

---
**（入力確認）チェックリスト**

- [x] 　2021/02/20
- [x] 　2021/02/20(同日、追加）

---

最初は、細かい頻度で見るかも。飽きたら、半年に1回とかに。
|= or equal記法について

# 概要 
- 記法.... `変数1 ||= 変数2or関数`
- 意味.... `変数1`が`nil`の場合,`変数2`を代入する。そうでない場合は,何も代入しない。

# 例
-  `@foo ||= "bar"`
-  `@foo`に値が存在する場合は,何も代入しない,`nil`の場合は文字列`bar`を代入する
ネイティブアプリのOAuth連携 メモ

## 用語・概念

* **ネイティブアプリ**
  * ユーザーがデバイスにインストールするアプリまたはアプリケーション。

* **埋め込みブラウザ(embedded user-agent)**
  * ネイティブアプリの一部を形成する、または同じセキュリティドメインを共有してアプリがCookieストレージにアクセスしたり、ページコンテンツを検査または変更したりできるよう、ネイティブアプリによってホストされるユーザーエージェント。
* **外部ブラウザ(external user-agent)**
  * ネイティブアプリがCookieストレージにアクセスしたり、ページコンテンツを検査または変更したりできないように、リクエストを行うネイティブアプリとは別のエンティティまたはセキュリティドメインである承認リクエストを処理可能なユーザーエージェント。
* **in-app browser tab**
  * ブラウザのタブをアプリから使う機能。
  * ホストアプリ内に表示されるが、ブラウザーの完全なセキュリティプロパティと認証状態を保持する、ブラウザーインスタンス。

* **private-use URI scheme**
  * アプリによって定義され、オペレーティングシステムに登録されたURIスキーム。
  * スキームへのURIリクエストにより、リクエストを処理するためにそれを登録したアプリを起動する。

* **claimed "https" scheme URI**
  * アプリがドメイン名の所有権を証明した後に「https」スキームURIを要求することで、アプリを起動する。
* **ループバックアドレス**
  * そのIPアドレスを指定することで自分の使用しているコンピュータのIPアドレスを指定した場合と同じ意味になるIPアドレス。



## 連携観点

### 認可リクエストの開始

#### 外部ブラウザの利用

外部ブラウザの利用を推奨する。

##### 推奨理由

- ブラウザに備わっている通常のアドレスバーや証明書の検証機能を利用可能。
- 他のアプリやブラウザと認証状態を共有するためUXが低下しない。
- パスワード・マネージャーの機能を使用できるため、UXが向上する。

##### 外部ブラウザ以外(埋め込みブラウザ)を推奨しない理由 

* 偽造Clientの可能性があり、偽造Clientによって以下の問題が発生する。
  * IdPのアカウントをClientが盗む事ができる。
  * IdPのSession cookieをClientが盗む事ができ、Sessionが有効な間、SSO可能な状態が持続する。

#### PKCEの実装

- 認可リクエスト毎に Code Verifier と呼ばれる値を生成し、そのハッシュ値を付与する。
- IdP からのレスポンスから、認可コード を受け取り、それを利用してアクセストークン の発行を行う。
- アクセストークン発行時に元の Code Verifier を 認可コード と同時に送らせることで、最初に Authorization Request をスタートしたアプリ (その時点まで Code Verifier を知っている唯一のアプリ) だけがアクセストークン の発行を行えることを保証する。

### 認可レスポンスの受信

* 認可サーバーは以下の3つのリダイレクトオプションをサポートする必要がある。

#### Private-Use URI Scheme Redirection

* アプリケーションが受け取る独自のURL スキームを事前にシステムに登録する方式。
* <u>複数のアプリが通常同じURL Schemeを登録できるため、**Private-Use URI Scheme上書き攻撃**が可能。</u>
  * 同じ URL スキームを複数のアプリが登録可能であることから、該当 スキーム 経由で起動されたアプリが本来期待されたアプリと異なる可能性がある。
  * これを利用し、他の ネイティブアプリが利用している URLスキームを乗っ取る攻撃アプリが成立する。
  * 攻撃者は、このような攻撃アプリをターゲットにインストール & ログインさせることで、IdPおよびバックエンドアプリが発行したターゲットアカウント向けのアクセストークンや、バックエンドアプリに保存されているターゲットのデータへのアクセス権を得ることができる。

#### Claimed Https Scheme URI Redirection 

* Private-Use URI Scheme Redirectionを改良した方式。
  * httpsスキームのURIをアプリで受信し、起動する方法。

#### Loopback Interface Redirection 

* ループバックアドレスでHTTPリクエスを受け取る方式。
  * デスクトップOSなどでの利用を想定している。
  * 一部のOSで同じループバックアドレスにアクセスすると、他のアプリの傍受の影響を受ける可能性がある。



## 参考情報

* [RFC 8252 - OAuth 2.0 for Native Apps 日本語訳](https://tex2e.github.io/rfc-translater/html/rfc8252.html)
* [OAuth for Native Apps](https://labs.gree.jp/blog/2015/12/14831/)
Gitコマンドメモ

GitHubの使いかじめメモ
前提として、Githubでリモートリポジトリを作成している状態である
ローカルリポジトリ作成、及びリモートへのpushまでの作業メモ

#Gitを使うためのファーストステップ
Terminalを起動して下記のコマンドを打ち込んでいく
##git <font color="Red">init</font>
まずは自分の作業領域を作成っして下記コマンドを入力
（とりあえずデスクトップにフォルダを作ってそこを開発領域とする）

```
mkdir ~/Desktop/[好きなフォルダ名]
cd ~/Desktop/[好きなフォルダ名]
git init
```
これで[.git]ファイルが生成される

##git <font color="Red">add</font>
作業領域の変更をgitインデックスに登録する

```
git add . (現在の領域全ての変更をインデックスに格納)
```

##git <font color="Red">commit</font>
addでインデックスに登録した変更内容をローカルリポジトリに登録する

```
git commit -m 'first repo'
```

##git <font color="Red">remote</font> add origin ~~~~~
リモートリポジトリへの登録をする。これでWeb上のGithubにローカルで作ったファイルが登録出来るようになる

```
git remote add origin https://github.com/[githubのユーザー名]/[githubで作ったリポジトリ名].git
```

#git <font color="Red">push</font> origin master
リモートリポジトリのmasterブランチに直接書き込む
※これはmasterに対して直接書き込んでしまう


#安全に作業をする為のブランチ作成
ブランチとは、masterファイルを直接編集することを回避するためのプレ作業領域
①ローカルでブランチの作成
②ブランチに変更を登録
③リモートリポジトリにpush
④リモートリポジトリでmerge
といった流れでリモートのmasterに安全に変更を加えることが出来る
##git <font color="Red">branch</font>
ローカルリポジトリのブランチを一覧表示出来る。
最初はmasterのみで`*master`となっている。`*`は選択されていることを示す

##git <font color="Red">branch</font> [好きなブランチ名]
ブランチを作成するコマンド
`git branch`で確認すると

```
*master
[好きなブランチ名]
```
ブランチが作成されたことが分かる

##git <font color="Red">checkout</font> [好きなブランチ名]
ブランチを移動するためのコマンド
このコマンドを打った後に再度`git branch`で確認すると

```
master
*[好きなブランチ名]
```
となってブランチが移動したことが分かる

##git add ~ git pushまで
下記のコマンドでブランチからのプッシュが出来る

```
git add .
git commit -m 'second commit'
git push origin [好きなブランチ名]
```
プッシュが出来たらgithubでmergeする
効果検証入門 4.差の差分法(DID)とCausalImpact

[前回：傾向スコアを用いた分析](https://qiita.com/_R2_/items/4a3ca8dc575e269af87d)

効果が広範囲に影響するような介入(法律の施行やスーパーの値引きなど)では、結果変数Yに地域固有の特性が含まれてしまい介入群と非介入群の単純な比較ができない。そこで、各グループの時系列データで介入前後の時点の差分を取り、その後にグループ間の差分を取る、という差の差分析(DID法)を学ぶ。

例：A県で、県外からの観光客にお土産を無料配布する(介入)。この介入によって県外からの観光客は増えるのかどうかを知りたいとする。非介入群として、お土産配布を行わないB県のデータを用いる。A、Bにおいて、介入前と介入後の県外からの観光客の人数は以下のようであった。

|        |   介入前      |     介入後     |　差 　  |
|:----------:|:---------------:|:-----------:|:-----------:|
| 介入群A   | 320       | 280    |     -40            |
| 非介入群B | 290          | 200             |      -90     |


このデータについて、介入後のA、Bを比較して「Aの方が80多いので効果は80」としたり(地域間の特性の違いを無視)、Aの介入前後を比較して「介入後のほうが40少ないので効果は-40」とする(介入以外の共変量の影響を無視)ことはできない。DID法では次のようなモデルを考える。

```math
\begin{align}
Y_{post,A}&= Time_{post}+Area_A+\tau\\
Y_{pre,A} &=Time_{pre}+Area_A\\
Y_{post,B}&=Time_{post}+Area_B\\
Y_{pre,B} &=TIme_{pre}+Area_B
\end{align}
```

ここで、Areaは変化しない地域固有の特性(人口など)、Timeは時間と共に変化するA、B共通の共変量(季節など)である。ただし、観測されない交絡因子の影響は不変であるとし、Timeに含まれる共変量の変化の仕方は一定であるとする(平行トレンド仮定)。このモデルを仮定することで、介入効果$\tau$は、

```math
\tau=(Y_{post,A}-Y_{pre,A})-(Y_{post,B}-Y_{pre,B})=(280-320)-(200-290)=50
```

と、時点間の差分をそれぞれ取ったのち地域間の差分を取る(差の差をとる)ことで求められる。

※CausalImpactの話もしているが、簡単化のために時系列モデルを端折っているせいでだいぶ薄い内容になっている。実装するほどではないかな、と思うので時系列モデルを勉強してから戻ってきたい。

※CausalImpactのアイデア：コロナ対策の政策実施前のデータについて、PCR検査数などから陽性患者数を推定するモデルを作って政策効果を評価する。
VScodeで日本語表示させる方法

1　VScodeを起動。「 command + shift + P」でコマンドパレットを開く
2　Configure Language から locale.json を開く
３　"locale": "en" のenをjaに変える
４　VScodeを再起動する

アップデートしたら英語になり、使いにくくなってしまったため。健忘録。
S3 syncコマンドを利用してＳ３バケット間を同期する

## S3 syncコマンドを利用してＳ３バケット間を同期する



最近Ｓ３バケットデータ移行の要望が来ていました。

バケット間同期用のコマンドを調査しましたので、備忘として残ります。



### やりたいこと

AアカウントにあるS3バケットのデータをBアカウントのS3に移行したい



### 実現方法を簡単に説明

1. BアカウントにS3バケットを作成する
2. オンプレミス環境で実行するので、S3操作権限あるIAMユーザを作成する
3. AアカウントのS3バケットにBアカウントで作成したIAMユーザのアクセス許可ポリシーを追加する
4. S3バケット間でデータを同期する
5. データが正しくコピーされているかを確認する



### 同期コマンド

cpコマンドを利用して再帰的にコピーできますが、今回利用するもっと楽の同期コマンドをご紹介します。

```
aws s3 sync s3://BUCKET-SOURCE s3://BUCKET-TARGET
```

**sync** コマンドは CopyObject API を使用して S3 バケット間でオブジェクトの移動を行います。**sync** コマンドは、ソースとターゲットのバケットをリストアップし、ソース側に存在しターゲット側にないバケットを特定します。また、このコマンドは、LastModified の日付がターゲットバケット内のものと異なる、ソースバケット内のオブジェクトも識別します。

結構使えるオプションもあるので、今回使ったオプションをご紹介します。

他にはAWSの公式ドキュメントをご参照ください。

[aws s3 sync](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3/sync.html)

| オプション                                                   | 説明                                                         |
| ------------------------------------------------------------ | ------------------------------------------------------------ |
| <span style="display:inline-block;width:150px"> --only-show-errors</span> | デフォルトではコピープロセスが表示されます。オブジェクトが多いので、エラー情報のみ出力するように設定する。 |
| --exact-timestamps                                           | S3からローカルに同期する場合、同じサイズのアイテムは、タイムスタンプが完全に一致する場合にのみ無視されます。 デフォルトの動作では、ローカルバージョンがS3バージョンよりも新しい場合を除き、同じサイズのアイテムは無視されます。 |
| --delete                                                     | コピー先には存在するがコピー元には存在しないファイルは、同期中に削除されます |



### コピー結果を確認

次のコマンドを実行して、ソースとターゲットバケットの内容を確認する

```
aws s3 ls --recursive s3://BUCKET-SOURCE --summarize > bucket-contents-source.txt
        
aws s3 ls --recursive s3://BUCKET-TARGET --summarize > bucket-contents-target.txt
```

上記のコマンドを実行すると、バケット内容にあるオブジェクトリスト一覧とオブジェクト数とサマリーサイズが出力されます。



### 少しハマった話

コピーした後に上記の確認コマンドでリスト一覧を出力してみたら、

あれ、オブジェクト数が異なっています。

いろいろ調査し、試してみたら、以下のことがわかりました。

元のバケットでは、基本フォルダを作成した後に、ファイルをアップロードしています。

とすると、サイズゼロのオブジェクト（フォルダ）がリスト一覧に出力されます。
![s3_list_size0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1109288/6ab19ff0-57be-a382-3b98-61d75bcd118e.png)

但し、オブジェクトをコピーする際に、サイズゼロのフォルダが作成しないので（プレフィックス付きのオブジェクトのみ作成する）

コピー後の`Totla Objects`が異なっています。

![s3_list.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1109288/29b7c28f-c549-4bc7-a9ba-bce5c5ddc6b0.png)


なんか、サイズゼロのオブジェクトを出力しないオプションがなさそうなので

トータルサイズを比較し、オブジェクト一覧をExcelにコピーして整形してから比較するようにしました。
連続した日付ベクトルをつくる【R】

seq()を使う。sequence...連続するもの、数列、配列

```
> seq(from=as.Date("2018-08-15"), to=as.Date("2018-09-03"),by="day")
 [1] "2018-08-15" "2018-08-16" "2018-08-17" "2018-08-18" "2018-08-19" "2018-08-20"
 [7] "2018-08-21" "2018-08-22" "2018-08-23" "2018-08-24" "2018-08-25" "2018-08-26"
[13] "2018-08-27" "2018-08-28" "2018-08-29" "2018-08-30" "2018-08-31" "2018-09-01"
[19] "2018-09-02" "2018-09-03"

# seq(from=はじまりの日付,to=終わりの日付,by=間隔)
```

日付の間隔も変えられる。

```
> seq(as.Date("2018-08-15"), as.Date("2018-09-03"),by="2 days")
 [1] "2018-08-15" "2018-08-17" "2018-08-19" "2018-08-21" "2018-08-23" "2018-08-25"
 [7] "2018-08-27" "2018-08-29" "2018-08-31" "2018-09-02"

> seq(as.Date("2018-08-15"), as.Date("2018-09-03"),by="2days")
 seq.Date(as.Date("2018-08-15"), as.Date("2018-09-03"), by = "2days") でエラー: 
   'by' に対する無効な文字列です 

# by="2days"だと認識されない。by="2 days"のように間隔をあける。
```

いろんな間隔を指定できる。

```
> seq(as.Date("2018-08-15"), as.Date("2018-09-03"),by="weeks")
[1] "2018-08-15" "2018-08-22" "2018-08-29"
# 週を指定
```

ほかの引数の使い方。

```
> seq(as.Date("2018-08-15"), as.Date("2018-09-03"),length.out=4)
[1] "2018-08-15" "2018-08-21" "2018-08-27" "2018-09-03"
# 指定した個数に分割してくれる
```
【VBA】ExcelVBAでOutlookを操作するための基本

まず、以下のとおり参照設定します。
`Microsoft Outlook XX.X Object Library`

基本的なコードは以下のとおりです。

```vb
Sub OutlookTest()

    Dim ol As Outlook.Application
    Set ol = New Outlook.Application

    Dim ns As Namespace
    Set ns = ol.GetNamespace("MAPI")

    '6番が受信トレイを示す
    Dim fl As MAPIFolder
    Set ns.GetDefaultFolder(6)

    '受信トレイのメールを受信日時で絞り込む
    Dim mails As Items
    Set mails = fl.Items.Restrict("[ReceivedTime] >= '" _
        & Format("2021/1/1 0:00", "ddddd h:nn AMPM") & "'" _
        & " And [ReceivedTime] < '" _
        & Format("2021/1/2 0:00", "ddddd h:nn AMPM") & "'")

    Dim m As MailItem
    For Each m In mails
        'メールに関する処理
    Next

    Set fl = Nothing
    Set ns = Nothing
    Set ol = Nothing

End Sub
```

ポイントは`Restrict`メソッドでメールを絞り込んでいるところです。
このように絞り込むことで、2021/1/1に受信したメールのみを`mails`に格納しています。
日時の形式を`Format`関数で整えているところ、シングルクォーテーションとダブルクォーテーションが入り乱れているところに注意してください。
日時以外にもいろいろな条件で絞り込みができるようです。

参考
[Restrict メソッド (Outlook)](https://docs.microsoft.com/ja-jp/office/vba/api/outlook.items.restrict)