OmniAICreator/Qiita-1.07M huggingface dataset:
【Next.js】Material-UI導入時に[Warning: Prop `className` did not match. ]が発生した場合の対処法

## はじめに

[Next.js](https://nextjs.org/)に[Material-UI](https://material-ui.com/)を導入した際、以下のエラーが出るようになったので、原因を調べてみた。

```log
react-dom.development.js:67 Warning: Prop `className` did not match. Server: "MuiTypography-root makeStyles-title-7 MuiTypography-h6" Client: "MuiTypography-root makeStyles-title-3 MuiTypography-h6"
    at h6
    at Typography (http://localhost:3000/_next/static/chunks/pages/index.js?ts=1623629454944:32031:28)
    at WithStyles (http://localhost:3000/_next/static/chunks/pages/index.js?ts=1623629454944:39745:31)
    at div
    at Toolbar (http://localhost:3000/_next/static/chunks/pages/index.js?ts=1623629454944:31078:23)
    at WithStyles (http://localhost:3000/_next/static/chunks/pages/index.js?ts=1623629454944:39745:31)
    at header
    at Paper (http://localhost:3000/_next/static/chunks/pages/index.js?ts=1623629454944:20042:23)
    at WithStyles (http://localhost:3000/_next/static/chunks/pages/index.js?ts=1623629454944:39745:31)
    at AppBar (http://localhost:3000/_next/static/chunks/pages/index.js?ts=1623629454944:1547:23)
    at WithStyles (http://localhost:3000/_next/static/chunks/pages/index.js?ts=1623629454944:39745:31)
    at div
    at ButtonAppBar (http://localhost:3000/_next/static/chunks/pages/index.js?ts=1623629454944:41740:17)
    at main
    at div
    at Root
    at App (http://localhost:3000/_next/static/chunks/pages/_app.js?ts=1623629454944:29:24)
    at ErrorBoundary (http://localhost:3000/_next/static/chunks/main.js?ts=1623629454944:158:47)
    at ReactDevOverlay (http://localhost:3000/_next/static/chunks/main.js?ts=1623629454944:274:23)
    at Container (http://localhost:3000/_next/static/chunks/main.js?ts=1623629454944:8135:5)
    at AppContainer (http://localhost:3000/_next/static/chunks/main.js?ts=1623629454944:8623:24)
    at Root (http://localhost:3000/_next/static/chunks/main.js?ts=1623629454944:8759:25)
```

## 結論

サーバー側でレンダリングされたCSSの名前と、クライアント側のCSSの名前がマッチしないため、当該エラーが発生している模様。

私の場合、[pages/_document.js](https://github.com/mui-org/material-ui/blob/master/examples/nextjs/pages/_document.js)を追加することで、問題が解消した。

## 環境

```json
{
    "@material-ui/core": "^4.11.4",
    "@material-ui/icons": "^4.11.2",
    "@material-ui/lab": "^4.0.0-alpha.58",
    "next": "10.2.2",
    "react": "17.0.2",
    "react-dom": "17.0.2",
}
```

## 参考

- [[styles] Strict Mode support · Issue #18018 · mui-org/material-ui](https://github.com/mui-org/material-ui/issues/18018)
- [Warning: Prop `className` did not match. Server.... Typography component, prop based styles · Issue #19772 · mui-org/material-ui](https://github.com/mui-org/material-ui/issues/19772)
- [node.js - React + Material-UI - Warning: Prop className did not match - Stack Overflow](https://stackoverflow.com/questions/50685175/react-material-ui-warning-prop-classname-did-not-match)
【AWS】S3を用いた画像のアップロード（Carrierwave）

# 目的
AWSのS3を使用し、画像をアップロードする。

# 開発環境
macOS: *Big Sur*
Rubyバージョン: *2.6.5*
Railsバージョン: *6.0.0*

# 前提

- S3のバケットが作成されている。
[【AWS】S3バケット作成](https://qiita.com/oak1331/items/b9b77200ad7c921f8961)
- 環境変数が設定されている。
[【AWS】S3を用いた画像のアップロード](https://qiita.com/oak1331/items/74da3cf101e2e2107f32)
- アプリが作成されている。
[【Rails】簡単な投稿アプリの作成](https://qiita.com/oak1331/items/18a4f3a3386aab0fa354)
- 画像アップロード機能が実装されている。
[【Rails】ユーザープロフィール画像機能の実装（Carrierwave）](https://qiita.com/oak1331/items/323041e595822d610312)

# 手順

1. [はじめに](#はじめに)
1. [Gemのインストール](#gemのインストール)
1. [アップローダーの編集](#アップローダーの編集)
1. [carrierwave.rbの編集](#carrierwaverbの編集)
1. [環境変数の設定](#環境変数の設定)

# はじめに

今回はAWSの`S3`を用いた画像アップロードを実装していきます。

# Gemのインストール

以降のコードを編集する際はmasterブランチで作業していきます。

それでは早速始めていきます！
S3を使用するために必要な`fog-aws`というGemをインストールします!

```ruby:Gemfile
#省略
gem 'fog-aws'
```

```:ターミナル	
% bundle install
```

これでインストールできました!

# アップローダーの編集

続いて、画像の保存先を`local`から`S3`に保存されるように設定を変更します！
`storage :file`を`storage :fog`に変更することで`S3`へアップロードすることができます。

```ruby:app/uploaders/avatar_uploader.rb
class AvatarUploader < CarrierWave::Uploader::Base
  # Include RMagick or MiniMagick support:
  # include CarrierWave::RMagick
  # include CarrierWave::MiniMagick

  # Choose what kind of storage to use for this uploader:
  # storage :file
  storage :fog
#省略
```

これで画像の保存先が変更できました。

# carrierwave.rbの編集

次に、S3で使用する`バケット名`や`リージョン名`、`環境変数`を記述します。
`carrierwave.rb`を作成し、以下のコードを追記します。

```ruby:config/initializers/carrierwave.rb
require 'carrierwave/storage/abstract'
require 'carrierwave/storage/file'
require 'carrierwave/storage/fog'

CarrierWave.configure do |config|
    config.storage :fog
    config.fog_provider = 'fog/aws'
    config.fog_directory  = 'バケット名' # バケット名
    config.fog_credentials = {
      provider: 'AWS',
      aws_access_key_id: ENV['AWS_ACCESS_KEY_ID'], # 環境変数
      aws_secret_access_key: ENV['AWS_SECRET_ACCESS_KEY'], # 環境変数
      region: 'ap-northeast-1', # リージョン
      path_style: true
    }
end 
```

「バケット名」の箇所には、自分のバケット名を入力します！

# 環境変数の設定

環境変数はこちらを参考に設定します。[【AWS】S3を用いた画像のアップロード](https://qiita.com/oak1331/items/74da3cf101e2e2107f32)

設定後、正しくできているかを確認するために、下記のコマンドを入力してください。

```
% heroku config
```

確認できたら、コミットしてHerokuに反映させます。

```:ターミナル
% git push heroku master
```

その後、本番環境で挙動確認し問題がなければ完了です。

# 最後に

以上で、`S3`を用いた画像アップロード機能実装は完了です。
では。
datadogのsystem.disk.in_useがうまく動かなくてはまった

#概要
AWSのEC2で構築したUbuntuのディスク使用率監視をdatadog-agentにて行おうと試みたところ、system.disk.in_useのmax値が1のまま変化せず監視が想定通りできずはまった。

#環境
インスタンスタイプ: t2.micro
OSバージョン: Ubuntu, 18.04 LTS
EBS: 8GiB, gp2
datadog-agentバージョン: v7.28.1

#実現したかったこと
以下クエリでのディスク使用率監視
`avg(last_5m):max:system.disk.in_use{system:xxx} by {host} > 閾値`

#状態
上記クエリの値が常に1のまま変動せず、監視ができない。

#解決策
datadog-agentのdisk.dのconf.yamlに以下を記載し、ループデバイスを除外する。


```yaml:/etc/datadog-agent/conf.d/disk.d/conf.yaml
init_config:
    file_system_global_blacklist:
      - squashfs

instances:
  - use_mount: false
```

#何が起きてたか
dfコマンドで確認したところ、使用率が100%のファイルシステム/dev/loop0,　/dev/loop1,　/dev/loop2が存在した。
datadog-agentはこれらの値も取得していたため、max値が常に1になってしまっていました。

```
$ df
Filesystem     1K-blocks    Used Available Use% Mounted on
udev              486408       0    486408   0% /dev
tmpfs             100208     768     99440   1% /run
/dev/xvda1       8065444 2952280   5096780  37% /
tmpfs             501036       0    501036   0% /dev/shm
tmpfs               5120       0      5120   0% /run/lock
tmpfs             501036       0    501036   0% /sys/fs/cgroup
/dev/loop0         33152   33152         0 100% /snap/snapd/11588
/dev/loop1         56832   56832         0 100% /snap/core18/1997
/dev/loop2         34176   34176         0 100% /snap/amazon-ssm-agent/3552
tmpfs             100204       0    100204   0% /run/user/1000
```

##ループデバイスとは
>任意のファイルを，ファイルシステム（例：ext2）のようにマウントができる機能だ。

参考: [ループバックデバイスってなに？ - ITmedia エンタープライズ](https://www.itmedia.co.jp/help/tips/linux/l0171.html)

これらは読み取り専用の仮想デバイスなので、使用率が100%であっても監視上問題ないようです。

##除外したいファイルシステムの特定

ループデバイスを除外するためdisk.d/conf.yamlの`file_system_global_blacklist`へ対象のファイルシステムを追記する必要がありました。
datadog-agentではファイルシステムの情報をpythonライブラリであるpsutilのdisk_partitionsにより取得していたため、本項にはこのレスポンスに含まれる`fstype`を記載する必要があリました。

```
$ python
>>> import psutil 
>>> psutil.disk_partitions()
  sdiskpart(device='/dev/xvda1', mountpoint='/', fstype='ext4', opts='rw,relatime,discard', maxfile=255, maxpath=4096),
  sdiskpart(device='/dev/loop0', mountpoint='/snap/snapd/11588', fstype='squashfs', opts='ro,nodev,relatime', maxfile=256, maxpath=4096),
  sdiskpart(device='/dev/loop1', mountpoint='/snap/core18/1997', fstype='squashfs', opts='ro,nodev,relatime', maxfile=256, maxpath=4096), 
  sdiskpart(device='/dev/loop2', mountpoint='/snap/amazon-ssm-agent/3552', fstype='squashfs', opts='ro,nodev,relatime', maxfile=256, maxpath=4096)
]
```

なお、上述したpsutilのdisk_partitionsは`/etc/mtab`を読み取っていたため、直接こちらを確認する方法でも良さそうでした。
(以下一部抜粋)

```
$ cat /etc/mtab
/dev/loop0 /snap/snapd/11588 squashfs ro,nodev,relatime 0 0
/dev/loop1 /snap/core18/1997 squashfs ro,nodev,relatime 0 0
/dev/loop2 /snap/amazon-ssm-agent/3552 squashfs ro,nodev,relatime 0 0
```

#まとめ
ループデバイスが原因であるところまではすぐたどり着いたが、除外方法に方法に悩みました。
困った時はソースコードを確認するのが一番でした。
```# FIXME (8.X): Exclude special file systems by default```
とあったので8系では良くなってるかもしれないです。
JavaScript−spliceについてメモ書き

以前、ドットインストールかなにかで自分が模写した、タイピングゲームのコードを見たのですが、どういう仕組みのコードか理解できませんでした。

そこで、以前はわからなくても写して終わりでしたが、今回は
調べてみました。

前置きが長くなりましたが、JavaScriptのspliceについて、
あまり理解してなかったことをまとめておきます。


```
 word = words.splice(Math.floor(Math.random() * words.length), 1)[0];
```

spliceについては、私が調べた限りでは、
第一引数に追加・削除する位置、第二引数に削除する要素の数、第三以降は、追加する要素と説明する限りのものがほとんどだったので、
このコードの最後の[0]の意味が全くわかりませんでした。


そこで、コンソールでどう表示されるのか、一つ一つ確認してみました。


コードはこんな感じです。

```
    let word;
    const words = ["red","blue","green",'white'];
    word = words.splice(Math.floor(Math.random() * words.length), 1)[0];
    console.log(word);
    console.log(Math.floor(Math.random() * words.length))
    console.log(words)
```

そして実行結果は、


こんな感じでした。
![スクリーンショット 2021-06-14 8.54.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1290117/8b95c062-2d8d-2552-d3d1-b791bceecad1.png)


つまり、spliceで削除したやつが、wordに入り、
残りがwordsに配列として格納されているということです。

では、[0]を消して、コンソールに表示してみると、
![スクリーンショット 2021-06-14 9.04.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1290117/33289505-1609-12af-12ae-54dad9003d12.png)


wordが配列として取得されてしまいました。

つまり、[0]の意味は、単に配列の０番目を取得するっていうだけでした。

目的は、変数wordに格納することなので、配列で格納してしまうと、
タイピングゲームの実装上面倒なので、[0]を付け加えて、
値を取得しています。


すごい初歩的なことでしたが、
割と悩みましたw


spliceだけ見ていると、「削除したから消えるんでしょ？」って
考えがちですが
このコードの場合、4つの要素からランダムに選ばれたものを
配列リストから削除し、定数wordに格納していました。


すなわち、実質的には、配列からランダムに要素を
取得しているようなものだったんです。


とまあ、至極当たり前のことなんですが、
初心者にとっては、結構引っかかりました。


splice=削除と、あまりに強く思い込みすぎて、
よくわからなくなりましたが、
コンソールで確認して、無事理解できたので、
メモを残しておきます。
【Javascript】Callメソッドを試してみる

# 初めに
CallメソッドとApplyメソッドについて学習した内容のoutput用記事です。

※内容に間違いなどがある場合はご指摘をよろしくお願いします。
※こちらの記事はあくまでも個人で学習した内容のoutputとしての記事になります。

# Callメソッド
関数を呼び出す際に、呼び出し元のthisがどのobjectなのかを指定します。

```javascript
//構文
呼び出す関数.call(適用するobject, 関数の引数, 関数の引数2, ...);
```

# 使ってみる
まず、次のようなobjectを用意します。 trainオブジェクトにはprintTrain関数があり、コンソールにはtrainオブジェクトのtrainNameとdestination、そしてprintTrain関数の引数carNumとnameを表示します。また、trainオブジェクトにはdataというからの配列があり、printTrain関数を呼び出すとdataにtrainNameとcarNum、関数の引数nameを追加していきます。

```javascript
const train = {
  trainName: 'JR',
  destination: 'Shibuya',
  data: [],
  printTrain(carNum, name) {
    console.log(
      ` ${name} takes a train on ${this.trainName}.\n`,
      `Bound for ${this.destination}.\n`,
      `Car number is ${carNum}`
    );
    this.data.push({ TrainNumber: `${this.trainName}${carNum}`, name });
  },
};
```
このtrainオブジェクトのprintTrain関数を呼び出します。引数には5と'Tom'を指定します。

```javascript
train.printTrain(5, 'Tom');
```

コンソールには以下のような結果が表示されます。
![スクリーンショット 2021-06-14 8.25.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/966135/5fa95cbe-6a14-15b4-01e3-79ed8a87cf29.png)
trainオブジェクトの中身を確認してみます。

```javascript
console.log(train);
```
data配列に値が格納されていることが分かります。
![スクリーンショット 2021-06-14 8.28.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/966135/a1bf5532-52c5-577a-ea1b-ea6a68c02bf8.png)

trainオブジェクトのprintTrain関数を変数printTrainに格納します。これで変数printTrainはtrainオブジェクトの関数を保持しています。

```javascript
const printTrain = train.printTrain;
```
この状態でprintTrainに引数を渡し、呼び出してみます。

```javascript
printTrain(23, 'Tanaka');
```
TypeErrorが出てしまいます。内容としてはtrainNameが変数printTrainに定義されていないと表示されます。
![スクリーンショット 2021-06-14 8.34.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/966135/18d33093-8bf5-0943-b503-e68f6f42e331.png)
これはtrainオブジェクトのprintTrain関数に指定されているthisがどのオブジェクトのthisなのかjavascriptが分からないことが原因です。オブジェクトの関数を他の変数に代入した時点でthisがグローバルコンテキストに変わったからです。

callメソッドを使い、thisがどのobjectなのかを指定(trainオブジェクトに指定）して引数と共に実行してみます。

```javascript
printTrain.call(train, 332, 'Suzuki');
```
結果を見てみると今回はうまくいきました。
![スクリーンショット 2021-06-14 8.44.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/966135/8fd13f10-b566-b25c-32eb-e1c70c8bad48.png)

trainオブジェクトの中身を確認します。

```javascript
console.log(train);
```
先ほど関数を呼び出した結果としてdata配列に値が追加されていることが分かります。
![スクリーンショット 2021-06-14 8.45.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/966135/f516debc-2f07-dc5b-d413-c3fa7a9743f7.png)
このようにcallメソッドを使うことによって呼び出す関数のthisがどのobjectなのかを指定し、関数の引数と共に結果を出力することができます。

# 参考サイト
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Function/call
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Function/apply
一覧をランダム順に返す API でページネーションする時に順序を維持する

## 背景
- あるリソースの一覧をランダム順に返却する API でページネーションを行う必要があった
- 単純に順序をランダム化するだけだとリクエストの度にランダム順に返ってしまう
- 1ページ目をリクエストした時と2ページ目以降をリクエストした時で同じ順番に並んでいてほしい

## 環境
- Ruby 2.7.3
- Rails 6.1.3.1
- PostgreSQL 12.5-alpine
- React 17.0.2
- TypeScript 3.9.9

## 設計
- 要素をランダムに並べる時に seed という数値を指定すれば、 seed が同じである限り同じ順番にランダム化してくれることを利用する
- フロント側で順序を維持したい範囲に seed を保持して、リクエストの度にパラメータとして送信する
- サーバー側では seed が同じであれば同じ順番でランダム化された一覧を返すように実装する

## サーバー側
### 実装
- 今回は諸事情により Ruby でランダムに並べ替えていたので、下記のように実装した。
- SQL でランダム化したい場合の実装は後述。

```rb
class StaffsController < ApplicationController
  def index
    page = params[:page].to_i
    per_page = params[:per_page].to_i
    seed = params[:randomize_seed].to_i
    staffs = Staff.all.shuffle(random: Random.new(seed)).slice((page - 1) * per_page, per_page) || []
    render json: { staffs: staffs }
  end
end
```

### 解説
`shuffle(random: Random.new(seed))` のところが肝だと思うので解説していく。

- [Array#shuffle](https://ruby-doc.org/core-2.7.3/Array.html#method-i-shuffle) で配列をランダムに並び替える時に、引数として Random オブジェクトを渡すことができる。
- [Random::new](https://ruby-doc.org/core-2.7.3/Random.html#method-c-new) で Random オブジェクトを初期化する際に seed として数値を渡すことができる。
- `params[:randomize_seed]` でフロントから受け取った seed を渡すことで順番を維持できる。

## フロント側
### 実装
```tsx
const StaffListPage: React.FC = () => {
  const [staffs, setStaffs] = useState<Staff[]>([]);
  const [page, setPage] = useState(1);
  const seed = useMemo(() => Math.floor(Math.random() * 100), []);

  useEffect(() => {
    const fetchStaffs = async () => {
      const response = await fetch(`/api/staffs?page=${page}&per_page=10&randomize_seed=${seed}`, {
        method: 'GET',
      });
      const data = await response.json();
      setStaffs(data.staffs);
    };
  }, [setStaffs, page, seed]);

  return <StaffList staffs={staffs} onChangePage={setPage} />;
};
```

### 解説
- [Math.random()](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Math/random) と [Math.floor()](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Math/floor) を用いて0から100までのランダムな数値を取得している
- ランダムな数値がレンダリングの度に変わらないように useMemo でキャッシュしている
- ページが切り替わっても同一の randomize_seed がサーバーに送信されるので順番が保持される

## 余談
- 普通は SQL 側でランダム化・ページネーションを行いたいと思うので、その時の実装も検討。

### MySQL
- [RAND()](https://dev.mysql.com/doc/refman/5.6/ja/mathematical-functions.html#function_rand) が利用できそう。

```rb
class StaffsController < ApplicationController
  def index
    page = params[:page].to_i
    per_page = params[:per_page].to_i
    seed = params[:randomize_seed].to_i
    staffs = Staff.order("RAND(#{seed})").page(page).per(per_page)
    render json: { staffs: staffs }
  end
end
```

### PostgreSQL
- [setseed](https://www.postgresql.jp/document/9.4/html/functions-math.html#FUNCTIONS-MATH-RANDOM-TABLE) が利用できそう。

```rb
class StaffsController < ApplicationController
  def index
    page = params[:page].to_i
    per_page = params[:per_page].to_i
    seed = params[:randomize_seed].to_i
    Staff.connection.execute("SELECT setseed(#{seed});")
    staffs = Staff.order("RANDOM()").page(page).per(per_page)
    render json: { staffs: staffs }
  end
end
```

## 備考
- 要点を絞って伝えるために本番で動作しているコードの一部を簡略化して掲載したので、実際に実行してみて動かなかったらごめんなさい。
QtのSSL/TLSバックエンドを wolfSSL で動かしてみる

wolfSSL は IoT デバイス、組み込み向け小型、軽量の SSL/TLS ライブラリーです。多くのリアルタイムOSを含む組み込み向けOSにポーティングされていると同時に、サードパーティー向けのインテグレーションにも力を入れています。今回は、Qt 5の最新版 Qt 5.15 のSSL/TLSバックエンドをwolfSSLでビルドし、簡単なサンプルを動かしてみます。

##概要
[Qt](https://www.qt.io/ja-jp/)のデフォルトSSL/TLSライブラリーはOpenSSLです。このバックエンドを[wolfSSL](https:/https://www.wolfssl.jp/)で置き換えます。今回は、LinuxやMacOS上でのコマンド環境を想定しています。

##QtのSSL/TLSバックエンドを wolfSSLとしてビルドする

###1.wolfSSLソースコードのダウンロードとパッチの入手
Qt 5.15 に対応した wolfSSL はもう間もなくの公開に向けて準備中です。また、Qt 5.15 のSSL/TLSバックエンドをwolfSSLに変更するためにパッチが必要となります。これらの入手については、公開までの少しの間[wolfSSL](mailto:info@wolfssl.co.jp) までお問い合わせください。

###2.wolfSSLのビルド
入手したwolfSSLをビルドします。

--prefix オプションで wolfSSL ライブラリーを任意のフォルダーにインストールします。

```
$ cd wolfssl
$ ./configure --enable-qt --enable-qt-test --enable-alpn --enable-rc2 --prefix=/custom/install/path
$ make
$ make check
$ sudo make install
```

###3.リンク用の環境変数を設定
QtのSSL/TLSバックエンドとしてwolfSSLをリンクするために、次の環境変数を設定します。
Step２の-prefix オプションで指定した、/custom/install/pathをライブラリーパスとして指定します。

```
$ export WOLFSSL_LIBS="-L/custom/install/path/wolfssl-install/lib -lwolfssl"
```

###4.Qtのソースコードをダウンロード
今回は、Qt のバージョン 5.15.2 を使用します。qt5 ディレクトリへ5.15.2 ブランチをクローンします

```
$ git clone git://code.qt.io/qt/qt5.git --branch v5.15.2 
```

qt5 ディレクトリでサブモジュールを初期化します

```
$./init-repository --module-subset=qtbase
```

コンパイル時間節約のために、"--module-subset=qtbase"を指定していますが、フルモジュールでコンパイルするさいには、"--module-subset=qtbase"を除きます。

###5.Qtにパッチを適用
QtのSSL/TLSバックエンドをwolfSSLに変更するために、パッチを適用します。ステップ１で入手したパッチをqt5フォルダーに配置しておきます。

```
$ cd /path/to/qt5/qtbase
$ git apply -v ../wolfssl_qt_src.patch
```

###6.Qtをビルド
ビルド用のフォルダを作成し、Qtのビルドコンフィグを実行します。

```
$ cd ../../
$ mkdir qt_build
$ cd qt_build
$ ../qt5/configure -wolfssl-linked -I/path/to/wolf-install/include/wolfssl -I/path/to/wolf-install/include
```

コンフィグが終了したら、make を実行します。

```
$ make
```


##QtのサンプルGUIプログラムを動かしてみる
出来上がった Qt のサンプルGUIプログラムを動かしてみます。また、Wireshark を使ってTLS通信を覗いてみます。
###1.サンプルGUIプログラムの起動
```
$ cd /path/to/qtbase/examples/network/securesocketclient
$ ./securesocketclient
```

次の画面が表示されるので、"Connect To Host"をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/683403/ba644e2e-2879-cbd0-a140-9afde529420b.png)

接続の様子は、wireshark で覗いてみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/683403/be28edad-f947-e057-f40e-6b17bb9c0252.png)

TLS 1.3 で接続出来ているようです。

あらためて、wolfSSL を使用しているか確認してみます。

```
$ ldd securesocketclient
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/683403/97c1c2f7-dd77-21ac-928b-4c0c07c1d0d5.png)

wolfSSL を使用してるようです。

##まとめ
今回は wolfSSL を Qt 5 の最新版バージョン 5.15　のSSL/TLSバックエンドとして使用する方法を紹介しました。

wolfSSLに関する詳細なドキュメント、製品情報については下記を参照してください。wolfSSLは、ソフトウェアの内容は同じですが無償のオープンソース版と有償商用版のデュアルライセンスとなっています。製品への組み込みの際は商用ライセンス契約が必要です。

wolfSSLのQtサポートまとめ：https://www.wolfssl.jp/qt_support/
ドキュメント：https://www.wolfssl.jp/docs/
英語サイト：https://www.wolfssl.com/
日本語サイト：https://www.wolfssl.jp/
Twitter: https://twitter.com/wolfSSL_Japan/
nasmの作法

#概要

nasmの作法、調べてみた。

#環境

windows vista 32bit
visual studio 2010
nasm 2.15 win32

#参考にしたページ

https://qiita.com/0gajun/items/e772e1223f6e596eb362

#実行

visual studio 2010のコマンドプロンプトで実行。

```
Setting environment for using Microsoft Visual Studio 2010 x86 tools.

C:\Program Files\Microsoft Visual Studio 10.0\VC>cd c:\nasm

c:\nasm>nasm -fwin32 hello.asm

c:\nasm>link hello.obj /ENTRY:main /SUBSYSTEM:CONSOLE /defaultlib:kernel32.lib
Microsoft (R) Incremental Linker Version 10.00.30319.01
Copyright (C) Microsoft Corporation.  All rights reserved.


c:\nasm>hello
Hello, World

c:\nasm>
```

以上。
RDCセミコンダクター

ハードオフで猛牛さんのプリントサーバを220円で買ってきてばらしてみました。

中にはRDCセミコンダクターのR2886が入っていました。FLASHはEONのEN29LV160が使われています。EthernetのPHYはRTL8201CPでRJ45コネクタはトランス内蔵型です。水晶発信器は25MHzが使われています。

FLASHに0845とあるので2008年くらいの製造のようです。

このチップの情報はほとんど無いのですが、RISCという情報がありましたがおそらく中身は80186互換のアーキテクチャではないかと思われます。

http://en.techinfodepot.shoutwiki.com/wiki/RDC

R2886はR2880にUSBを付けたもののようです。

JTAG-Likeな開発支援があるようですが、このターゲットは直接はでてなさそうです。

[古いプリントサーバ](https://qiita.com/yamori813/items/25968cf66f031a7a1c75)でも80186を使ったものを見た記憶があります。

RDCには486相当のSOCもあり、これをHACKしているページがありました。

https://sites.google.com/site/bifferboard/Home

こちらも苦戦しているようで、結構ハードル高いです。

この手のモジュールは2000年くらいからあり、ずっとx86系でコードベースが変わらないので、デバッグの必要が無くなっているのかもしれません。
MSVCx64関数呼び出し規約のメモ

MSVCが`/Od`で吐き出すアセンブリの話です。
最適化をかけると呼出し自体が消滅（inline）したり、余分なバックアップがなくなったりします。

x86では`__cdecl`、`__stdcall`などいろいろな呼び出し規約がありましたが、x64では`__fastcall`に一本化（もはや区別する意味が無い）されました。

# レジスタ

https://www.mztn.org/lxasm64/amd04.html

### 引数

引数は先頭4つまでがレジスタ渡しになりうる。この4つというのは整数、浮動小数合わせたもの。

0番目引数は、整数なら`rcx`浮動小数なら`xmm0`。
1番目引数は、整数なら`rbx`浮動小数なら`xmm1`。
2番目引数は、整数なら`r8`浮動小数なら`xmm2`。
3番目引数は、整数なら`r9`浮動小数なら`xmm3`。

例えば`f(int,int,float,float)`のようなときは`f(rxc,rbx,xmm2,xmm3)`となる。
`f(rxc,rbx,xmm0,xmm1)`ではない点に注意。
また、`f(int,int,int,int,float,float)`では4,5番目は浮動小数レジスタが余っているが引数に利用されずスタック渡しとなる。

### 引数

戻り値は、整数なら`rax`、浮動小数なら`xmm0`。
整数の場合は引数で用いるレジスタとは別だが、浮動小数では戻り値と0番目引数が同じく`xmm0`を用いる。排他ではなく呼び出し直前と直後で解釈が変わるということ。

### バックアップ

下記レジスタの状態をバックアップするのは呼び出された側の役目。（そもそも使わない場合はバックアップもスキップされるので注意）
それ以外のレジスタは呼び出され側で書き換え自由なので、ある意味呼び出し側で（必要に応じて）バックアップが必要ということになる。

`R12~R15`（汎用整数）、`RBX,RDI,RSI`（一応用途はあるけど実質汎用整数）、
`XMM6~XMM15`（汎用浮動小数）、
`RBP`（基本的にベースポインタ?）

https://docs.microsoft.com/ja-jp/cpp/build/x64-software-conventions?view=msvc-160


# スタック

引数にスタックを使わない場合でも、呼び出し前に40Bを自由に使える領域として確保しておく必要があります。
40Bの内訳は、アラインメント8+レジスタ引数バックアップ用8*4で40とのこと。
アラインメントが揃っているなら8は不要ですが、スタックのアラインメントは16Bで関数呼び出し時に戻りアドレスのバックアップで8B積まれているので、アライメントが崩れています。
http://herumi.in.coocan.jp/prog/x64.html

```
sub rsp 40
```

実際にMSVCが吐くアセンブリでは、スタックの確保の回数はなるべく少なくするようになっているようで、関数の初めにローカル変数や引数用の分とまとめて確保（`rsp`を減算）しているようです。

また、呼び出され側で引数を受け取った場合はとりあえず、呼び出し側が確保してくれた引数用スタックの32Bに放り込んでいます。（引数有関数では冒頭は以下のような決まり文句になっています）

```
f:
mov DWORD PTR [rsp+32], r9d ; 3番目整数引数
mov DWORD PTR [rsp+24], r8d ; 2番目整数引数
mov DWORD PTR [rsp+16], edx ; 1番目整数引数
mov DWORD PTR [rsp+8], ecx  ; 0番目整数引数
// push ?? ; レジスタのバックアップ
// push ??
sub rsp, ?? ; スタックの確保
```

これを一見すると、スタック確保前にスタック使っているように見えるのですが、movしている先のスタックは呼び出し元の関数のスタック領域です。（rspより下なので確保済み領域ですね）

| アドレス | 内容 | 確保した関数 | 使う関数 |
|:-:|:-:|:-:|:-:|
| 0x00  | ローカル変数  | Callee | Callee |
| 0x08 | レジスタのバックアップ | Callee（push） | Callee |
| 0x10  | ReturnAddress         | Caller（jmp）  | Callee  |
| 0x18  | アラインメント          | Caller    | -  |
| 0x20  | 5番目引数              | Caller    | Callee  |
| 0x28  | 4番目引数              | Caller    | Callee  |
| 0x30  | 3番目引数バックアップ用  | Caller    | Callee  |
| 0x38  | 2番目引数バックアップ用  | Caller    | Callee  |
| 0x40  | 1番目引数バックアップ用  | Caller    | Callee  |
| 0x48  | 0番目引数バックアップ用  | Caller    | Callee  |
| 0x50  | ローカル変数  | Caller  | Caller      |

### ベースポインタとRBP

`rbp`はベースポインタということで、上の表で言うならCalleeに居る時、`rbp=0xXX38`と期待されると思うのですが、実際に吐かれるアセンブリではその限りではないようです。
というのもスタックの確保は基本的に関数の先頭でまとめて`sub rsp`で済ませてしまうため、ローカル変数や引数の基準点は`rsp`からでも計算できますし、それでなくとも基準点さえ固定であれば何もReturnAddressが入っているアドレスを基準にする必要もありません。
なので微妙な位置に`rbp`をセットすることもあるようです。特に、`rsp`は先の関数呼び出しのために確保してあげる40B+αも含めたものになっているので、そこから40B+αを足した分（量的には引いた分）を`rbp`にセットしているようです。

# おまけ

これ便利

https://godbolt.org/z/K4xn517To
greetingを使ったstring型（HelloWorld)

package HelloWorld2;

public class HelloWorld2 {
//　メインプログラム
	public static void main(String[] args) {
		// TODO 自動生成されたメソッド・スタブ
      String greeting = "Hello";
      String name="World";
      System.out.println(greeting + name );
  }
}

①プロジェクト・パッケージ・クラスを作成
②String greeting = ();
③String neme =();
④System.out.println(+);
[awk]encodeとdecode

- Web開発において、データの受け渡しの際に必要なURLのencodeとdecodeがある。
- 汎用的であり頻度が多い処理のため、jsやphp,perl等では標準やライブラリとして提供されていることがある。
- 今回はそのような処理をawkで処理する方法を記録する。

## 環境
- Mac OS X 10.15.6
- GNU Awk 5.1.0

## 結果
- 結果の記述は以下の通り。

```awk:main.awk
BEGIN{
	print "normal : " ARGV[1]
	print "encode : " encode(ARGV[1])
	print "decode : " decode(encode(ARGV[1]))
}

# encode関数
function encode(s){
    if(s=="") error("encode対象を指定してください。")
    command="printf " s " | od -tx1 -An | xargs"
    command | getline d
    close(command)
    # gensubはgawk拡張のため、nawkもしくはmawkの際にはgsubを利用。
    result=gensub(/([0-9a-z]{2}) ?/,"%\\1","g",d)
    result=toupper(result)
    return result
}

# decode関数
function decode(s){
    if(s=="") error("decode対象を指定してください。")
    l=tolower(s)
    gsub("%","\\x",l)
    command="printf \"" l "\""
    command | getline result
    close(command)
    return result
}

function error(m){
    print(m) > "/dev/stderr"
    exit(1)
}
```

- 表示結果は以下。

```bash
$ awk -f main.awk "私はt_o_dと申します。"

normal : 私はt_o_dと申します。
encode : %E7%A7%81%E3%81%AF%74%5F%6F%5F%64%E3%81%A8%E7%94%B3%E3%81%97%E3%81%BE%E3%81%99%E3%80%82
decode : 私はt_o_dと申します。
```

## 補足

### encode
- awkでの対象文字列のダンプ及び整形はOSコマンド(od,xargs)で任せており、記述を短くしている。
- また%付与のために利用しているgawk拡張のgensub関数は、グルーピング目的として利用している。
    - 柔軟性を考慮する場合、gsub関数を利用する。
    - **※gsubの場合、「グルーピングの利用不可」及び「対象の破壊的変更」があるので注意。**

## まとめ
- awk単体での利用ではなく、OSコマンドとの組み合わせ次第で記述の簡略化と可読性を図れることを実感。
- ただawkと外部コマンドとの行き来によって生じる「速度・負荷・汎用性の低下」の考慮も重要。

## 参考
- http://www.kt.rim.or.jp/~kbk/gawk-30/gawk_13.html
- https://stackoverflow.com/questions/3728049/using-awk-printf-to-urldecode-text
Eclipse JDKについて

Eclipse フルバージョンなら基本的にJDKのダウンロードはいらない

しかし、EclipseではEclipse自身が持っているコンパイラを使用するためJDKは必要無いのですが、JavaDocなどの参照を行う場合にはJDKの中に含まれるJREを指定しておく必要があるよう。
stack machineを愛でる。 その6

#概要

stack machineが、好きだ。
練習問題、やってみた。

#練習問題

1から70までを、表示せよ。

#考え方

メモリーアクセスは、無いので、変数を使う。set,getを使う。

- set	スタックの二番目を変数として、一番目の値をセット、1個減る。
- get	スタックの一番目を変数として、その値をセット

変数xは、表示用。
変数iは、カウント用。
if　使ってループする。
loopとskipは、ラベル。


#サンプルコード

```
  push  "x"
  push  ""
  set 
  push  "i"
  push  "0"
  set
loop  push  "i"
  push  "i"
  get
  ++
  set
  get
  push  "x"
  push  "x"
  get
  push  "i"
  get
  add
  push  " "
  add
  set
  push  "i"
  get
  push  "70"
  >
  !
  if  skip
  jp  loop
skip  end
```

#成果物

https://embed.plnkr.co/plunk/WorSiZzVAgyE0nlS


以上。
Cryptocurrencyの価格取得に便利なPythonライブラリ

### cryptocompare
API Keyとかも取得する必要がなく、使いやすいです。

https://github.com/lagerfeuer/cryptocompare

インストール via pip

```zsh
$ pip install cryptocompare
```

### cryptofeed
エクスチェンジプラットフォームを指定して、価格を取得することが可能です。

https://github.com/bmoscon/cryptofeed

インストール via pip

```zsh
$ pip install cryptofeed
```

### ccxt
エクスチェンジプラットフォームを指定して、価格を取得することが可能です。
cryptofeedより多くのプラットフォームをカバーしています。

https://github.com/ccxt/

インストール via pip

```zsh
$ pip install ccxt
```


簡単に価格を取得したい場合は`cryptocompare`、複数のエクスチェンジプラットフォームから価格を取得して比較するような用途の場合は`ccxt`がいいと思います。
【Bootstrap】モーダルを1つのページに2つ実装する時に注意しなければならないこと

#Bootstrapモーダルを1つのページに2つ実装する時に注意しなければならないこと
モーダルを1つのページに2つ実装すると、どちらのボタンを押しても片方のモーダルウィンドウしか表示されません。
この記事ではその解決法をご紹介します。

![modal.gif](https://j.gifs.com/XQ6G85.gif)

###現状のコード

```html.erb
<!-- Button trigger modal -->
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#exampleModal">
    モーダル1
</button>
  
  <!-- Modal -->
  <div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
    <div class="modal-dialog">
      <div class="modal-content">
        <div class="modal-header">
          <h5 class="modal-title" id="exampleModalLabel">モーダル1</h5>
          <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
        </div>
        <div class="modal-body">
         モーダル1だよ！！！
        </div>
        <div class="modal-footer">
          <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
          <button type="button" class="btn btn-primary">Save changes</button>
        </div>
      </div>
    </div>
  </div>

  <!-- Button trigger modal -->
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#exampleModal">
    モーダル2
</button>
  
  <!-- Modal -->
  <div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
    <div class="modal-dialog">
      <div class="modal-content">
        <div class="modal-header">
          <h5 class="modal-title" id="exampleModalLabel">モーダル2</h5>
          <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
        </div>
        <div class="modal-body">
          モーダル２だよ！！！
        </div>
        <div class="modal-footer">
          <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
          <button type="button" class="btn btn-primary">Save changes</button>
        </div>
      </div>
    </div>
  </div>
```

このままだとモーダル2のボタンを押してもモーダル1のウィンドウが出てきてしまいます💧
　

###解決方法
どのボタンがどのモーダルウィンドウを表示させるかは``<button>``タグのdata-target属性を使って定義しており、data-target名と同じid名である``<div class="modal fade">``のモーダルが表示されます。
つまり、モーダル2のdata-target名をモーダル1とは別のに変更し、ボタンのコードの下にある``<div class="modal fade"~>``のid名を変更したdata-target名と同じにすれば問題は解決されます。

```
#変更前
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#exampleModal">
    モーダル2
</button>

 <div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">

#変更後
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#exampleModal2">　#data-bs-target="#exampleModal"　→　data-bs-target="#exampleModal2"
    モーダル2
</button>

 <div class="modal fade" id="exampleModal2" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">　#id="exampleModal"　→　id="exampleModal2"
```

![modal2.gif](https://j.gifs.com/w0jNXR.gif)
深層学習の、今の限界を示す記事をメモっとく。N個（まだ、N=2)。

# 概要
深層学習が、まだまだだ、というような内容の記事を、時々、目にするが、目にして流れていくので、メモっとく。

#メモ
## AIはまだ、ヘイトスピーチを見分けるのが苦手＝米最新研究
https://www.technologyreview.jp/s/246861/ai-still-sucks-at-moderating-hate-speech/

### 記事の日付など
by Karen Hao2021.06.09

### 記事の内容

すべて記事の引用。

>最新の研究で、科学者たちが最先端AIシステム4種類にヘイトスピーチを検出させるテストを実施したところ、4種類すべてのAIシステムが悪質な文章と問題のない文章の識別に苦労していることが明らかになった

　
>問題のない発言の最中にある冒涜的な表現や、被害を受けた人たちが繰り返し発した中傷的な言葉、ヘイトスピーチを糾弾する活動において元のヘイトスピーチを引用あるいは言及する例（カウンター・スピーチ）などだ。

### 記事に対するコメント
「ヘイトスピーチを引用」とかは、それを引用と判断するのは難しいと思うが、逆に、そんなことができてないのだーーー、とちょっと、気になった。

## トラックから信号機が次々出てくる？　自動運転AIの画像認識結果が話題に　対策は？
https://www.itmedia.co.jp/news/articles/2106/14/news098.html


### 記事の日付など
2021年06月14日 15時45分 公開

### 記事の内容

すべて記事の引用。

>前方を走るトラックが、実際に信号機を荷台に載せていたのだ。どうやらこれを自動運転システムが認識してしまった結果のようだが、

(図：記事引用）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/342207/80ad5261-e1fa-4181-96b8-531c8d8eaa73.png)

>Redditの投稿によると、この誤認識を起こしたのは米TeslaのEV「Model 3」だという。

### 記事に対するコメント
深層学習の場合、
この記事の場合とか、車に車を積んだ状態とか、人であれば、『あっ珍しいものみた、（嬉しい）』的な場面は、まだ、弱い感じがする。
しかし、人であっても、一旦、『は？』となるわけで、深層学習にも、そのような処理を組めばいいだけかも。。。

# まとめ
特にありません。記事にする意味があるか不明ですが、、、たまに、不明なものでも役立つことがあるので。
Goの実行時にimportエラーでハマった話。

## はじめに
Goの勉強中、実行するとimportエラーでハマったのでその時に調べた内容を記録しました。

## エラー内容
ターミナルでmain.goファイルのある階層まで移動し、以下のコマンドで実行する。

```
$ go run main.go
```
すると、以下のエラーが表示された。

```
main.go:5:2: package my_app/config is not in GOROOT (/usr/local/Cellar/go/1.16.5/libexec/src/my_app/config)
```

## エラーが発生したときの状況
main.goファイルにconfigディレクトリ内のconfig.coファイルをimportしようとしたところでエラーが発生。

```main.go
package main
import (
	"fmt"
	"my_app/config"  //←ここの読み込みができずエラーが発生
)
func main() {
...
```
main.goファイルと、configディレクトリの位置関係

```Go
    $GOPATH/src/my_app/main.go            //main.goファイル
    $GOPATH/src/my_app/config/config.go   //configディレクトリとconfig.goファイル
```
（※ GOPATHの調べ方：https://kazuhira-r.hatenablog.com/entry/2021/01/03/222459 ）

## 解決手順
importエラーが出ているmain.goファイルのモジュールファイルを作成する。main.goファイルがあるパスまでターミナルで移動し、以下のコマンドを実行する。（例として、今回はモジュール名をmainとして実行。）

```
$ go mod init [モジュール名]
```
```
$ go mod init main
```

go.modファイル（main.goのモジュールファイル）がmain.goファイルと同じ階層に作成される。

次に、エラーが起きていたmain.goファイルのimportの箇所を変更する。

```main.go
package main
import (
	"fmt"
	"main/config"  //←ここを変更
)
func main() {
...
```
ここでエラーが消えるはずなので、main.goファイルを実行し処理が通ればOK。

```
$ go run main.go
```

## 解説
Goを実行する際は「GOPATHモード」「モジュールモード」が存在し「.mod」のモジュールファイルがない場合は「GOPATHモード」と認識される。その結果、GOPATH内にimportで指定したファイルがない場合にエラーとなる。

importの変更は、「 (go.modに記載したモジュール名) + (go.modのある場所からのパッケージの相対パス)を探しに行く」ことを考慮して変更すること。（https://qiita.com/fetaro/items/31b02b940ce9ec579baf ）

## その他参考
・https://qiita.com/spiegel-im-spiegel/items/5cb1587cb55d6f6a34d7
・https://note.crohaco.net/2019/golang-package/
フレームワーク・ライブラリから学ぶpython

※私個人の主張もあります。
追記予定

スキルは、国内問わず、優秀なフレームワーク、ライブラリから得られるものが多いと思います。

# Djangoより
https://github.com/django/django
↑high-level Python Web framework 

## アプリケーションはどのように実行されるのか

①フォルダ構成は下記の通りで`__main__.py`を作成しておく。
/プロジェクト名/アプリ名/`__main__.py`

②カレントディレクトリを/プロジェクト名にしておき、下記コマンドを実行

```
python -m アプリ名
```
③`__main__.py`が実行される。
※カレントディレクトリがアプリのルートになるので、import時の問題にも遭遇しにくいメリットがありますね。

## 同じモジュールからimportする場合はカッコを活用する。
```py
from .resolvers import (
    LocalePrefixPattern, RegexPattern, RoutePattern, URLPattern, URLResolver,
)
```
エレガントですね。ワイルドカードは避ける方向で行きましょう。

## クラスの役割(責務)はコメントとして記述する
>class ContextList(list):
>  """
>    A wrapper that provides direct key access to context items contained>
>    in a list of context objects.
>    """

責務をコメントに書くことで、読み手に対して、どのようなクラスかを明確に示す事ができます。
責務が沢山あると、クラスを分割した方がよいとかの気づきになりますから（単一責任の原則）


## プロパティは@propertyを活用する。
```
self.__name ⇒サブクラスを含めた外部から呼び出しをしない
self._name　⇒外部から呼び出しをしない
self.name　⇒外部へ公開される属性(public)。 
プロパティ　⇒外部へ公開される。ゲッタ、セッター時に何らかの処理をしたいのであれば
　　　　　　　プロパティとして実装するのが良い
```
オブジェクトのデータはプロパティ（特性）またはデータ属性、振る舞いはメソッドで実装しましょう。
⇒プロパティはデータ属性をクラスのパブリックインターフェイスとして安全に公開するためにある。
⇒プロパティ内でバリデートの実装も多い。
⇒setterを実装しないプロパティも多数ある。

下記の記事はダンダーの説明が分かりやすかったので、参考に
https://qiita.com/shiracamus/items/5331cd89b202953403dd

## pythonはオブジェクト指向の言語であるが、関数をまとめたモジュールの実装もあり
django/django/template/loader.pyを参考に

## グローバルな定数/変数宣言をするモジュールクラスもある。

```py:一部引用
DEBUG = False
DEBUG_PROPAGATE_EXCEPTIONS = False
ADMINS = []
```
すべて大文字

## elseではなく早期リターンの活用

```py:django/core/paginator.pyより
if callable(c) and not inspect.isbuiltin(c) and method_has_no_args(c):
    return c()
return len(self.object_list)
```
早期リターンはコードを簡潔にすることが多いですね

# pythorchより
https://github.com/pytorch/pytorch
⇒Deep neural networks built on a tape-based autograd system

## 型ヒントを実装する

```py:引用

def bundle_inputs(
        model: torch.jit.ScriptModule,
        inputs: Union[Optional[Sequence[Tuple[Any, ...]]], Dict[Callable, Optional[Sequence[Tuple[Any, ...]]]]],
        info: Optional[Union[List[str], Dict[Callable, List[str]]]] = None,
        *,
        _receive_inflate_expr: Optional[List[str]] = None,
) -> torch.jit.ScriptModule:
```
引数の型、戻り値の型ヒントが明記されている。
Amazonの商品検索を自動化したい

##はじめに##
前回までの記事で楽天APIを使って楽天商品の検索を自動化する記事を書かせてもらいましたが、
今回はAmazonのそんな機能が無いものかといろいろと調べてみました。

商品検索のAPIは昔、AmazonAPIという名前で利用できていたものの現在はポリシーが変更されておりAmazon Product Advertising APIに代わっています。これを利用するには、Amazonアソシエイトプログラムに参加・承認を受けなければいけません。（2021/6/14現在。ポリシー変更があったのは2019/1/23）

##Amazonアソシエイトプログラムとは？##
 [Amazonアソシエイト・プログラム](https://affiliate.amazon.co.jp "Amazon アソシエイト・プログラム")

アソシエイトとは、日本語で「協力する、仲間になる」という意味です。
要はAmazonが「紹介料払うからSNSやブログやってるやつら協力してや！そしたら売上倍増やん！」って意味で作ったサービスです。
プログラムに参加すると広告斡旋を介さずに直接Amazonから収益がもらえるようになるという利用者にもお得なWIN-WINなサービスといえます。俗にいうアフィリエイトというものですが今風なんでしょうか名称が違うだけで同じ意味です。

#紹介料の発生するまでの手順#
１，アソシエイト・プログラムに参加する 
**アソシエイトID**が発行されます
**[アソシエイト・セントラル](https://affiliate.amazon.co.jp/home "アソシエイト・セントラル")**にログインできる。
２，アソシエイト・セントラルのページで好きな商品のリンク先を取得。
//（商品のリンク先にアソシエイトIDが組み込まれます）
３，ツイートやブログにリンクを貼る。
４，誰かがそのリンクをクリックして商品を購入する。
５，商品売上げの3～8％が紹介料としてもらえる。

#アソシエイト・セントラルとは？#
アフィリエイトに特化したサービスサイトです。紹介したい商品を選ぶとリンク作成からHTML化までボタン１つで素敵なリンク先を自動で生成してくれます。また、紹介料・クリック数の推移も見れますし複数アカウント、複数サイトの収益の収集・推移分析もできます。いうなれば完全にビジネス用ですね。


##Amazon Product Advertising API（PA-API）##
アソシエイト・セントラル内の１つの機能で、商品をAPIを使って検索できる機能です。
ただし、APIの利用には収益サイトやSNSですでに売上実績が必要です。
以前のAmazonAPIは楽天APIと同様にアカウントさえ持っていればAPIの利用ができたのですが、PA-APIはAmazonアカウントだけでは利用できません。まず、上のAmazonアソシエイト・プログラムに参加する必要があります。（既にAmazonアカウントをお持ちの方は紐づけする作業になります）このとき、自前のサイトかSNSのアカウントサイトのURLが必要になります。**これが承認されないとAPIが利用できません。**
<br>


<div><details><summary><strong>登録後に送られてくるメール内容</strong></summary>
Amazon アソシエイト・プログラムへようこそ！

〇〇〇〇 さん、Amazon アソシエイト・プログラムへお申し込み頂きありがとうございます。
現時点で、あなたはアソシエイト・セントラルで作成したアソシエイトリンクを、あなたのWebサイトやSNS（Twitter、Facebook等）に掲載いただくことができます。ただし、アソシエイトパートナーはアカウントを維持するために、アカウント作成から180日以内に少なくとも3つの適格販売（下記「運営規約」参照）が必要です。3つの適格販売が発生した段階で、当社のチームはアカウントに紐づいているWebサイトまたはSNS（Twitter、Facebook等）を審査し、Amazonのコンプライアンスに準拠していることを確認します。

未成年者へのご注意 もしあなたが未成年者の場合、Amazonアソシエイト・プログラム運営規約上、アソシエイトアカウントの作成と運用は原則禁止されています。Amazonアソシエイト・プログラム運営規約 をご確認ください。例外的に、もし未成年者がアカウントの運用を希望する場合は、今後正式に参加が承認された際に「未成年者のプログラム参加同意書」にもとづく表明と保証が必要です。まずは、あなたのサイトにアソシエイトリンクを設置して活動を開始してください。アカウント作成から180日以内に少なくとも3つの適格販売（下記「運営規約」参照）が発生した段階で、<strong>Amazonのチームはアカウントに紐づいているWebサイトまたはSNS（Twitter、Facebook等）を審査し、Amazonのコンプライアンスに準拠していることを確認します。一定の売り上げがない限りは審査は開始されない</strong>という点に、ご留意ください。売り上げが発生しお客様のお申込みの確認が開始・承認された場合は「Amazo.co.jp アソシエイト・プログラム－アプリケーションが承認されました」という件名の審査の結果を伝えるメールが送信されます。この件名のメールを受け取ってから、こちらのフォーム から保護者同意書の取得についてお問い合わせください。
</details></div>
<br>
要約すると審査を受ける条件として上の「紹介料金が発生する手順」で紹介料(一定の売上げ)が発生しないと、そもそもAPI利用できないよ。
ということです。AmazonのAPIを試せるようになるまでには一定の収益を１８０日以内に上げないといけなくなりました。正直かなりめんどくさいですが、がんばりたいと思います。
【VBA】オートフィルターの重複しないリストを配列に入れよう

Excelのオートフィルタで▼を押すと、

重複しないリストが出てくる。
これを配列に入れたい！って思ったことありませんか？
特にcsvデータで数千、数万行のデータを処理する場合、知っておいた方がいい知識です。

ググって調べてみたのですが、どれも冗長なコードが多くスマートなコードがなかったのでここで紹介します。

```
    Dim Dic As Dictionary, Data As Variant,i As Long
    Set Dic = CreateObject("Scripting.Dictionary")
    Data = ActiveSheet.cells(1,1).currentRegion.Offset(1,0)  

    i = 1
    Do While Data(i, 1) <> ""

        buf = Data(i, 2)
        
        If Not Dic.Exists(buf) Then

            Dic.Add buf, buf
        
        End If

        i = i + 1
    Loop
```

Dictionaryオブジェクトとは、連想配列を使ってデータをまとめて管理できるオブジェクトです。Dictionaryオブジェクトに関して詳細を知りたい方は下記サイトを参考にしてください。

https://valmore.work/excel-vba-dictionary/#Dictionary
Rustの便利イテレータ scan と fold

# イテレータ
Rustには様々な便利なイテレータがあります。ここでは、しばしば使うものの、頻繁には使わないイテレータである[scan](https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.scan)と[fold](https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.fold)を紹介します。
どちらも、「いままでの情報」をもちつつ、ループを走査したいような場合に有効なイテレータです。「いままでの情報」をもてると何がうれしいかというと、`mut`な変数をループの外に用意する必要がなくなり、コードの見通しが良くなります。

## fold
まずは、特に癖もなく、扱いやすい`fold`からです。例えば、イテレータの合計を求めたい場合などに使用することができます。

```rust
let v = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let sum = v.iter().fold(0, |sum, x| sum + x);
println!("{}", sum);  // 55
```

基本的には見たままかと思いますが、第一引数に`0`を与えています。`max`などのような、イテレータが空であった場合に対応するために`Option`でラップするようなインターフェースにしないためだと思います。

ちなみに、合計を計算するためには[sum](https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.sum)というメソッドも使うことができますが、こちらは出力に型を明示する必要があります。また、`Add`トレイトと`Default`トレイトが定義されていればいいというようなインターフェースにはなっておらず、`usize`などのプリミティブな型にしか使えないようです([参照](https://doc.rust-lang.org/std/iter/trait.Sum.html))

```rust
let v = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let sum: u64 = v.iter().sum();
println!("{}", sum);  // 55
```

## scan
次に、`scan`です。こちらは少し癖があります。先ほどの`fold`がイテレータから一つの値を返すメソッドだったのに対して、こちらの`scan`はイテレータの要素数と同じ数だけ値を返すようなメソッドになります。たとえば、[NumPy](https://numpy.org/)の[cumsum](https://numpy.org/doc/stable/reference/generated/numpy.cumsum.html)関数のように接頭辞和を求めたい場合は、次のように書くことができます。

```rust
let v = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let cumsum: Vec<_> = v.iter().scan(0, |cum, x|{
    *cum += x;
    Some(*cum)
}).collect();
println!("{:?}", cumsum);  // [1, 3, 6, 10, 15, 21, 28, 36, 45, 55]
```

`fold`同様第一引数に初期状態を与えるほか、`scan`については、クロージャの中の処理が主に2つ必要になります。

1. 次の要素の処理に使うための情報 (`cum`の参照先への代入に当たる部分)
1. イテレータとして返す値 (`Some(*cum)`というクロージャの返り値に当たる部分)

まずは、1. について、クロージャの第一引数には`mut`な参照が与えれるようになっており、これは、つまるところ、普通にループで書いたときにループの外に用意するような`mut`な変数にあたります。ただし、所有権は持っておらず、あくまで参照なので、参照先の値を変更するためには`*`によって参照を外してやる必要があります。
初期状態を`Box`でラップし、`Copy`トレイトによって変数のアドレスが変わらないようにして少し覗いてみると、ループを通して参照先が変化していないことがわかりそうな気がします。

```rust
let v = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let cumsum: Vec<_> = v.iter().scan(Box::new(0), |cum, x|{
    println!("{:p}", *cum);
    **cum += *x;
    Some(**cum)
}).collect();
println!("{:?}", cumsum);  // [1, 3, 6, 10, 15, 21, 28, 36, 45, 55]
```
```:出力例
0x5586a9ad7ad0
0x5586a9ad7ad0
0x5586a9ad7ad0
0x5586a9ad7ad0
0x5586a9ad7ad0
0x5586a9ad7ad0
0x5586a9ad7ad0
0x5586a9ad7ad0
0x5586a9ad7ad0
0x5586a9ad7ad0
[1, 3, 6, 10, 15, 21, 28, 36, 45, 55]
```

そして、2.の、クロージャの返り値について、これはこのイテレータに対して、`next`メソッドを呼んだ際の返り値になります。`next`メソッドの返り値は`Option`でラップされており、`None`が返ってくるとそのイテレータは終了したとみなす実装となっていることが多いです。ここでも例にもれず、`Some`でラップした値を返すことで、イテレータを続けます。`Some`の中で`*`によって参照外しをしているのは、ここで参照を返してしまうとライフタイムの制約に違反するためです。明示的に`clone`メソッドを呼んでもいいと思います。

# さいごに
`fold`と`scan`の中間というか、`scan`の`mut`な参照をなくし、`fold`のようにクロージャの前の返り値を次のクロージャの第一引数に与えるというようなイテレータがあれば微妙に便利な気もするのですが、そういうのは(少し探した限りでは)ないようです。

何か思い出したら追記する可能性があります:bow_tone1:
【メモ】next.js typescript Evergreen ISR 最小構成 + format

## setup

```bash
$ npx create-next-app --example with-typescript with-typescript-app
```
see: https://github.com/vercel/next.js/tree/canary/examples/with-typescript

```bash
$ npm install --save evergreen-ui
```
see: https://evergreen.segment.com/introduction/getting-started
see: https://github.com/segmentio/evergreen

```pages/index.tsx
import React from 'react'
import ReactDOM from 'react-dom'
import { Button } from 'evergreen-ui'

const IndexPage = () => (
  <Button>I am using 🌲 Evergreen!</Button>
)

export default IndexPage
```

## ISR

```pages/index.tsx
import React from 'react'
import ReactDOM from 'react-dom'
import { Button } from 'evergreen-ui'
import {sampleUserData} from '../utils/sample-data'
import { GetStaticProps } from 'next'

type Props = {
  data: typeof sampleUserData
}

const IndexPage = ({data}:Props) =>{
  return (<><ul>{data.map((x)=><li key={x.id}>{x.name}</li>)}</ul>
  <Button>I am using 🌲 Evergreen!</Button></>)
}

export const getStaticProps: GetStaticProps = async () => {
  return { props: { data: sampleUserData }, revalidate: 60 }
}

export default IndexPage

```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62209/3ba6e88b-1b8c-f379-23f5-b30bd9f95f1f.png)

see: [インクリメンタル静的再生成 (Incremental Static Regeneration; ISR)](https://qiita.com/thesugar/items/47ec3d243d00ddd0b4ed#%E3%82%A4%E3%83%B3%E3%82%AF%E3%83%AA%E3%83%A1%E3%83%B3%E3%82%BF%E3%83%AB%E9%9D%99%E7%9A%84%E5%86%8D%E7%94%9F%E6%88%90-incremental-static-regeneration-isr)

## format

```..vscode/settings.json
{
    "editor.formatOnSave": true,
    "editor.codeActionsOnSave": {
        "source.fixAll.eslint": true,
        "source.organizeImports": true // import 自動整列 & 不要定義の削除
    },
    "editor.defaultFormatter": "esbenp.prettier-vscode"
}
```
after saved.

```pages/index.tsx
import { Button } from "evergreen-ui";
import { GetStaticProps } from "next";
import React from "react";
import { sampleUserData } from "../utils/sample-data";

type Props = {
  data: typeof sampleUserData;
};

const IndexPage = ({ data }: Props) => {
  return (
    <>
      <ul>
        {data.map((x) => (
          <li key={x.id}>{x.name}</li>
        ))}
      </ul>
      <Button>I am using 🌲 Evergreen!</Button>
    </>
  );
};

export const getStaticProps: GetStaticProps = async () => {
  return { props: { data: sampleUserData }, revalidate: 60 };
};

export default IndexPage;

```
Unityシーン遷移の方法

#シーン遷移
ブロック崩しゲームを作成中ですが、ボールが下の壁に触れたらゲームオーバーの表示にしようと思います。
まず、初めにProjectからSceneを作成します。
そして、下の壁にBox Colliderをつけます。
当たり判定を行いたい所を調節します。

下の壁に触れたらゲームオーバーにしたいので、
スクリプトを作成し、

```C#
void OnCollisionEnter(Collision collision)
    {
    }
```

↑これを書くことでColliderに触れたらと言う意味になります。(2つ目の引数は変数です)
つまり、下の壁にColliderをついてるので、この中にシーン遷移をするプログラムを書けば、
下の壁に触れたらシーンが切り替わります。

```C#
void OnCollisionEnter(Collision collision)
    {
            SceneManager.LoadScene("GameOver");
    }
```
プログラムはこうなります。
GameOverの部分はシーンの名前です。
出来たスクリプトを下の壁につけます。

SceneManagerを使用する時は

```C#
using UnityEngine.SceneManagement;
```
を忘れずに定義するようにして下さい。
あと、FileのBuild SettingsのScenes in Buildに
メインシーンと切り替えるシーンをドロップ&ドラッグを
して下さい。

そしたら画面が切り替わりますが、触れたら即切り替わります。
なので、１秒後に切り替わるようにしたいのでまた次回記事にしようと思います！！
[Swift] Compositional Layouts の Inner スクロールを検知する

# 前置き

特定の実装をする際に、スクロールのハンドリングをしようと考えていました。

``Compositional Layouts`` では簡単にできると思っていましたが、案外情報がなかったので（英語での情報はちらほら）、自分へのメモ的な部分も含めて記載していきます。

## 1. Inner Scrollとは？

Inner Scrollという名前があるわけではなく、わかりやすくするために呼んでいます。

![Screen Shot](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/175242/9d28dfb0-36e5-f01a-0d38-259b784d3300.png)

このように**入れ子の構造になった画面**でのスクロールを指します。

## 2. 現在地を取得する際の問題点

今までは、このような入れ子の構造を実装する場合 
 1. ``CollectionView`` in ``TableView``
 2. ``ScrollView`` + ``StackView``
などで実現できるかと思います。


1 の場合は、中にある``CollectionView``から親に``Delegate``を渡してスクロールを検知できます。
2 の場合は、``indexPathsForVisibleItems``や``visibleCells``を使って計算することになります。

``Compositional Layouts``で入れ子の構造を実装した場合、``Delegate``が**Innerのスクロールに反応してくれません**。
2 と同じように``CollectionView``のプロパティを使って計算することもできますが、とても冗長な実装になります。



## 3. 解決策

セクションのプロパティである ``visibleItemsInvalidationHandler`` を使うことで解決できます。
![apple](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/175242/f92d20d3-3e17-0a5c-7e53-8505c2d79e60.png)

この ``NSCollectionLayoutSectionVisibleItemsInvalidationHandler`` の中身ですが（名前がクソ長い）

```.swift
public typealias NSCollectionLayoutSectionVisibleItemsInvalidationHandler = (
    [NSCollectionLayoutVisibleItem], 
    CGPoint,
    NSCollectionLayoutEnvironment
) -> Void
```

となっています。１つずつ見ていきましょう。

### ① NSCollectionLayoutVisibleItem

スクロールされた際に表示されている、セルの情報が入っています。
![item](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/175242/ff351be0-5ae2-0f9b-8899-532dd1dc401b.png)

### ② CGPoint

これはそのままですが、スクロールされた際に表示されている、セルの**現在地の座標**を取得することができます。
![Screen Shot swipe](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/175242/213f15ae-d212-3344-1734-233e06333eb6.png)


### ③ NSCollectionLayoutEnvironment

スクロールされた際に表示されている、セルのレイアウト情報が入っています。
![Screen Shot layout](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/175242/62ddf498-375c-ba4a-2a58-520b003c5996.png)

### 現在値を取得

② のCGPointを使って計算することもできます。

または、① の ``NSCollectionLayoutVisibleItem`` には``IndexPath`` の情報が含まれているので、こちらを使用する方が内部的に計算がされており、実装は楽になるでしょう。

ただし、使い方に少しだけ注意が必要です。

![index](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/175242/eaf916bc-6b91-b67b-f9ba-ad24604ec2d9.png)

セルが複数表示されている場合は、余計なIndexも取得されて複数で返ってくるので、その部分の計算は必要になってきます。基本的には、**配列の最後に返ってくるIndex**が現在地のIndexになります。

## 終わりに

一見すると便利な API が用意されてそうでしたが、挙動が少し怪しい？感じもあり...
``Compositional Layouts`` も万能ではないということですね

``SwiftUI`` もスクロールのハンドリングは自前で実装したりするので、Apple にはこの辺の実装を強化して欲いなぁと思ってしまった感じがあります。



## 参考文献

- [Apple - visibleItemsInvalidationHandler](https://developer.apple.com/documentation/uikit/nscollectionlayoutsection/3199096-visibleitemsinvalidationhandler)
- [UICollectionView CompositionalLayout not calling UIScrollDelegate](https://newbedev.com/uicollectionview-compositionallayout-not-calling-uiscrolldelegate)
- [orthogonalScrollingBehavior paging - getting current cell in center](https://developer.apple.com/forums/thread/652035)
- [CompotionalLayouts でセクションごとのcollectionView/cellにアクセスする方法](https://blog.shota-ito.com/2020/08/07/post-648/)

## その他

https://qiita.com/hcrane/items/f16560ebf12b7a12588a
【Swift】AudioToolboxについて

#はじめに
今回は、録音、再生、音声を扱うときに使われるフレームワークであるAudioToolboxについて書きたいと思います。

#AVFoundationとの違い
サウンドを再生するときのフレームワークとしてAVFoundationがあります。この二つの違いを簡単に明記します。

AVFoundation: BGMなどの動画を再生する(AVAudioPlayer)
AudioToolbox: 効果音などの音源を再生する

#AudioToolbox
まずはドキュメントを読みましょう。
[AudioToolbox](https://developer.apple.com/documentation/audiotoolbox)

ドキュメントには`Record or play audio, convert formats, parse audio streams, and configure your audio session.`と書かれています。
訳すと`オーディオの録音または再生、フォーマットの変換、オーディオストリームの解析、およびオーディオセッションの構成`です。

つまり、サウンド再生や[バイブレーション](https://qiita.com/REON/items/5812fc12ba50c91b8d9e)をユーザーに通知するためのフレームワークということですね。

せっかくなので、簡単に音を鳴らして遊んでみましょう。

今回使うもの以外にも[こちら](https://github.com/TUNER88/iOSSystemSoundsLibrary)から様々な音源を選べます！

このように、適当な数だけボタンを用意してください。(ボタンの番号はSystemSoundIDにしました)
![ScreenShot 2021-06-14 0.43.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954451/86e8b62b-9018-3234-8331-ec6edee4ae9a.png)

ViewControllerに以下のように記述します。

```swift
    @IBAction func button1DidTapped(_ sender: Any) {
        sound(id: 1000)
    }
    
    @IBAction func button2DidTapped(_ sender: Any) {
        sound(id: 1010)
    }
    
    @IBAction func button3DidTapped(_ sender: Any) {
        sound(id: 1050)
    }
    
    @IBAction func button4DidTapped(_ sender: Any) {
        sound(id: 1201)
    }
    
    @IBAction func button5DidTapped(_ sender: Any) {
        sound(id: 1310)
    }
    
    @IBAction func button6DidTapped(_ sender: Any) {
        sound(id: 1336)
    }
    
    @IBAction func button7DidTapped(_ sender: Any) {
        sound(id: 4095)
    }
    
    private func sound(id: SystemSoundID) {
        var id = id
        if let soundUrl = CFBundleCopyResourceURL(CFBundleGetMainBundle(), nil, nil, nil) {
            AudioServicesCreateSystemSoundID(soundUrl, &id)
            AudioServicesPlaySystemSound(id)
        }
    }
```

色々な音源を鳴らしてみてください！


#おわりに
今回はAudioToolboxについて書きました。音を扱えると開発の幅も広がりそうですね！