OmniAICreator/Qiita-1.07M huggingface dataset:
俺でもわかるPostgreSQLからMySQLへの移行調査

俺です。

Aurora PostgreSQLから Aurora MySQL5.7への移行は右から左に鼻ほじりながらスッとできるもんではありません
事前調査でいくつか調べることがあったので何調べてたかのメモを残します。



| つまづいたところとかしばき倒しておきたいところ| 読んだ記事 | どうしたか|
|:---:|:---|:---|
|移行元と移行先のRDBMSバージョンチェック| SELECT AURORA_VERSION() とかDMSのドキュメントとかAuroraのドキュメントとか| PostgreSQLとして制限, MySQLの制限, Auroraの制限を確認する |
|移行元データ件数の確認|とくになし|SnapshotからリストアしてSELECT COUNT(*)叩く.数千万件程度なら大したことないので鼻ほじる|
| 移行対象テーブルの定義情報確認| なし | `\d table_name` でcolumn, index, sequenceが関連付けられた列を確認する |
| timestamp [ with time zone ]型の扱い |https://qiita.com/ykawakami/items/2449a24e3b82ff0cbab6 | datetimeに切り替えていく|
| timestamp [ with time zone ]型の扱い |https://www.postgresql.jp/document/9.6/html/datatype-datetime.html| |
| PostgreSQLのシーケンス番号チェック| http://php.o0o0.jp/article/postgres-sequence | `\d sequence_name` でlast_valueをチェックする.ノーメンテで切り替えできるようにMAX + αでターゲットに定義しておく|
| 行サイズ制限 | https://dev.mysql.com/doc/refman/5.6/ja/innodb-restrictions.html | 可変長を固定長にしてくのつらい. SELECT MAX(LENGTH(column)) FROM hogeと戦い|
| LOB型のチェック | なし | なかったので鼻ほじる.あったらLOB型の変換制約みる|
| PostgreSQL独自の型 | なし |なかったので鼻ほじる. あったら...|
| TriggerやView,Procedure, Functionオブジェクトの確認| なし |なかったので鼻ほじる.あったら鼻ほじ貫通からの死|




そしてこれは続きます。
ではまた！
PHP 参照と参照渡しについて

## PHPの参照とは
[公式マニュアル](https://www.php.net/manual/ja/language.references.whatare.php)によると以下のように説明されています。
>PHP において、リファレンスとは同じ変数の内容を異なった名前で コールすることを意味します。これは C のポインタとは異なります。 リファレンスを使ってポインタの演算をすることはできませんし、 リファレンスは実メモリのアドレスでもありません。詳細は リファレンスが行わないこと を参照ください。 そうではなく、リファレンスはシンボルテーブルのエイリアスです。 PHP では、変数名と変数の内容は異なっており、 このため、同じ内容は異なった複数の名前を有する事が可能であることに 注意してください。最も良く似ているのは、Unix のファイル名とファイルの 関係です。この場合、変数名はディレクトリエントリ、変数の内容は ファイル自体に対応します。リファレンスは、Unix ファイルシステムの ハードリンクのようなものであると考えられます。

PHPのマニュアルでは参照のことをリファレンスと表記していますが、参照と記載したほうがなじみ深いので、ここでは参照と統一して記載します。

PHPの参照は、C言語のポインタのようにメモリのアドレスが格納されているのではなく、呼び出し元の変数のエイリアス（別名）として機能するようです。

## 参照渡しについて
変数の前に「&」をつけることによって、その変数に格納されている値を呼び出し先の変数と共有することができます。
実際に参照渡しを行い、挙動を確認してみましょう。

```test1.php
<?php
    $value = 'あいうえお';
    $result = &$value; // $valueを参照渡し
    $result = 'かきくけこ';
    
    var_dump($value);
?>
```

3行目で\$valueを\$resultに参照渡しをし、4行目で\$resultの値を変更しています。
この状態で\$resultの参照元である\$valueをvar_dumpで出力してみます。

```
string(15) "かきくけこ"
```

\$resultに参照渡しで格納された\$valueの値も変更されました。
\$valueと\$resultで値の共有がされていることが分かると思います。
参照渡しを行わないとどうなるでしょうか。

```test2.php
<?php
    $value = 'あいうえお';
    $result = $value; // 参照渡しを行わない
    $result = 'かきくけこ';
    
    var_dump($value);
?>
```

var_dumpで\$valueを確認すると次のように出力されます。

```
string(15) "あいうえお"
```

3行目で参照渡しを行わないため、\$valueの値がコピーされて\$resultに格納されたことにより、\$valueの値は変更されませんでした。
※PHPの変数は、「コピーオンライト」と呼ばれるメモリを節約する仕組みにより、変数の値を変更した場合に複製されます。test2.phpのコードだと、3行目までは\$valueと\$resultは同じ値を参照していますが、4行目で\$result値の変更があったタイミングで、3行目の\$resultに格納されている\$valueが複製されます。

配列も参照渡しを使うことができます。

```test3.php
<?php
    $a = array('あ','い','う', 'え', 'お');
    $b = &$a;
    $b[2] = 'く';
    
   var_dump($a);
?>
```

実行結果

```
array(5) {
  [0]=>
  string(3) "あ"
  [1]=>
  string(3) "い"
  [2]=>
  string(3) "く"
  [3]=>
  string(3) "え"
  [4]=>
  string(3) "お"
}
```

オブジェクトはデフォルトで参照渡しが使われています。

```test4.php
<?php
    $obj = new stdClass();
    $obj->suzuki = '鈴木';
    $ref = $obj;
    $ref->suzuki = '佐藤';
    echo $obj->suzuki;
?>
```

実行結果

```
佐藤
```

関数は仮引数に参照渡しをすることで、参照元の変数の値を変更することができます。

```test5.php
<?php
    function hoge(&$b)
    {
        $b *= 10;
    }
    
    $a = 2;
    hoge($a);
    echo $a;
?>
```

実行結果

```
20
```

## まとめ
- PHPの参照はメモリのアドレスではなく、参照元の変数のエイリアスとして同じ値を持つ。
- 変数の先頭に「&」をつけることによって参照渡しを行い、参照元の変数の値を共有できる。
- 参照元、参照先どちらかの値を変更すると、もう一方の値も変更される。
- 参照渡しは配列、オブジェクト、関数でも使用することができる。（オブジェクトはデフォルトで参照渡しされている）
Vueでの維持しやすいCSS

# 概要

1. きっかけ／目標
1. CSSの問題
1. ５つのルール
1. まとめ

---

# きっかけ

ここ１年、毎日CSSを書いてきましたが、分かったことを伝える機会はなかなか来ないです。

# 目標

1. めったにフロントエンドに手を加えない方でも、維持しやすいCSSが書けるように。
2. そして、これから発表する点について議論を始めたいです。

# 前提

Fire-and-forget（ファイア・アンド・フォーゲット？）ではないプロジェクトです。

---

# CSSの問題

CSSは客観的に難しいです。

1. 新しいプログラミング言語ばかりか、超独特！
1. 関心の分離（viewとmodel）はしたいですが、混ぜるの方がなぜか維持しやすい？
1. ブラウザー互換性の落とし穴。

上記の３点が生み出すのは危険な開発環境です。

---

# ５つのルール

1. CSSフレームワークを使いまくる
1. 互換性を`autoprefixer`に任せる
1. `*`スタイルを使わない
1. 横幅と高さを固定しない
1. ルート要素にpadding／marginを付けない

---

# #1 CSSフレームワークを使いまくる

ミシャが好きなことわざ：「一番（形容詞）なコードは存在しないコードです。」

CSSフレームワークとは、よく使われるスタイルをクラス化したライブラリーのことです。最近ハマっているのは[TailwindCSS](https://tailwindcss.com/)です。

1. CSSはほとんど構成によらなくなる
2. CSSの構文、詳細が無視できる - 抽象化
3. **修正する時はテンプレートより深く調べなくてよくなる**

今のプロジェクトは、スタイルタグがないコンポーネントは**48% (69/146)**に止まっています。

要するに、一番維持しやすいCSSは存在しないCSSです。

--- 

# #2 互換性を（ある程度）`autoprefixer`に任せる

ブラウザー互換性は複雑です。ブラウザーによってCSS機能のプレフィクスが異なることは多いです。

```scss
@mixin placeholder($color) {
  &::-webkit-input-placeholder { /* Chrome/Opera/Safari */
    color: $color;
  }
  &::-moz-placeholder { /* Firefox 19+ */
    color: $color;
  }
  &:-ms-input-placeholder { /* IE 10+ */
    color: $color;
  }
  &:-moz-placeholder { /* Firefox 18- */
    color: $color;
  }
}
```

普段は[caniuse.com](https://caniuse.com/)を参考しながら解決できますが、誰もそれぞれのプレフィクスが覚えられません。

でも、ブラウザーのCSSタグの差分をある程度自動的にカバーできます。そこを[autoprefixer](https://github.com/postcss/autoprefixer)に任せましょう。例えば、上のコードはこうなります。

```scss
@mixin placeholder($color) {
  &::placeholder {
    color: $color;
  }
}
```

自分でブラウザータグを書いていることに気付いたら、やめてください。

---

# #3 `*`スタイルを（基本的に）使わない

`*`は再起的に子供にスタイルを付ける機能です。例えば、プロジェクト全体のフォントサイズを設定するには：

```scss
* {
  font-size: 16px;
}
```

プロジェクトを始めていない限り、使わない方が良いです。

1. 将来、コンポーネントは`<slot>`が必要になったら、内容がそのスタイルと闘うことになります。
2. コンポーネントの柔軟性はある程度なくなります。
3. **たまに、スタイルバグを隠してしまいます。**

特にpadding、margin、と色を設定するのは危ないです。共有性が破壊されます。

---

# #4 横幅と高さを（基本的に）固定しない

罪です。

1. コンポーネントの内容が変わった -> 変更
2. コンポーネントに親のスペースを全部取って欲しい -> 変更
3. 中身にスタイルを付けて、空に見えないように縮んで欲しい -> 変更
4. …

次回は必ず固定された数字を更新するハメになります。「維持しやすい」の正反対です。

## 例外

1. テキストと一緒に現れるコンポーネント（アイコンなど）には使うべきです。特に`em`で。
2. レスポンシブウェブデザインを気にしない、アプリ全体の横幅を設定する時は使っちゃいます。

残りはほぼ全部比率あるいは内容／親の大きさに応じて決めれば良いです。見た目は自然に更新されます。

---

# #5 ルート要素にpadding／marginを付けない

`ErrorCard.vue`

```vuejs
<template>
  <div class="mb-2">
   {{ error }}
  </div>
</template>
```

`App.vue`

```vuejs
<template>
  <div>
    <ErrorCard class="mb-1" />
    <MyForm class="mb-1" />
    <MyFooter />
  </div>
</template>
```

上記の`mb-*`は`margin-bottom-*`の省略で、下のmarginを設定するCSSクラスです。

この例では：

1. `mb-1`か`mb-2かのどちらかが勝つから`!important`を使うことになる、あるいは使っている方を合わせる。
1. 書き直すには、そのコンポーネントが使われているところを全部修正するハメになる。（テストしきれない！）

marginとpadding以外でのスタイルも、ルート要素なら慎重に付けましょう。どんなに経験を積んでも、コンポーネントの使い方はめったに予想できません。

---

# まとめ

ルールは２種類ありました。

 #1 ツールに頼る

- CSSフレームワークを使いまくる
- 互換性を`autoprefixer`に任せる

 #2 コンポーネントの使い方を前提にしない

- `*`スタイルを使わない
- 横幅と高さを固定しない
- ルート要素にpadding／marginを付けない

そこはコツだと思います。後はCSSを学習することです。

以上。
Macのストレージ「その他」がめっちゃ多いと思ったらDockerとpipenvのせいだった

# 3行
* macの空き容量が1GBしかない
* 「その他」が80GBくらい専有している
* 調べたら「Dockerイメージのキャッシュ」と「pipenvのキャッシュ」のせいだったので消した

# Docker for Macのキャッシュデカすぎ & 消えない問題
* こちらの記事に詳しいです。そのまま実行させていただきました。
    * [Docker for Macを使っているとストレージ容量不足になる問題をなんとかする](https://qiita.com/ktsujichan/items/726e0f896e30b355fee1)
    * 私のシェルはfishなのでコマンドはこちらの記事にあるものになりました。
        * [Dockerコマンドメモ(fish)](https://qiita.com/crawd4274/items/5c494e99bcf38a306cd3)

# pipenvのキャッシュもデカすぎ問題
* issueに上がってました。2020/06/17時点でissueはOpen。
    * [Pipenv unlimited cache size #3655](https://github.com/pypa/pipenv/issues/3655)
* 公式を見ると（依存関係の解決ができないときの対処としてですが）「キャッシュを手動で消してみて」とあったので、消していいものと判断して削除。
    * [Pipenvでよく出喰わす問題](https://pipenv-ja.readthedocs.io/ja/translate-ja/diagnose.html)

        > これで上手くいかない場合は、キャッシュディレクトリ全体を手作業で削除してみてください。 キャッシュディレクトリは通常は、次の場所のうちのどこかです:
        > ~/Library/Caches/pipenv (macOS)
        > %LOCALAPPDATA%\pipenv\pipenv\Cache (Windows)
        > ~/.cache/pipenv (それ以外のオペレーティングシステム)

* 一応適当なディレクトリを作って、 `pipenv install` がちゃんと動くか確認

```sh
$ mkdir pipenv_cache_test
$ cd pipenv_cache_test
$ pipenv install pandas
```

* 動いたのでOK

# 結果
* 40GBくらい空きました。
* ~~そもそもこの辺を気にしなくて良いスペックのPCにしたい…~~
WindowsにUbuntu入れてみた

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59161/ad2bf8b6-ad1a-8d11-c7aa-a6871d677a2d.png)

社会人で仕事し始めて５年経ったが、一社目に入って半年後にMacbook Proを手入れてからはずっとMacintoshで仕事していました。ところで、最近話題（もうそんなに最近ではないが）WSL2（Windows Subsystem for Linux）をきになったので、それを自宅のPCに入れて、開発に使えないか模索しています。

PCは10年前、大学入学したときで買った初期のIntel i7です。今はWindows10にバージョンアップしています。それでは早速やって行きましょう！

### 前提条件
- Windows 10 Build 19041である以上(windowsキー + R, winver, OKで確認できます)
    - なってない人はwindows insiderで検索して、加入して最新化してね（windows updateで結構時間かかる）

## WLS動くようにする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59161/418370d1-f5e9-ebc9-6f1c-b53b4d1801dd.png)
1. まずTerminalある場合はTerminalで、ない場合はCMDをアドミンとして実行する。
2. 開いた画面で WSLを有効化させます：
    `dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart`
3. 次にWSL2にあげます：
    `dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart`
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59161/6d6c58d4-b3d8-7a2f-9920-599a7f58da97.png)
4. 次に行く前に一回PCを再起動させます。
5. その後、もう一回アドミンとしてTerminalやCMDを開いて、デフォルトでWSL2を使うように設定を入れます：
    `wsl --set-default-version 2`

`WSL 2 requires an update to its kernel component. For information please visit https://aka.ms/wsl2kernel` と出た場合は指示通りにリンク先からダウンロードしてインストールしましょう。

この状態であれば、WSL2は準備できて、あとはwindows storeからUbuntuを入れるだけです。

## Ubuntuを手に入れる
1. [Microsoft Store](https://aka.ms/wslstore)を開いて、「Ubuntu 20.04 LTS」で検索して(または好きなLinuxシステムを選択して)、インストールする。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59161/05a3fa04-4615-5f58-e3fb-6a99f52c8017.png)
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59161/11d5ad79-7269-b987-6c03-81fce8884273.png)
2. インストールが終われば、スタートメニューからUbuntuを起動できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59161/ef26f98f-ba6b-66a7-9b10-b382ba0fbf04.png)
初回起動時はユーザー名とパスワードを新設できますので、決めて記入しましょう。

あとは、普通のUbuntuとして使えます！

## おまけ
- `wsl --list --verbose`でインストールされたlinux環境の一覧が見れます。
- `wsl --set-version <distribution name> <versionNumber>`でWSLのバージョンも切り替えられます。




公式ドキュメント: https://docs.microsoft.com/en-us/windows/wsl/install-win10
プロトタイピングと負債、リスクについて

こんにちはスープです。
スタートアップのお手伝いをしています。

## プロトタイピング

価値検証のために、実装とリリース、ユーザーフィードバック収集のサイクルを繰り返し行います。
そのサイクルのスピードと精度が重要です。

### メンテンナンス性を度外視できる場合

コードは書かれるよりも、人に読まれる時間のほうが長いので、一般的にきちんとした設計のコードを書くメリットは大きいです。

ただし、書き捨てのコードに限っては、動作すれば何でも良いため、基本的にどんな書き方でも支障がないです。
これはプロトタイピング用のコードに関しても同じことが言えますね。

## リスク

### 中長期的な成長の阻害

問題になるのは、プロトタイピング目的で書かれたコードをメンテナンスしなければいけないときです。
プロトタイピングフェーズ後、目下のビジネス価値の実現のみにエンジニアリングリソースが割かれることは非常に多く、スケールしない設計のまま突き進んでしまうケースが多いのです。設計のひずみが日増しに大きくなり、3年もすると（早ければ半年程度で）身動きが取れない状態になります。

バッドコードにより、機能開発に必要なリソースは指数関数的に増えていきます。
また、フラストレーションを溜めた離職者が続出したり、プロダクトの成長が止まったりすることは日常茶飯事で、会社ごと吹き飛んだりするケースもあるらしいです。

### 訴訟、ブランド毀損

低品質なソフトウェアによってユーザーが損害を被った場合、訴訟に発展したり、それによってブランドイメージを毀損したりするリスクが存在します。
Uberの自動運転で死者を出す事故が起きているのは記憶に新しいですね。

## リスクにどう対処するか

### 負債の管理

負債の性質と量を把握し、負債返済のロードマップを作成する必要があります。

また、負債を増やすステークホルダーの要求があった場合、開発者はそのリスクを指摘します。
ステークホルダーのほとんどの人たちは、負債によって発生するリスクを知らないので、当該システムのことを知っているプログラマーにその責任がありますね。

一般的に、CTOやソフトウェアアーキテクト、テックリード等がソフトウェアのアーキテクチャへの影響をコントロールする役割を率先して担えるでしょう。

変更によって増す複雑性とそれによって追加される機能性を天秤にかけ、機能性の方が低いと判断される場合は、その変更は受け入れられません。

### ステークホルダーとのコミュニケーション

プロトタイピングフェーズである旨をステークホルダー皆が認識する必要があります。
価値検証が終わったら、後にソフトウェアのリライト（フルリライトもしくはパーシャルなリライト）をすることをチーム全体、またステークホルダー達と握っておく必要があります。

ステークホルダーには、下記の人たちが含まれるはずです。

- CEO
- 投資家
- PO
- 開発チーム
- Salesチーム
- その他影響を受けるチーム
- エンドユーザー

## まとめ

ソフトウェアがどのフェーズに位置しているかを理解するのは重要ですね。
リスクを管理し、適切にステークホルダーとコミュニケーションを取っていくことによって、ソフトウェアが成功する確率を高めることができると思います。
macOS で AWS CLI バージョン 2 を利用できるようにしたメモ

## 前提(私の作業環境)

`macOS 10.15.5 (Catalina)`

## 手順

このページ( https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/install-cliv2-mac.html#cliv2-mac-install-cmd-all-users ) からインストーラをダウンロードして、インストーラを実行。「現在のユーザーのみ」だと手順が少し多く面倒なので「コンピュータ上のすべてのユーザーを対象」で。

インストールし終わったら動作確認。

```shell
$ aws --version
aws-cli/2.0.22 Python/3.7.4 Darwin/19.5.0 botocore/2.0.0dev26
```

次に、AWS マネジメントコンソールの IAM で、自ユーザの アクセスキー と シークレットアクセスキー を作成し文字列を控えておく。

控えたら `configure` コマンドを実行。( 参考 : https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-chap-configure.html#cli-quick-configuration )

```shell
$ aws configure
AWS Access Key ID [None]: <控えていたアクセスキー>
AWS Secret Access Key [None]: <控えていたシークレットアクセスキー>
Default region name [None]: ap-northeast-1
Default output format [None]: json
```

`~/.aws/` 配下にファイルが作成されたのを確認する。（修正する場合はこれらのファイルを編集すればOK）

適当な aws コマンドで動作確認。

```shell
$ aws s3 ls
```

以上
RailsのenumをSQLから集計する

## はじめに
セキュリティ上の観点からproductionでrails consoleを使えないことがあります。
このとき登録されているデータの調査を行う場合、redashなどをBI ToolからSQLで調査することがあると思います。
その際のenumを見やすく表示する方法をまとめます。

## 集計方法(やりかた)
次のような、roleがenumで定義されています。

```ruby
enum role: { user: 1, admin: 9 }
```

こんな感じのデータを調査します。

| name   | role |
|--------|------|
| test_1 | 1    |
| test_2 | 1    |
| admin_1 | 9    |
| admin_2 | 9    |

調査用のSQLであるため、速度を気にせずサブクエリを使います。

```sql

SELECT td.name, td.role, enum_code.name
FROM test_data AS td
JOIN
(
     SELECT 'user' AS name, 0 AS code UNION ALL
     SELECT 'admin' AS name, 9 AS code
) AS enum_code
ON td.role = enum_code.code;
```
次のような結果になり、ロール名が表示されます。

| name   	| role	| role_name	|
|--------|------|------|
|test_1		|0 		|user|
|test_2		|0 		|user|
|admin_1	|9 		|admin|
|admin_2	|9 		|admin|


## 余談
以下は余談ですが、追加で説明しておきたい情報です。

### 試した環境
* MySQL 14.14
    * [paiza](https://paiza.io/projects/featured?language=mysql)
* PostgreSQL 12.3
    * [Docker](https://hub.docker.com/layers/postgres/library/postgres/alpine/images/sha256-0a75bd75331a524b17353296945a6963b30a1e7f4ea70a1a1d8fb34c5895c1ac?context=explore)

### 結合するための一時的な表

※  `一時的な表` の公式な呼び方があれば、ご教示いただけると幸いです。

```sql
SELECT 'user' AS name, 0 AS code
```
を実行すると次のような `一時的な表` を作れます。

| name   | code |
|--------|------|
| user | 0    |

これを複数行作って `UNION ALL` で行単位で結合しています。

| name   | code |
|--------|------|
| user | 0    |
| admin | 9    |


 そして、JOINで列単位で結合しています。

| name   	| role	| role_name	|
|--------|------|------|
|test_1		|0 		|user|
|test_2		|0 		|user|
|admin_1	|9 		|admin|
|admin_2	|9 		|admin|

### FROMの省略
https://oss-db.jp/dojo/dojo_09

MySQLとPostgreSQLでは `FROM` を省略したSQL文が書けます。
Oracle と DB2 ではFROMの省略はできないので、 `FROM dual` を使います。


```sql
SELECT 'user' AS name, 0 AS code FROM dual;
```

https://docs.oracle.com/cd/E16338_01/server.112/b56299/queries009.htm
https://www.ibm.com/support/knowledgecenter/ja/SSEPGG_11.1.0/com.ibm.db2.luw.apdv.porting.doc/doc/r0052874.html

### with句
PostgreSQLはwith句が使えるので一時的な表を最初に記述できます。
この書き方は、上から順番に処理が追えるので集計用クエリを作る際に使っています。
MySQLの場合は8.0から使えるようです。

```sql
WITH enum_code AS (
    SELECT 'user' AS name, 0 AS code UNION ALL
    SELECT 'admin' AS name, 9 AS code
)
SELECT td.name, td.role, enum_code.name AS role_name
FROM test_data AS td
JOIN enum_code
ON td.role = enum_code.code;
```
https://www.postgresql.jp/document/12/html/queries-with.html
https://dev.mysql.com/doc/refman/8.0/en/with.html
AWS　EC2　未経験エンジニアがデプロイするまでにハマり&解決法　MYSQLの設定編➀

参考にさせていただいた記事　
https://qiita.com/naoki_mochizuki/items/f795fe3e661a3349a7ce

###➀MYsqlの設定について
まず当たり前ですがAWSのサーバー内でMYSQLにログインして、作業をしていく必要があります。
この記事でいえば
```
[naoki|mumu]$ sudo service mysqld start
```
これを実行して、hogehogeみたいな。
でも実行結果は
```
Redirecting to /bin/systemctl start mysqld.service
Failed to start mysqld.service: Unit not found.
```

なにこれ（困惑）

ちなみに正しい場合は
```
Redirecting to /bin/systemctl start mysqld.service
```
だけが表示される状態です。
###解決方法
正解は僕の知る限り２パターン
####➀MySQL5.7の導入
####➁Amazon linux 2ではなく、Amazon linuxにしちゃう 
 (https://teratail.com/questions/163564)

どちらかで対応しますが私は今回１番で対応しました。
MYSQLの5.7にする方法は下の参考文献に譲ります。  

ただ、5.7に改インストールできれば
```sudo service mysqld start```
結果
```Redirecting to /bin/systemctl start mysqld.service
```
これが表示されるかもしれませんが
```
rake db:create RAILS_ENV=production
```これが通らない。ORZなぜ・・・

理由はサーバーにログインで来ていないためです。
そこで大切なのは、MYSQLには初期でランダムにパスワードが設定されていたからだった。
だからルートユーザーでもなぜかparmission denedが表示されていたんですか・・・

そのため、ランダムに生成されるmysqlの設定を変更する必要がある、そしてそれが変更できれば
```
rake db:create RAILS_ENV=production
```
これが通るようになるわけなんですね。

#####ここから先にもたくさんのエラーと戦わなければいけない為大変だと思いますが、
#####僕の分かる範囲で質問に対して答えられればと思いますのでお気軽にコメントください！



参考(mysqlのインストール)
https://qiita.com/hamham/items/fd77bb0bb167a150dc8e#mysql57%E3%81%AE%E5%B0%8E%E5%85%A5
MQTTサーバー(ブローカー)mosquittoを5分で立ち上げる

# MQTTブローカー　mosquitto 立てる

M5Stackを入手。まずは気温・湿度・気圧をグラフにしたい。
データを集約するにはMQTTサーバー（ブローカー）が良いらしい。
あまり面倒な事はしたくないが
登録が必要なサービスを使うと仕様の変更とか制限があったりしてイヤなので
VPSでmosquittoを動かすことにした。
mosuqittoのコンテナイメージがあるとの事でありがたく使わせていただく。

##起動する

適当なディレクトリの下に設定ファイルを作成

```
mkdir -p mosquitto/config
vi mosquitto/config/mosquitto.conf
```

```mosquitto/config/mosquitto.conf 
listener 1883  # デフォルトのポート
listener 9001  # WebSocket用
protocol websockets

```

ユーザー認証なしでの設定なのでご注意ください

---
起動

```
docker run -it --rm --name mosquitto \
  -v `pwd`/mosquitto:/mosquitto \
  -p 1883:1883 \
  -p 9001:9001 \
  eclipse-mosquitto:latest
```

ポート9001はWebsocket用なので無くても問題ないが
あると面白い事ができるので入れておく事をおすすめ

##動作テスト

コマンドラインでのテスト
mosquitto を起動した端末とは別の端末から

```
mosquitto_sub -h localhost -t TOPIC/#
```
さらに別の端末から

```
mosquitto_pub -h localhost -t TOPIC/INFO -m "Hello World"
```
---
スマホのアプリ「MQTT Dash」でもテストできる
[MQTT Dash](https://play.google.com/store/apps/details?id=net.routix.mqttdash&hl=ja)


##TLS接続
ウェブサイトで利用するにはTLS接続できるようにしておくと都合が良い。
その場合には以下のように証明書関連の設定を追加する


```mosquitto/config/mosquitto.conf 
listener 1883  # デフォルトのポート
listener 9001  # WebSocket用
listener 8883  # TLS接続用
protocol websockets

cafile /etc/letsencrypt/live/<FQDN>/fullchain.pem
certfile /etc/letsencrypt/live/<FQDN>/cert.pem
keyfile /etc/letsencrypt/live/<FQDN>/privkey.pem
```
起動

```
docker run -it --rm --name mosquitto \
  -v /etc/letsencrypt:/etc/letsencrypt:ro \
  -v `pwd`/mosquitto:/mosquitto \
  -p 1883:1883 -p 9001:9001 \
  -p 8883:8883 \
  eclipse-mosquitto:latest
```


letsencryptの場合の例なので適宜修正してください

この内容はさくらインターネットのVPS(Debian10)で確認しています
kubernateのlivenessProbeの設定

## 概要
Probe とは、直訳すると調査になります。
なので、livenessProbeは、生きているかどうかの調査になります。

## 実際の使用例

例えば、以下のような設定をした場合どういう挙動をするでしょう

```
 livenessProbe:
          tcpSocket:
            port: 9000
          initialDelaySeconds: 30
          periodSeconds: 60
          timeoutSeconds: 3
          successThreshold: 1
          failureThreshold: 2
```

各設定

- initialDelaySeconds : コンテナが開始してからProbeを行うまでの初期遅延を秒単位で指定
- timeoutSeconds : Probeのタイムアウトを秒単位で指定する。デフォルトは1秒
- periodSeconds : Probeの間隔を秒単位で指定する。デフォルトは10秒で最小の値は1秒
- successThreshold : Probeが成功したと判断する最小回数を指定。デフォルトは1回
- failureThreshold : Probeが失敗したと判断する最小回数を指定。デフォルトは3回


この場合、アプリが落ちた場合、60秒間隔でエラーを察知し、2回feilureが返ってきた場合、コンテナを再起動してくれます。
再起動後、30秒待ってから、再度チェックを行います。


参考）
https://cstoku.dev/posts/2018/k8sdojo-10/
Cloud Functions の認証が必要な関数を Cloud Scheduler から実行する

# はじめに

* GCP の Cloud Functions の関数は以前はデフォルトで認証がなく任意の接続元からアクセスできる設定でしたが、最近変更がありデフォルトで認証が必要になりました。
* この記事では Cloud Functions の認証が必要な関数を GCP の定時ジョブ実行サービスである Cloud Scheduler から実行する方法を紹介します。

# Cloud Functions 実行用のサービスアカウントの作成

* GCP コンソールにログイン
* メニューから「IAM と管理」の「サービスアカウント」に移動
* 「サービスアカウントを作成」から作成開始
    * 「サービスアカウント名」と「サービスアカウントID」は任意のもの
	* 「ロール」に「Cloud Functions 起動元」を追加
    * 「作成」ボタン押下で作成完了

# Cloud Functions の関数の作成

* GCP コンソールにログイン
* メニューから「Cloud Functions」に移動
* 「関数を作成」から作成開始
    * 「名前」は任意のもの
    * 「トリガー」は「HTTP」
    * 「URL」を控えておく
    * 「ソースコード」は「インラインエディタ」で「ランタイム」とコードはデフォルトのもの
    * 「作成」ボタン押下で作成完了

# Cloud Scheduler のジョブの作成

* GCP コンソールにログイン
* メニューから「Cloud Scheduler」に移動
* 「ジョブを作成」から作成開始
    * 「名前」「頻度」「タイムゾーン」は任意のもの
	* 「ターゲット」は「HTTP」
	* 「URL」は作成した関数の URL
	* 「HTTPメソッド」は「GET」
	* 「SHOW MORE」の中の「Auth ヘッダー」は「OIDC トークンを追加」で「サービスアカウント」は作成したサービスアカウントのメールアドレスを指定
    * 「作成」ボタン押下で作成完了
* 作成したジョブの「今すぐ実行」ボタンを押下して動作確認

# おわりに

* この記事の内容について[公式ドキュメント](https://cloud.google.com/scheduler/docs/http-target-auth)にも一応は記載がありますが、具体的に Cloud Functions を対象に解説されているわけではなかったので試してみた結果をまとめました。
Gitでerror: src refspec master does not match anyのエラー

git push -u origin masterで初めてのプッシュをしようとした。
（まったくブランチの作成していない状態）

そこで

```
error: src refspec master does not match any
error: failed to push some refs to 'git@github.com,,,'
```
まさかのエラー。

原因：コミット忘れてた。

```
git commit -m "First commit"
```

このようなエラーが出たらコミットしたか確認してみてください。
以上です
PRML　演習問題 4.17 （基本）

## 問題
>ソフトマックス活性化関数 

>```math
\begin{align*}
p\left(\mathcal{C}_{k} | \phi\right)=y_{k}(\phi)=\frac{\exp \left(a_{k}\right)}{\sum_{j} \exp \left(a_{j}\right)}
\tag{4.104}
\end{align*}
```
の微分が、

>```math
\begin{align*}
\frac{\partial y_{k}}{\partial a_{j}}=y_{k}\left(I_{k j}-y_{j}\right)
\tag{4.106}
\end{align*}
```

>によって与えられることを示せ。
ここで、 $a_{k}$ は

>```math
\begin{align*}
a_{k}=\mathbf{w}_{k}^{\mathrm{T}} \boldsymbol{\phi}
\tag{4.105}
\end{align*}
```

>によって定義される。
なお、$I_{k j}$ は単位行列の要素である。

## 方針
本問を通して示したいのは、最尤法を用いて、直接パラメータ $\mathbf{w}_{k}$ を決定する方法です。

そのために、全ての活性化関数 $a_{j}$ に関する $y_{k}$の微分を考える必要があります。
この微分が (4.106) で与えられることを示します。

なお、$I_{k j}$ は単位行列の成分であるため、

$I_{k j} = 1, \quad j = k $
$I_{k j} = 0, \quad j \neq k $

であることに注意します。


## 解答

```math
\begin{align*}
\frac{\partial y_{k}}{\partial a_{k}}=\frac{e^{a_{k}}}{\sum_{i} e^{a_{i}}}-\left(\frac{e^{a_{k}}}{\sum_{i} e^{a_{i}}}\right)^{2}=y_{k}\left(1-y_{k}\right)
\end{align*}
```

```math
\begin{align*}
\frac{\partial y_{k}}{\partial a_{j}}=-\frac{e^{a_{k}} e^{a_{j}}}{\left(\sum_{i} e^{a_{i}}\right)^{2}}=-y_{k} y_{j}, \quad j \neq k
\end{align*}
```

よって、題意は示された。
Node.jsでルーティングを行う方法と、やってはいけないこと

##ルーティング
ルーティングとは：アクセスするパスに応じて、表示する内容や行う処理を変えること

##Node.jsでのルーティングの記述方法
・Node.jsアプリのファイル構成

```
├──app.js    //アプリのメインのバックエンド処理
├── public   //UI（css,クライアントサイドのjavascript）を記述
│   └── css
│       └── style.css
├── routes   //ルーティング処理を記述
│   └── index.js
└── views　　//特定のパスにアクセスした時に引き渡すファイル。テンプレートエンジンを用いて記述
    ├── home.ejs
    ├── index.ejs
    ├── login.ejs
    └── register.ejs
```



・app.js

```javascript
'use strict'
//共通変数
const path = require('path');
const morgan = require('morgan');　//ターミナルにHTTPの処理をリアルタイムで表示させる
const express = require('express');
const app = express();
const router = require('./routes/index.js')　//ルーティング処理を書いたファイルをモジュールとして読み込む

//POSTのミドルウェア
app.use(express.urlencoded());
app.use(express.json());

//テンプレートエンジンの設定
const viewsPath = path.join(__dirname, './views')
const publicDirectoryPath = path.join(__dirname, './public')

app.set('view engine', 'ejs');
app.set('views', viewsPath)
app.use(express.static(publicDirectoryPath));
app.use(morgan({format: 'dev', immediate: true}));

//ルーティング処理
app.use('/', router);

app.listen(3001, () => {
  console.log('server is up on port 3001')
})


```


・index.js

```javascript
const express = require('express');
const router  = express.Router();　//ルーティング処理を記述していく

router
  .get('', (req,res) => {
    res.render('index')
  })
  .get('/login', (req,res) => {
    res.render('login')
  })

  .get('/register', (req,res) => {
    res.render('register')
  })
//homeにPOSTするときの処理
  .post('/home', function(req, res) {
      const _username = req.body.username;
  //POSTが作動しているか確かめる為にconsoleする
      console.log(111)
  // usernameを渡す + views/home/index.jsを参照する
      res.render('home', {username: _username})
});

module.exports = router;
```


##やってはいけない実装方法

もしも、「/login」パスにアクセスした時の処理だけをindex.jsに書いていたとしたら？

```javascript

//ルーティング処理を書いたファイルをモジュールとして読み込む
const router = require('./routes/index.js')

(省略)

app.get('', (req,res) => {
    res.render('index')
  });

app.use('/login', router);

```

こうすると、/loginのパスにアクセスした時に、エラーになる。
ルーティング処理を書いたファイルをモジュールとして読み込む時のapp.useでは、第一引数を'/'のパスにする必要がある
windowsでiverilog その30

#概要

windowsでiverilogやってみた。
九九、書いてみる。

#サンプルコード


```

module mul(input clk, rst, input [3:0] a, input [3:0] b, output [7:0] out);
	reg [7:0] out;
	always @(posedge clk or negedge rst)
	begin
		if (!rst)
		begin
			out <= 0;
		end
		else
		begin
			out <= a * b;
		end
	end
endmodule

module test();
	reg clk;
	reg rst;
	reg [3:0] a;
	reg [3:0] b;
	wire [7:0] out;
	mul u(.clk(clk), .rst(rst), .a(a), .b(b), .out(out));
	integer i,
		j;
	initial
	begin
		$monitor("%d %d %d", a, b, out);
		clk = 0;
		rst = 1;
		#10
			rst = 0;
		#10
			rst = 1;
		for (i = 1; i < 10; i = i + 1)
		begin
			for (j = 1; j < 10; j = j + 1)
			begin
				#10;
				a = i;
				b = j;
			end
		end
		#10
			$finish;
	end
	always
	begin
		#5
			clk = 1;
		#5
			clk = 0;
	end
endmodule




```


#実行結果


```


 x  x   x
 x  x   0
 x  x   x
 1  1   x
 1  1   1
 1  2   1
 1  2   2
 1  3   2
 1  3   3
 1  4   3
 1  4   4
 1  5   4
 1  5   5
 1  6   5
 1  6   6
 1  7   6
 1  7   7
 1  8   7
 1  8   8
 1  9   8
 1  9   9
 2  1   9
 2  1   2
 2  2   2
 2  2   4
 2  3   4
 2  3   6
 2  4   6
 2  4   8
 2  5   8
 2  5  10
 2  6  10
 2  6  12
 2  7  12
 2  7  14
 2  8  14
 2  8  16
 2  9  16
 2  9  18
 3  1  18
 3  1   3
 3  2   3
 3  2   6
 3  3   6
 3  3   9
 3  4   9
 3  4  12
 3  5  12
 3  5  15
 3  6  15
 3  6  18
 3  7  18
 3  7  21
 3  8  21
 3  8  24
 3  9  24
 3  9  27
 4  1  27
 4  1   4
 4  2   4
 4  2   8
 4  3   8
 4  3  12
 4  4  12
 4  4  16
 4  5  16
 4  5  20
 4  6  20
 4  6  24
 4  7  24
 4  7  28
 4  8  28
 4  8  32
 4  9  32
 4  9  36
 5  1  36
 5  1   5
 5  2   5
 5  2  10
 5  3  10
 5  3  15
 5  4  15
 5  4  20
 5  5  20
 5  5  25
 5  6  25
 5  6  30
 5  7  30
 5  7  35
 5  8  35
 5  8  40
 5  9  40
 5  9  45
 6  1  45
 6  1   6
 6  2   6
 6  2  12
 6  3  12
 6  3  18
 6  4  18
 6  4  24
 6  5  24
 6  5  30
 6  6  30
 6  6  36
 6  7  36
 6  7  42
 6  8  42
 6  8  48
 6  9  48
 6  9  54
 7  1  54
 7  1   7
 7  2   7
 7  2  14
 7  3  14
 7  3  21
 7  4  21
 7  4  28
 7  5  28
 7  5  35
 7  6  35
 7  6  42
 7  7  42
 7  7  49
 7  8  49
 7  8  56
 7  9  56
 7  9  63
 8  1  63
 8  1   8
 8  2   8
 8  2  16
 8  3  16
 8  3  24
 8  4  24
 8  4  32
 8  5  32
 8  5  40
 8  6  40
 8  6  48
 8  7  48
 8  7  56
 8  8  56
 8  8  64
 8  9  64
 8  9  72
 9  1  72
 9  1   9
 9  2   9
 9  2  18
 9  3  18
 9  3  27
 9  4  27
 9  4  36
 9  5  36
 9  5  45
 9  6  45
 9  6  54
 9  7  54
 9  7  63
 9  8  63
 9  8  72
 9  9  72
 9  9  81


```

以上。
Windows 10 + C# + selenium で headless chrome を試してみる

# 目的
ChromeをC\# + selenium からキックしてみる
※Selenium4 はこちら [Windows 10 + C# + Selenium4 で Chrome と Edge を headlessで起動してみる](https://qiita.com/tabizou/items/ea69da65759f1d5f82d6)
OpenQA.Selenium.Support.UI.ExpectedConditions method is now deprecatedに対しては
SeleniumExtras.WaitHelpers.ExpectedConditionsで書き換えて対応してみる
※サイトの作成された時期によって修正の量が違うと思われる・・・・
PythonでのWebDriverWaitは

```python
    element = WebDriverWait(driver, 10).until(
        EC.presence_of_element_located((By.TagName, 'h3'))
    )
```
を書き換えると以下になるのかいな？？

```cs
    WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));            
    IWebElement firstResult = wait.Until(SeleniumExtras.WaitHelpers.ExpectedConditions.ElementExists(By.TagName("h3")));
```
## 追加パッケージ
.NETFramework 4.5でプロジェクトを作成後
プロジェクト -> NuGetパッケージの管理より以下を追加する

<pre>
Selenium.WebDriver
Selenium.WebDriver.Chrome
DotNetSeleniumExtras.WaitHelpers
</pre>
## サンプルコード
[Seleniumブラウザー自動化プロジェクト](https://www.selenium.dev/docs/site/ja/)のCS版を書き換えてみる

```cs
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Support.UI;
using SeleniumExtras.WaitHelpers;

private void btnChrome_Click(object sender, EventArgs e)
{
    var options = new ChromeOptions();
    options.AddArgument("--headless");
    IWebDriver driver = new ChromeDriver(options);

    try {
        WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
        
        //Webページを開く
        driver.Navigate().GoToUrl("https://www.google.co.jp");
        
        //検索ボックスに検索ワードを入力
        IWebElement el = wait.Until(SeleniumExtras.WaitHelpers.ExpectedConditions.ElementExists(By.Name("q")));
        driver.FindElement(By.Name("q")).SendKeys("Selenium" + OpenQA.Selenium.Keys.Enter);

        //検索結果が出たという判定を何にするか??　は仕様依存??
        IWebElement firstResult = wait.Until(SeleniumExtras.WaitHelpers.ExpectedConditions.ElementExists(By.TagName("h3")));
        
        //ページソースの出力
        Console.WriteLine(driver.PageSource);
    }
    catch (Exception)
    {
        Console.WriteLine("Err");
    }
    finally
    {
        if (driver != null){
            driver.Quit();
        }
    }
}
```
# 参考にしたのは以下のサイト
[Seleniumブラウザー自動化プロジェクト](https://www.selenium.dev/docs/site/ja/)
[C# Selenium 'ExpectedConditions is obsolete'](https://stackoverflow.com/questions/49866334/c-sharp-selenium-expectedconditions-is-obsolete)
[Selenium Web Driver, ExpectedConditions [deprecated] alternative](https://sqa.stackexchange.com/questions/37250/selenium-web-driver-expectedconditions-deprecated-alternative)
[seleniumを使ってC#でGoogle Chromeの自動操作をする](https://qiita.com/natuki33/items/c0947c31fc733b4e39ef)
[【C#】Selenium ChromeDriverを使ってWebスクレイピング](https://gazee.net/develop/csharp-selenium-chrome-driver/)
rubyでの整数チェック方法

今回は、変数の値が整数かどうかを確認する方法を書いていきます。
例として、aを整数か見たい変数として、以下のようにして見ます。

```ruby
if a - a.to_i == 0
  puts "これは整数です"
else
  puts "これは非整数です"
end
```

ここでa.to_iという部分がありますが、これはa=1.1の場合だと整数に変換（小数点以下は切り捨て）という意味で、1（実数と計算する場合は、その小数点以下の数だけ0がつく→今だと1.0）になります。

```ruby
a - a.to_i = 1.1 - 1.0 = 0.1 （0とならない！）
```
そのため、平方根が実数かどうかみるには、この方法も一つありかなと思います。
Linuxで使えるUSB Wifiの探索 (Ubuntu 20.04LTS)

# はじめに
計算PC（Ubuntu 20.04 LTS, 自作）をネットにつなげようとしたときにいろいろ調べたものの、情報が古い、また、廃盤になってしまっているものの情報しかなかったということで、ここに記録を残しておこう、というものです。随時更新予定です。

（[ここ](https://qiita.com/aoki/items/db4db7c0ba0e9dd1df61)を参考にさせていただいております。）

__今(2021/2/15)のところ、TP-Link T2Uあたりが安定していておすすめです（個人的な感想ですが）。__

# 動いたUSB Wifi
- PLANEX [GW-450D2](https://www.planex.co.jp/products/gw-450d2/) 
Ubuntu 18のときは[ここ](https://beautifulajax.dip.jp/?p=1184)などを参考にドライバーを入れて動かしていましたが、動作が不安定でした。よく切断していました・・・。
が、Ubuntu20.04LTSでは、挿しただけで認識し、接続ができました。切断もありません。

- TP-Link [Archer T2U Nano AC600](https://www.tp-link.com/jp/home-networking/adapter/archer-t2u-nano/)
[RTL8812au](https://github.com/aircrack-ng/rtl8812au)のドライバーをインストールで動作確認できました。
他のページ動作報告があった[こっち](https://github.com/lixz789/mt7610u_wifi_sta_v3002_dpo_20130916)のドライバーでは、インストール以前のコンパイルでつまづきました（@Ubuntu20.04)。 

- TP-Link [Archer T2U ver.3 AC600](https://www.tp-link.com/jp/home-networking/adapter/archer-t2u/)
T2U nanoと同様の手続きで使用可能です。

- ASUS [TUF Gaming B550M](https://www.asus.com/jp/Motherboards-Components/Motherboards/TUF-Gaming/TUF-GAMING-B550M-WI-FI-ZAKU-II-EDITION/)
USB Wifiではないですが、ASUSのこのマザーボードのWifiもデフォルトで使えます。
載っているチップはIntel AX200になります。

# [RTL8812au](https://github.com/aircrack-ng/rtl8812au)ドライバのインストール方法

まずgithubからドライバーのソースを持ってきます。

```bash
git clone https://github.com/aircrack-ng/rtl8812au.git
```

ダウンロード後、当該ディレクトリに移動し、

```
sudo make dkms_install
```

とするだけで良いです。再起動すれば、T2Uが認識されています。
なお、インストールには`dkms`パッケージが必要になります。詳細はReadMeに記載されていますので、そちらも参照ください。

# 動きそうなUSB Wifi
- [T9UH](https://www.tp-link.com/jp/home-networking/adapter/archer-t9uh/) 
公式HPにLinux対応しているとの記述あり。
- [Archer T3U AC1300](https://www.tp-link.com/jp/home-networking/adapter/archer-t3u/) [Mint LInux](https://forums.linuxmint.com/viewtopic.php?t=283990#p1570311)のサイトでは動くとの報告有り。github/[jeremyb31](https://github.com/jeremyb31/rtl8822bu)からドライバーをインストール。→安定しませんでした・・・


# その他
- [BUFFALO エアステーション](https://www.monotaro.com/g/03243552/?t.q=WLI%20UTX)
Wifi中継機で、PCとはLANケーブルで接続。別PC（Windows等）でWifi設定をしておく必要あり。その代わり、Linux側では設定不要。
- [r8125-dkms](https://github.com/PyCoder/r8125-dkms) : Realtek純正ドライバーをDKMSに対応させるたもの。
- Ubuntu本家にある[機器リスト](https://help.ubuntu.com/community/WifiDocs/WirelessCardsSupported) (かなり古い)



# 更新情報
- 2020.6.30 TP-Link Archer T2U Nano AC600を追加
- 2020.11.25 TP-Link Archer T2U ver.3 AC600を追加
- 2020.12.12 TP-Link Archer T3U AC1300（未確認情報）を追加
- 2021.2.15 TP-Link Archer T3U AC1300のインストール報告（ダメでした）を追加
- 2021.2.15 rtl8812ドライバのインストール方法を追加
- 2021.11.20 TUF Gaming MBの情報を追加
【写真複数登録】rails 画像を複数枚同時に登録する　原始的　力技

##【ゴール】
データ保存時1回で複数枚の画像を一緒に登録する


##【メリット】
■　アソシエーション理解度UP
■　アプリケーションの機能向上
■　UXの向上


##【開発環境】
■ Mac OS catalina
■ Ruby on Rails (5.2.4.2)
■ Virtual Box:6.1
■ Vagrant: 2.2.7

##【実装】

####アプリケーション作成

```mac.terminal
$ rails new photo
```

####refile 設定

```app.gemfile
gem "refile", require: "refile/rails", github: 'manfe/refile'
gem "refile-mini_magick"
```

```mac.terminal
$ bundle install
```

####モデル作成
※アソシエーション 　Book : Image = 1 : 多



```mac.terminal
$ rails g scaffold Book name:string text:text
$ rails g model Image image_id:string book:references
$ rails db:migtrate
```

####モデルを編集
※親のBookモデルの記述が特殊


```models/book.rb
has_many :images, dependent: :destroy
accepts_attachment_for :images, attachment: :image, append: :true
```

```models/image.rb
attachment :image
belongs_to book
```

####コントローラー追記
※DBへ情報が送られるように、paramaterに**「images_iamges: []を追加」**
※記述特殊ですが、**複数画像 ＝ 複数の情報**なので配列で渡す。


```controllers/books_controller.rb
def book_params
      params.require(:book).permit(:name, :text, images_images: [])
end
```

####ビュー追記

※ **「multiple: true, direct: true, presigned: true」**は必須
※下記コードを保存したい枚数分だけ追記する。。。。原始的ですが

```views/books/_form.html.erb
<div class="field">
    <%= form.label :photo %>
    <%= form.attachment_field :photos_images, multiple: true, direct: true, presigned: true %>
 </div>
```

※表示は**情報が複数**なので配列で表示してあげます。

```views/books/show.html.erb
<div>
  <% @book.images.each do |image| %>
    <%= attachment_image_tag image, :image ,:fill, 200, 200 %>
  <% end %>
</div>
```


####※refile key要求されたら、追記

```config/application.rb
Refile.secret_key = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
```

以上、修正箇所ございましたら
ご指摘ください。





##【合わせて読みたい】
■refile設定に関して
https://qiita.com/salvage0707/items/2614c97a1f256027ef71

■データ型　referencesに関して
https://qiita.com/ryouzi/items/2682e7e8a86fd2b1ae47

■画像送信ボタン変更
https://qiita.com/tanaka-yu3/items/f4a0df867ca9f2476314

■formに関して
https://qiita.com/tanaka-yu3/items/50f54f5d4f4b8dfe19f3
【Javascript】IE上でスプレッド構文の代用としてPolyfill+Object.assignを用いて実装。

メモとして残します。


トランスパイルをしない場合でスプレッド構文と同じような実装のやりかたを記述します。

（JSはレガシーな環境だと目的達成が大変です・・・）
#■やり方
###1. headでPolyfillを読む
（オンライン限定）

```html
<script
  src="https://polyfill.io/v3/polyfill.min.js"
  crossorigin="anonymous">
</script>
```
###2. 下記のようにObject.assignがっちゃんこ。
```javascript
let obj1 = {
    'hoge':'hogehoge',
    'hige':'higehige'
}
let obj2 =  Object.assign(
    obj1,
    {
        'hige':'HIGEHIGE',
        'fuge':'fugefuge'
    }
)
// obj2 → {hoge: "hogehoge", hige: "HIGEHIGE", fuge: "fugefuge"}

//スプレッド構文の場合
//let obj1 = {
//    'hoge':'hogehoge',
//    'hige':'higehige'
//}
//let obj2 = {
//    ...obj1,
//    'hige':'HIGEHIGE',
//    'fuge':'fugefuge'
//    
//}
```
ここで一つ注意しないといけないのは、
`プロトタイプチェーンされているオブジェクトの場合`は上記のような動作にならないため注意が必要。
yolactを実装してみる

![mini_2boxes.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404557/89b3c1be-f319-9c97-b243-d07d92eedac2.png)


## 環境
* CUDA V10.0.130
* Python 3.7.3
* gcc 7.3.0
* Pytorch 1.2.0

## セットアップ
```shell
git clone https://github.com/dbolya/yolact.git
cd yolact
pip install opencv-python pillow==6.2.1 pycocotools matplotlib
pip install cython
pip install torch==1.2.0 torchvision==0.4.0    # CUDA10.0で安定
```

yolact++を使用する場合、DCNv2をコンパイル

```shell
cd external/DCNv2
python setup.py develop
```

## 学習済みモデルで推論
1. 学習済みモデルをダウンロード  
    https://drive.google.com/file/d/15id0Qq5eqRbkD-N3ZjDZXdCvRyIaHpFB/view?usp=sharing
1. 推論を実行
   * 画像  

    ```shell
    python eval.py 
        --trained_model=weights/yolact_base_54_800000.pth  
        --score_threshold=0.15 
        --top_k=15 
        --images=path/to/input/folder:path/to/output/folder
    ```
    * 動画

    ```shell
    python eval.py 
        --trained_model=weights/yolact_base_54_800000.pth 
        --score_threshold=0.15 
        --top_k=15 
        --video_multiframe=4 
        --video=input_video.mp4:output_video.mp4
    ```



## オリジナルデータで学習
1. coco形式でデータセットを準備

```
dataset_name/
├── test
│   ├── test.json
│   └── images/
└── train
    ├── train.json
    └── images/
```

1. 学習前のモデルをダウンロード
   * Resnet50  
    https://drive.google.com/file/d/1Jy3yCdbatgXa5YYIdTCRrSV0S9V5g1rn/view?usp=sharing
   * Resnet101  
    https://drive.google.com/file/d/1tvqFPd4bJtakOlmn-uIA492g2qurRChj/view?usp=sharing
   * Darknet53  
    https://drive.google.com/file/d/17Y431j4sagFpSReuPNoFcj9h7azDTZFf/view?usp=sharing


1. configファイルを修正(2箇所)
    まずデータベース定義を記入して、

    ```py:data/config.py
        test_dataset = dataset_base.copy({
            'name': 'Test Dataset',

            'train_images': '~/dataset_name/train/images/',
            'train_info':   '~/dataset_name/train/train.json',

            'valid_images': '~/dataset_name/test/images/',
            'valid_info':   '~/dataset_name/test/test.json',

            'has_gt': True,
            'class_names': ('class_1', 'class_2', 'class_3', ...),    # クラス名を定義
            'label_map': {'class_id_1': 1, 'class_id_2': 2, ...}    # class idの辞書
        })
    ```


    次にデフォルトのconfigファイルを変更して終了。 
 
    ```py:data/config.py
        yolact_base_config = coco_base_config.copy({
            'name': 'yolact_base',

            # Dataset stuff
            # 'dataset': coco2017_dataset,    # default
            'dataset': test_dataset,    # Original Dataset

            # 'num_classes': len(coco2017_dataset.class_names) + 1,
            'num_classes': len(test_dataset.class_names) + 1,
        })
    ```

1. 学習  
    * モデルに応じてconfigは変更  
    * save_folder内に初期モデル(resnet50-19c8e357.pth)を格納

    ``` 
    python train.py --config=yolact_plus_resnet50_config --save_folder=/path/to/workspace/ --save_interval=1000
    ```

1. モデル精度評価
    * 以下のコードで評価できる。
    * `--output_coco_json` を末尾につけると、~/results/以下にjsonファイルを生成できる。

    ```
    python eval.py --trained_model=weights/yolact_base_54_800000.pth
    ```
windowsでiverilog その29

#概要

windowsでiverilogやってみた。
遅いI/Oのためにwait、書いてみる。

#サンプルコード


```

module wait0(input clk, rst, output out, output [2:0] state);
	reg out;
	reg [2:0] state;
	reg [23:0] wait_time;
	always @(posedge clk or negedge rst)
	begin
		if (!rst)
		begin
			out <= 0;
			state <= 0;
		end
		else
		begin
			case (state)
			0:
			begin
				out <= 1;
				state <= 1;
			end
			1:
			begin
				out <= 0;
				wait_time <= 24'd10;
				state <= 5;
			end
			2:
			begin
				out <= 1;
				state <= 3;
			end
			3:
			begin
				out <= 0;
				state <= 4;
			end
			4:
			begin
				out <= 0;
				state <= 0;
			end
			5:
			begin
				wait_time <= wait_time - 1;
				if (wait_time <= 0)
				begin
					state <= 2;
				end
			end
			endcase
		end
	end
endmodule

module test();
	reg clk;
	reg rst;
	wire out;
	wire [2:0] state;
	wait0 u(.clk(clk), .rst(rst), .out(out), .state(state));
	initial
	begin
		$monitor("%b %d", out, state);
		clk = 0;
		rst = 1;
		#10
			rst = 0;
		#10
			rst = 1;
		#200
			$finish;
	end
	always
	begin
		#5
			clk = 1;
		#5
			clk = 0;
	end
endmodule




```

#実行結果


```


x x
0 0
1 1
0 5
0 2
1 3
0 4
0 0
1 1
0 5


```

以上。
bootstap-vueで内部リンクと外部リンクでプロパティが切り替わるやつを作ってみた

#概要
BootstrapVueには通常の`<a>`タグリンクと`<router-link>`両方をサポートしている`<b-link>`があるけど[^1]、それぞれhrefとtoとプロパティが違うので、v-forなどでリスト化する時わざわざ書き分けるのが~~めんどくさい~~非効率なので一つにまとめられないかなと考えた。
##できたもの
タグ切り替えだけじゃもったいないので外部リンク時は新しいタブでひらいて、Font Awesomeを使ってアイコンつけるようにしたよ

```vue:LinkPath.vue
<template>
  <b-link :[bind]="path" :target="isExternalLink ? '_new' : '_self'">
  <slot></slot>
    <font-awesome-icon v-if="isExternalLink" icon="external-link-alt" />
  </b-link>
</template>
<script lang="ts">
import Vue from "vue";
export default Vue.extend({
  props: {
    path: { type: String },
  },
  computed: {
    bind(): string {
      return this.isExternalLink(this.path) ? `href` : `to`;
    },
    isExternalLink(): boolean {
      return /^https?:\/\//.test(this.path);
    },
  },
});
</script>
```
##余談
###Q:フレームワーク使わないとダメなの？
A:`<component :is="bind"～`[^2]利用してタグそのもの切り替えれば同じようにできるはず。~~知らんけど。~~
###Q:なんでTypeScript？
A:JavaScriptよりTypeScriptのほうがミスが少なくなるらしい、勉強するなら早いに越したことないしね。~~乗らなきゃこのビックウェーブに~~
デコレーターを使うとよりTypeScriptらしく記述できるらしいけど、将来どうなるか分からない[^3]ので今回は`Vue.extend`を利用したよ
###参考リンク
- [【Vue.js】nuxt-linkタグとaタグを使い分ける方法](https://hafilog.com/nuxt-link-and-atag)
- [Vue.js公式：TypeScript のサポート](https://jp.vuejs.org/v2/guide/typescript.html)
- [[Vue+TypeScript] Vue.extend で Vue らしさを保ちつつ TypeScript で書くときの型宣言についてまとめた](https://qiita.com/is_ryo/items/6fc799ba4214db61d8ab)
[^1]: [BootstrapVue│Links│Component reference](https://bootstrap-vue.org/docs/components/link#links)
[^2]: [Vue.js公式：動的 & 非同期コンポーネント](https://jp.vuejs.org/v2/guide/components-dynamic-async.html)
[^3]: [the Class API proposal is being dropped.](https://github.com/vuejs/rfcs/pull/17#issuecomment-494242121)
PRML 演習問題4.14 解答

##問題
>線型分離可能なデータ集合に対してロジスティック回帰モデルの最尤解が, クラスを分離する決定境界$\mathrm{w^T{\phi}(x)=0}$を満足するベクトル$\mathbf{w}$に対しその値を$\mathrm{\infty}$とすることで得られることを示せ.

##ロジスティック回帰モデル
本文より

>
まず2クラス分類問題における一般化線形モデルを扱ってみよう. 4.2節での生成的アプローチの議論において,かなり一般的な仮定の下で.クラス C1 の事後確率が特徴ベクトル$\mathbf{\phi}$の線形関数のロジスティックシグモイド関数として書けた.つまりその事後確率は

$$
\mathrm{p(C_1|\phi)=y(\phi)=\sigma(w^T\phi)}
\tag{4.87}
$$
$$
\mathrm{p(C_2|\phi)=1-p(C_1|\phi)}
\tag{4.87.a}
$$
$$
\mathrm{\sigma(a)=\frac{1}{1+exp(-a)}}
\tag{4.59}
$$

>となる$\mathrm{\sigma(\centerdot)}$は(4.59)で定義される**ロジスティックシグモイド関数**である.このモデルは回帰より分類のモデルであるが統計では**ロジスティック回帰**として知られている.

##ロジスティックシグモイド関数
![An-illustration-of-the-signal-processing-in-a-sigmoid-function.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/636102/81180b91-fd43-4b62-0c59-069dee9e75a3.png)

シグモイド関数は$\mathrm{0<f(x)<1, lim_{x\to-\infty}f(x)=0,lim_{x\to\infty}f(x)=1}$という性質を持つことから確率としてみることができる.また以下のように使うことで2クラス分類にも用いることができる.

```math
\begin{align*}
\left\{
\begin{array}{ll}
y=1 \hspace{10pt} (f(x)\ge0.5, x\ge0) \\
y=0 \hspace{10pt} (f(x)<0.5, x<0)
\end{array}
\right.
\end{align*}
```

上の分類法より$\mathrm{x=0}$が分類の境界になっていることがわかる.この境界がロジスティック回帰による決定境界である.

##方針
まずベクトル$\mathbf{w}$がクラスを分離する決定境界$\mathrm{w^T{\phi}(x)=0}$を満足することを示す.そして次に推定した最尤解のとる値によってベクトル$\mathrm{w}$がどのような値を取るのかを考え題意を示していく.

##解答

線型分離可能なデータ集合{$\mathrm{\phi_n, t_n}$}, $\mathrm{t_n\in}$ {0,1}が存在するときに

```math
\begin{align*}
\left\{
\begin{array}{ll}
t_n &=1 \hspace{10pt} (w^T{\phi}\ge0)\\
t_n &=0 \hspace{10pt} (w^T{\phi}<0) \hspace{10pt} ただし\phi = \phi(x) 
\end{array}
\right.
\end{align*}
```

したがってベクトル$\mathbf{w}$はクラスを分離する決定境界$\mathrm{w^T{\phi}(x)=0}$を満足する.

次に最尤解について考える.最尤解を与える尤度関数は(4.89)で与えられる.

```math
\begin{align*}
\mathrm{p(t|w)=\prod_{n=1}^Ny_n^{t_n}\bigl\{1-y_n\bigr\}^{1-t_n}}
\tag{4.89}
\end{align*}
```

$\mathrm{t=(t_1,...,t_n)^T}$であり$\mathrm{y_n=p(C_1|\phi_n)}$である.
尤度の負の対数を取って誤差関数を定義すると以下の(4.90)で与えられる交差エントロピー関数を得る.

```math
\begin{align*}
\mathrm{E(w)}=\mathrm{-lnp(t|w)}=\mathrm{-\sum_{n=1}^N\bigl\{t_nlny_n+(1-t_n)ln(1-y_n)\bigr\}}
\tag{4.90}
\end{align*}
```

(4.90)より負の対数尤度は全ての$\mathrm{t_n}$に対して$\mathrm{y_n=t_n}$のときに最小化されることがわかる.与えられたデータ集合では$\mathrm{t_n=0, 1}$である.また$\mathrm{y_n}$が$\mathrm{y_n=0, 1}$を取りうる時、$\mathrm{w^T\phi}$の値は$\mathrm{\pm\infty}$である.したがってベクトル$\mathbf{w}$の値を$\mathrm{\infty}$とすることでロジスティック回帰モデルの最尤解が得られることが示された.
Office2016 突然「文字列領域が不足しています」というエラー。Accessで文字化けも。

#現象
Office2016 Personal
Access2019

上記環境で業務システムを運用。
2020年6月初旬
突然「文字列領域が不足しています」というエラーも発生。
おまけにSQLで取得した数値が文字化け。

Office、Accessを再インストールしてもダメ。
PCを再インストールしてもダメ。

#原因
2020年6月に配信されたWindowsUpdate
Officeビルド番号：16.0.12827.20336

これが原因だと判明。

#対策
ビルド番号：16.0.12730.20236
ここまで戻した結果、正常動作を確認。

#以前のバージョンに戻す方法
１．管理者でコマンドプロンプトを開く

２．コマンドプロンプトにて以下を実行
    cd %programfiles%\common files\Microsoft shared\clicktorun

３．続けて以下を実行　※実行前は作業中のファイルは閉じましょう。
   officec2rclient.exe /update user updatetoversion=16.0.12730.20236

４．「Officeの更新プログラムをダウンロードしています...」が表示される。

５．処理が完了したらOfficeのバージョンを確認して終了。
リレー駆動をシミュレーションする

#はじめに
 現在のプロジェクトで、AIプログラムでPLC側のリレーを駆動する必要があり、関連技術情報を詳しく書いておく。

#リレーの構造
 今回、PLCに設置されているリレーは、HONGFA製のHF18FF型である。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208980/6e1bfcd9-78c3-e835-e8a9-984118897936.png)
 リレーの構造を下記の図に示す。
SPDTのスイッチを形成する接点部があり、ここが実際のPLC側のスイッチング動作を担当する。
 このスイッチのON/OFFを動作するため、電磁石を利用し、接点部の稼働接点を動かす。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208980/fc98b274-3e71-70d9-4f84-81854107e571.png)

 普段、コイルを動かす部分を1次側、実際のスイッチングされる部分を2次側と呼ぶ。なんで、こんな面倒なことをするかと言うと、1次側と2次側を電気的に絶縁するためである。下記の絵を見ると、リレー駆動電極とスイッチング電極は、コイルの磁場で連結されているが、電気的には分離されている。もし、2次側にサージなどが発生した場合、この絶縁構造により、1次側の回路は影響を受けないで済むことになる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208980/e6f9726f-6a77-fae7-7c52-3296b2bd748f.png)

#リレーの特性
 ミスミのHPに、このリレーの特性が書いてあったので転載する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208980/47a3fd15-ee52-ec01-8904-0bbdc36b63e3.png)

-定格電圧：リレーをDC駆動するとき、必要な電圧を言う。
-定格電流：リレーをON/OFFするために、コイルに流す電流のこと。これより電流が少なく流れると、コイルが動作しなくなる。
-動作電圧：リレーをON/OFFするための、閾値電圧である。このリレーは、24Vの80%の19.2Vを超えた時点でON動作をする。
-コイル抵抗：リレーのコイルの直流抵抗である。思った以上高くてびっくり。

-絶縁抵抗：リレーがOFFの状態でのスイッチの電気抵抗。1000メガΩ。要は絶縁されていること。
-接触抵抗：リレーがONNの状態でのスイッチの電気抵抗。接点の抵抗で100ミリΩ。

#回路シミュレーション上のリレー
リレーを回路図と書くと下記のようになる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208980/d414c6b1-1b7a-f158-20cc-a43ca03f022e.png)

Spiceで、電圧制御スイッチング素子としてリレーを表現する。Spiceでは　**.model**という関数のようなものを用いる。

```Spice
.model MY_Relay SW(Ron=100m, Roff=1000Meg Vt=19.2)
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208980/622939da-c756-2110-5f25-a4a740c9aa1c.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208980/8b025f30-a15f-f2d5-dac7-8caca2b6a55a.png)

#リレー駆動シミュレーション
1次側に24Vを、2次側に100Vを連結し、間のリレーを利用して、2次側を動かす。
下記のようなSpice回路を作成する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208980/78c018e3-ae64-39f5-ba01-a7a0f483f5f4.png)

下記の図に、シミュレーション結果を示す。
上部は、1次側の電圧の波形。下部に2次側の電圧の波形を示す。
設計通り、リレー駆動ができていることが確認できた。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208980/9a48135a-d161-efa8-0cd3-7b880045977b.png)


#まとめ
1. リレーの構造と動作原理を理解した。
2. リレーの回路をSpiceでシミュレーションし、動作していることを確認した。

- **後続記事を書きました。**
- [x] https://qiita.com/kotai2003/items/b0305f1df96e98a98c0e


#参考資料
1. [初心者のためのLTspice 入門　コイルを利用した電源回路　(2)　電圧制御スイッチで負荷をON/OFFする](https://www.denshi.club/ltspice/2018/05/ltspice-2onoff.html)

2. [制御盤用ミニパワーリレーGPR-M　2C接点](https://jp.misumi-ec.com/vona2/detail/110400266840/)
3. [Simulating Relays](https://hackaday.io/project/110288-click-clack-clock/log/138116-simulating-relays)
4. [How can I model a relay in LTSpice IV?](https://electronics.stackexchange.com/questions/185855/how-can-i-model-a-relay-in-ltspice-iv)
Javascriptの実行時間を日時で表示

# プログラムの起動開始時刻と終了時刻をミリ秒で取得した後日時で表示するメモ
※注：  筆者脳筋につきゴリゴリやる
 
```javascript:elapsed_time.js

let start_time = new Date();

// Do something...

let elapsed_time = Date.now() - start_time;

let ms=elapsed_time % 1000,                 // ミリ秒
s = elapsed_time % 60000 / 1000 | 0,          // 秒
m = elapsed_time % 3600000 / 60000 | 0,       // 分
h = elapsed_time % 86400000 / 3600000 | 0,    // 時
d = elapsed_time / 86400000 | 0;              // 日

console.log('起動時間'+(d?d+'日':'')+(h?h+'時間':'')+(m?m+'分':'')+s+'秒'+ms);

```
- 軽く解説
  - 1秒は1000ミリ秒
  - 1分は60000ミリ秒
  - 1時間は3600000ミリ秒
  - 1日は86400000ミリ秒
  - 0とORをとることによって小数点以下が消える。
  - 三項演算子はカッコでくくらないと文字列と合わせてくれない。
  - テスト環境はNode.js
   
### 2020/6/17 19時追記
- @rfc828 さんにコメント欄でご指摘いただきました。私の脳筋コードと違いとてもスタイリッシュで好みだったので紹介させていただきます！ありがとうございます！

- 日・時・分・秒の変数計算のところです。

```stylish.js
let t = elapsed_time,
    ms = t % 1000,
    s = ~~(t /= 1000) % 60,
    m = ~~(t /= 60) % 60,
    h = ~~(t /= 60) % 24,
    d = ~~(t /= 24);
```
`~~`を付けることによって小数点以下を切り捨てることができるのですね。勉強不足でした。カッコ内で一時変数に順次代入していくことで、ミリ秒→秒→分→時→日の変換がとても分かりやすいと思いました。

---
　私が気がついていない誤字・脱字、それは違うよボケェ！というところあれば私としても是非直したいので教えてください。
UbuntuにWineを入れてWindowsのプログラムを使おう

# 全部ここに書いてある

これから書くことは[WineHQ](https://wiki.winehq.org/Ubuntu)に全て書いてあることなので、英語に抵抗が無い方は公式のほうをちゃんと見て下さい。以後は**クソザコ英語君**向けです。

## 64bitOS向け

事前に32bit向けのプログラムを利用できるようにします。

```bash
sudo dpkg --add-architecture i386 
```

## リポジトリの鍵を入手

```bash
wget -O - https://dl.winehq.org/wine-builds/winehq.key | sudo apt-key add -
```

## リポジトリの追加

お使いのOSに合うコマンドを入力して下さい。

|Ubuntuバージョン|コマンド|
|:----------------:|:-----------------:|
| Ubuntu 20.04 | sudo add-apt-repository 'deb https://dl.winehq.org/wine-builds/ubuntu/ focal main' |
| Ubuntu 19.10 | sudo add-apt-repository 'deb https://dl.winehq.org/wine-builds/ubuntu/ eoan main' |
| Ubuntu 18.04 Linux Mint 19.x |sudo add-apt-repository 'deb https://dl.winehq.org/wine-builds/ubuntu/ bionic main' || will
|Ubuntu 16.04 Linux Mint 18.x|sudo add-apt-repository 'deb https://dl.winehq.org/wine-builds/ubuntu/ xenial main'|

```bash
sudo apt update
```

## パッケージ群のインストール

目的に応じて以下のうち**1つ**を実行してください！

```bash
# Stable branch
sudo apt install --install-recommends winehq-stable

# Development branch
sudo apt install --install-recommends winehq-devel

# Staging branch
sudo apt install --install-recommends winehq-staging
```

## 試してみる

[cpu-z](https://www.cpuid.com/softwares.html)をダウンロードしてみる。実行ファイルを**右クリック - 別のアプリケーションで開く - wine Windows プログラムローダー**で実行する。

※ なんかダウンロードしろって言われるかもしれない。その場合は素直に従っておくこと！

![Screenshot from 2020-06-17 16-23-35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246065/3a654d83-a1ee-3b3e-a300-7916a19d1d3b.png)

やりました。
Laravelで3000行程度でinsert上限になってしまった件

Laravelか、MySQLの仕様かは分かりませんが、データベースに10000行ほどなのでループではなくてinsertで一括保存をしようとして、はまりました。

勝手に、数万行くらいinsertできるものという謎の思い込みがあり、「やっぱ思い込みはよく無いよね」という話と、「エラーログが最強だよね」という話。


あるデータをinsertで一括保存しようとしたが、なぜか3200行を超えるあたりでエラーになる。
foreachでならエラーが起きないし、3277列目がエラーの起点だったのですが、3277を単一指定で保存しようとすると成功する。

この時点で、上限が頭に思い浮かぶも、「いや、現代においてたった3000行程度で上限なわけない！と違う理由を探す。


ここで、ひどいことに、このクラスはキューで処理をしていたので、phpのエラーログを見るのが面倒で、面倒くさがってゴチャゴチャいろんなトライをしていたんですね。

でも、ダラダラと３日目に入り、キューではなくページでルートを作り直してみると、、、

laravel Prepared statement contains too many placeholders

というなんとも分かりやすいエラーが。。

https://qiita.com/Shun_Nagahara/items/93641263578782f885bf

このように、1000行ずつに分けてinsertすることであっさり解決しましたとさ。



素人は、思い込むべからず。

面倒くさがらずに、エラーログを見るべし。