OmniAICreator/Qiita-1.07M huggingface dataset:
ソリューションアーキテクト対策_DWHほか篇

## はじめに
試験勉強した際のメモを自分用に記事化。
内容は公式やBlack Beltの写経ですので目新しいことはありません:pray:


## Redshift
### Redshiftとは
リレーショナルデータベース型のデータウェアハウス。
並列処理ができるのでパフォーマンスが高い。


### Redshiftの概要
Redshiftデータウェアハウスは、ノードと呼ばれるコンピューティングリソースの集合で、クラスターと呼ばれるグループに編成されている。
で、各クラスターはAmazon Redshiftエンジンを実行し、1つ以上のデータベースを含む。


### Redshiftクラスターの費用対効果について
Redshiftはスナップショット用に無料ストレージを提供しているが、上限を超えると課金が発生する。
なので不要なスナップショットを消したりするサイクルが必要。


### RedshiftのWLM(Work Load Management)
Redshiftのクエリ処理に対して、割り当てるRedshiftのリソースを指定する機能。
クエリ処理をキューとして実行順序を定義することが可能になる。

### Redshiftの拡張VPCルーティング
Redshiftクラスター間のすべてのトラフィックがインターネットを通過しないようにするには、拡張VPCルーティングを使用する。
使用することでクラスターとデータリポジトリ間の全てのCOPY, UNLOADトラフィックがVPCを経由することを強制する。
これによりVPCの機能(SG, ACL, IGW, DNSサーバー)およびVPCフローログを使用することが可能になる。

#### 類似の機能
・VPC間の接続に利用されるVPCピアリング。Redshift〜S3間のコネクションには使わない。
・NATGWはプライベトートサブネットのインスタンスにはインターネットから接続できないようにするいつものやつ。
・VPCエンドポイントはVPC外のサービスとの接続や連携ができるようになる。Redshift〜S3間のコネクションには使わない。

## AWS StorageGateway
### AWS StorageGateWayとは
オンプレミス環境のストレージをAWSに拡張するサービス。

・キャッシュ型ボリュームゲートウェイ
プライマリーはS3ストレージ。
頻繁にアクセスするデータはオンプレのキャッシュに保存することで低レイテンシーなアクセスが可能になる。

・保管型ボリュームゲートウェイ
プライマリーはオンプレミスストレージ。バックアップをS3に保存する。


## Amazon FSx
### Amazon FSxとは
Windows File Serverと互換性のあるストレージ。
SMBプロトコルを使ってる。主にWindowsシステムで使用する。
Windowsでストレージを共有するならFSxで、通常はEFS。

なのでWindows File ServerをAWSクラウド上で利用したい場合にFSxを利用する。
ちなみにSMBプロトコルはアプリケーションレベルのネットワークプロトコル。

それ以外の細い特徴は、
・AccessControlLists(ACLs)
・シャドウコピー
・ユーザークォータ

などのWindowsネイティブファイルシステムの機能をサポートしている。
あとActive Directoryの機能もサポートしているとのこと。


### S3 Transfer Acceleration
長距離のデータ転送。
クライアントとS3バケットの間で長距離にわたるファイル転送を高速・安全・簡単に行う。
各リージョンからS3へのデータ転送が容易に実現できる。CloudFrontを使っている。


### S3をトリガーにしてサービスを実行できるのは？
- SNS
S3をトリガーとしてメールなどを通知できる

- SQS
S3をトリガーとしてStandardキューを配信できる

- Lambda
S3をトリガーとしてLambda関数を実行できる


## Glacier
### Glacier Deep Archive
Glacierよりも更に安くデータ保存が可能だが、データ取得は更に遅くなる中長期保存用ストレージタイプ。
標準取り出しで12時間以内、大量取り出しで48時間以内の取り出しが可能。


### Glacierの管理方式的な
- ボールトポリシー
ボールトで直接アクセスポリシーを制御する

- データ取り出しポリシー
データ取り出しに関する制限を定義

- ボールトロックポリシー
ロックによって変更を禁止することにより、コンプライアンス管理を強力に実施することが可能

ちなみにボールトは、アーカイブを格納するコンテナのことを指す★


### S3 Glacierの種類(要暗記)
- S3 Glacier Retrieval
通常のGlacier。データの取り出し方法については以下の通り。
　迅速：通常1分〜5分。保証することをプロビジョニングキャパシティと言う
　標準：デフォルト設定。通常3〜5時間
　大容量：一番安価。通常5〜12時間

- S3 Glacier Instant Retrieval
ミリ秒単位で取り出せるタイプ

- Glacier Deep Archive
最安。7年〜10年単位でアクセスされないデータ向け



## ElastiCache
### ElactiCacheが得意なのは？
リアルタイムのランキング処理やゲームのアイテム出現など、行動データ記録に応じた処理が得意


## おわりに
引き続き追記します！
以上です。
Amazon Pollyについて

AWS MLS資格対策より、Amazon Pollyが範囲のため、使ってみた。

https://d1.awsstatic.com/ja_JP/training-and-certification/docs-ml/AWS-Certified-Machine-Learning-Specialty_Exam-Guide.pdf

# Amazon Polly
テキスト文を音声に変換するサービス。

## 無料枠
1年間の無料枠期間内に、1 か月あたり 500 万文字まで、音声または Speech Marks リクエストを利用可能。

https://aws.amazon.com/jp/polly/pricing/

## 実際に使ってみた
一番左の「テキスト読み上げ機能」をクリックし、画面が遷移されたことを確認。
その後、「音声を聴く」をクリックすると、、、**女性の声が聞こえます！**
![スクリーンショット 2022-04-29 20.48.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263017/ac72fb14-75a8-dd5d-40cc-3f65f5e24c0c.png)

「音声」を男性に変えると、**男性の声が聞こえます！**
![スクリーンショット 2022-04-29 20.48.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263017/c8c5b2c8-7faf-2307-a3bd-802a6ee8aa73.png)


言語も多種多様です！

![スクリーンショット 2022-04-29 20.43.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263017/3e6feab3-1672-3496-73c8-e26160711260.png)

発音に問題があれば、「音声ファイル形式の設定」「発音のカスタマイズ」で対応可能です!
![スクリーンショット 2022-04-29 20.45.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263017/d290961b-9ec2-124f-6783-53bea612501a.png)
【Rails】WebpackerでインストールしたVueが表示されない

Webpackerを利用してVue.jsをインストールしたところ、`Hello Vue!`を表示させることができませんでした。
解決法を得るのに時間がかかってしまったので、同じ状況に遭遇した方向けに情報を残しておきます。
結論から言うとインストールされたVueのバージョンが原因でした。

## 前提
まず、不具合が発生するまでの過程をまとめると下記の流れです。

### Vueのインストール
まずは下記のコマンドでWebpackerをインストール
```
$ rails webpacker:install
```

次にWebpackerでvueをインストール
```
$ rails webpacker:install:vue
```

### ルーティングを追加
```config/routes.rb
Rails.application.routes.draw do
  get 'home', to: 'home#index'
end
```

### コントローラーを作成

``` app/controllers/home_controller.rb
class HomeController < ApplicationController
  def index
  end
end
```

### viewファイルを作成
``` app/views/home/index.html.erb
<%= javascript_pack_tag 'hello_vue' %>
```

ここまでを行い、`rails s`でサーバーを起動して[http://localhost:3000/home](http://localhost:3000/home)にアクセスすると、通常なら`Hello Vue!`が表示されるはず、、、
ですが今回僕の場合はただのまっしろな画面でした

## 解決法
原因は`rails webpacker:install:vue`でインストールされたVueのバージョンが3系だったことみたいです。
なので、`package.json`を編集してvueを2系にバージョンダウンしました。
最初にインストールされていたのが下記
``` package.json
    "vue": "^3.2.33",
    "vue-loader": "^17.0.0",
    "vue-template-compiler": "^2.6.14",
```
これを下記に変更して
```package.json
    "vue": "^2.6.14",
    "vue-loader": "^15.7.0",
    "vue-template-compiler": "^2.6.12",
```

`$ yarn install`を実行して再インストールすることで、[http://localhost:3000/home](http://localhost:3000/home)で`Hello Vue!`が表示されるようになりました。

## 参考
[Ruby on Rails + Vue.jsで環境構築](https://zenn.dev/n199603/articles/a555f46fb6614d)
MIME とは

## 勉強前イメージ

見たことはあるんやけど・・・なんやっけ？思い出せない

## 調査

### MIME とは

マイムと読み、Multipurpose Internet Mail Extensionの略になります。

電子メールは元々テキストベースのシステムで英語の仕様が前提となっており、ASCIIコードの範囲内でしか記載ができなかったのです。
インターネットの普及によって非ASCIIコードを使用する国も使用するようになりました。
MIMEを使用することで各国の文字を本文に記載することができ、また画像や音声データなどの文字以外の様々なデータを
非ASCII文字同様ASCII文字に変換してメールを送信します。

### MIMEタイプについて

MIMEタイプの形式についてはメールのヘンダーに記載されています。

例えば、テキストのみのメールは以下のように表示されたり

![1元のメッセージ - Google Chrome 2022-04-29 20.31.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/7462ec2f-d3ac-b579-c56b-e1c560c4470d.png)

画像を送った際には以下のように表示されました。

![2元のメッセージ - Google Chrome 2022-04-29 20.33.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/16128187-931e-e0c5-e73d-645d92238ac1.png)

## 勉強後イメージ

メールってASCIIしかダメで、拡張して送れる様になったのね。それがMIME

## 参考

- [MIME 【Multipurpose Internet Mail Extensions】](https://e-words.jp/w/MIME.html)
- [MIME（Multipurpose Internet Mail Extensions）～前編](https://atmarkit.itmedia.co.jp/ait/articles/0104/10/news002.html)
Windows 10 Pro に WSL2 をインストールしたときのメモ [2021/12ころ]



## 概要

**2021年12月**に Windows 10 Pro に WSL2 をインストールしたときの手順メモ

ただし、正確な手順は、下記公式ドキュメントを参考にすること.

### 公式ドキュメント

https://docs.microsoft.com/en-us/windows/wsl/
https://docs.microsoft.com/en-us/windows/wsl/install-manual

　

## 手順

#### 0. UEFI or BIOS の Virtualization を有効にしておくこと

CPU による仮想化支援機能である Virtualization を有効にする.

具体的な手順は、PC によって異なるので省略する.


#### 1. OS バージョンが導入基準を満たせているか確認する

```
Winキー + r 
↓
「winver」と入力する
```

今回は、`バージョン 20H2 (OS ビルド 19042.1348)` であり、公式が求める基準を満たしていた.

　

#### 2. WSL をインストールする

##### 2-1. 管理者権限で PowerShell を開く

```
「Winキー + r」
↓
「powershell」と入力する
↓
「Shift + Ctrl」を押しながら Enterキーを押す
↓
「はい」を選択する
```

##### 2-2. WSL と 仮想化機能 を有効にする

起動した管理者権限の PowerShell ウインドウで次を実行する

```
> dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
> dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
```

ただし、正確なコマンドは、下記公式を見ること.

WSL2 は開発が活発なはずなので、手順が変更になっている確率高い.

https://docs.microsoft.com/en-us/windows/wsl/install-manual#step-2---check-requirements-for-running-wsl-2
https://docs.microsoft.com/en-us/windows/wsl/install-manual#step-3---enable-virtual-machine-feature


##### 2-3. PC を再起動する

略

　

#### 3. WSL2 への Upgrade をする

下記 URL をクリックすると、WSL2 への Upgrade インストーラ の DL と インストールが開始する

https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi

なお、正確なコマンドは下記公式を見ること

https://docs.microsoft.com/en-us/windows/wsl/install-manual#step-4---download-the-linux-kernel-update-package

　


#### 4. WSL2 をデフォルトにする

(一般ユーザ権限の) PowerShell ウインドウで、次のようにあるいは「`wsl --set-default-version 2`」を実行する.

```
> wsl --set-default-version 2
```


#### 5. Microsoft Store より、Ubuntu 20.04 をインストールする

```
Winキー
↓
「Microsoft Store」と入力し、Enter を押す
↓
Microsoft Store が起動するので、「ubuntu 20.04 lts」を検索する
↓
表示された「Ubuntu 20.04 LTS」を選択する
```

　

#### 6. WSL2 を起動する

```
Winキー
↓
「wsl」と入力して、ペンギンアイコンを実行する
```

　

#### 7. Ubuntu 20.04 が起動するのでアカウントを作成する

略

　

　

### 動作確認

　

このとき、(一般ユーザ権限の) PowerShell ウインドウで、🛑のように「2」になっていることを確認する.

```
> wsl -l -v
  NAME          STATE     VERSION
* Ubuntu-20.04  Running   2🛑
```
Docker Compose + Node でコンテナ内に node_modules を保持する

## 目的
Dockerfile で `npm install` などとすると，ビルドされたイメージ内には `node_modules` ディレクトリが作られることになる．しかし， Docker Compose で親ディレクトリにボリュームをマウントすると， `node_modules` ごと上書きされてなくなってしまう．

```dockerfile:app/Dockerfile
FROM node

WORKDIR /app
COPY package*.json ./
RUN npm install # node_modules が作られる
```

```docker-compose.yml
services:
  node:
    build: ./app
    volumes:
      - "./app:/app" # node_modules が上書きされてしまう
```


今まではこれを回避するために

```
docker compose build
docker compose run npm install # ホスト側にも node_modules を作る
```

などと二度手間を踏んでいたが，これを回避できる， i.e., イメージのビルド時にインストールした `node_modules` をコンテナ内に保持できる方法を知ったので，備忘録として残す．

## やりかた

[Docker Compose の bind mounts から node_modules を除外する方法](https://gotohayato.com/content/544/) を参考にさせていただいた．記事内では「方法B.」となっている．

```dockerfile:app/Dockerfile
# 変更なしで OK
FROM node

WORKDIR /app
COPY package*.json ./
RUN npm install
```

```docker-compose.yml
services:
  node:
    build: ./app
    volumes:
      - "/app/node_modules" # ←追加
      - "./app:/app"
```

これで，イメージのビルド時に作られた `node_modules` 内に保持して利用することができる．
参考記事内では `node_modules` という named volume を作っているが，必須ではない模様．

ただし，少なくとも筆者の環境では，ボリュームの記述順に注意しなければならない．つまり， `node_modules` の指定を先にしないといけないようであった．

おわり．
Python で型ヒントを明記する

# 当記事の目的
Python3 での型ヒントの書き方を紹介する。


# 型ヒントを書く理由
Python では型を示さずとも変数、引数、戻り値の定義ができるので、型がいまいち分かりづらい。
そこで型ヒントを明記すると、それぞれの変数、引数、戻り値の型が一目見てわかるようになり、親切な実装になる。


# 基本的な書き方

```python
# メソッドの引数と戻り値の型を示す
def get_item(id: int) -> str:
    """
    item を取得する

    :param id: ID
    :return 文字列
    """
    # 変数の型を示す
    item_name: str = "hogehoge"
```


# 各種型ヒントの書き方
個人的に使用頻度の高い型の型ヒントの使い方を、以下に示す。

## int
数値型の場合。

```python
# 使用例
number: int = 1
```

## str
文字列型の場合。

```python
# 使用例
name: str = "piyopiyo"
```

## List
リスト型の場合。（[ドキュメント](https://docs.python.org/ja/3.10/library/typing.html#typing.List)）

```python
from typing import List
# 数値のリストである場合
id_list: List[int] = [1, 2, 3]
```

※ `list` もあるが、こちらは Python 3.9 以降非推奨となった模様。

## Dict
辞書型の場合。（[ドキュメント](https://docs.python.org/ja/3/library/typing.html#typing.Dict)）

```python
from typing import Dict
# 文字列と文字列の辞書の場合
respose_dict: Dict[str, str] = {"name": "fugafuga"}
```

※ `dict` もあるが、こちらは Python 3.9 以降非推奨となった模様。

## Union
複数型が入り得る場合。（[ドキュメント](https://docs.python.org/ja/3/library/typing.html#typing.Union)）

```python
from typing import Dict, Union
# int または str が入り得る場合
Union[str, int]
# 使用例
param_dict: Dict[str, Union[str, int]] = {"id": 1, "name": "hogepiyo"}
```

## Optional
None またはそれ以外の型が入り得る場合。（[ドキュメント](https://docs.python.org/ja/3/library/typing.html#typing.Optional)）

```python
from typing import Optional
# int または None が入り得る場合
Optional[int]
# 使用例
def get_japanese_str(name: str) -> Optional[str]:
    """
    名前に「日本人の」が含まれていれば「日本人です」との文字列を、そうでなければ None を返す

    :param person_name: 判定対象の人の名前
    :return 「日本人です」または None
    """
    if "日本人の" in name:
        return "日本人です"
    return None
```


# 参考
[Python 型ヒントドキュメント](https://docs.python.org/ja/3/library/typing.html#)
NVIDIAのおかげでGPU版Kaggle Dockerの再構築でGWの一日を溶かした

# 0.Intro
GWに入ったので機械学習の勉強に専念できると思いきや色々問題があってKaggle Dockerを再構築しようとしました。前回の構築から半年以上経っていたので丁度いいかなと思い
```
./build --gpu
```
とすると途中で止まる。
エラーは以下のような感じ。
```
W: GPG error: https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64  InRelease: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY A4B469963BF863CC
E: The repository 'https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64  InRelease' is not signed.
```
色々調べた結果、
[Updating the CUDA Linux GPG Repository Key](https://developer.nvidia.com/blog/updating-the-cuda-linux-gpg-repository-key/)
とのこと。
本家がこのタイミングでセキュリティの強化という非常にご尤もなことをなさったので起きているエラーでした。

色々調べた結果回避策は以下のようになりました。

# 1.手順

まず
```
./build --gpu
```
を走らせる。

すると配下に生成される
```
docker-python/.generate/gpu.Dockerfile
```
をコピー

gpu.Dockerfileの27行目辺りに
以下を追記
```
RUN rm /etc/apt/sources.list.d/cuda.list
RUN rm /etc/apt/sources.list.d/nvidia-ml.list
RUN apt-key del 7fa2af80
RUN apt-get update && apt-get install -y --no-install-recommends wget
RUN wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/cuda-keyring_1.0-1_all.deb
RUN dpkg -i cuda-keyring_1.0-1_all.deb
```
**※本家の記事にもあるようにwgetするOSとarchは適宜変更してください。**


次に実行するシェルbuildを編集

末尾を
```
docker build --rm --pull $CACHE_FLAG -t "$IMAGE_TAG" -f gpu.Dockerfile $BUILD_ARGS .
```
と変更して下さい。
末尾のすぐ上を見てもらうと分かるように、buildは最新のDockerfileをとってきてオプションの設定を反映させる為に書き換えた結果を実行するためです。
ですのでオプションを設定を反映後のDockerfileに対して今回の回避策をコードを追加する必要があります。

これで
```
./build --gpu
```
を実行すると冒頭のエラーを回避できます。
僕のように貴重なGWの一日を溶かす人が一人でも少なくなればと思い記事にしました。
Laravelのcolumn-sortableでnullを含むカラムのソートTips


[column-sortable](https://github.com/Kyslik/column-sortable)めちゃ便利です。
一覧のソートはこれで十分感あります。
通常の使い方はマニュアルで十分なので、nullを含むソートを少し悩んだので備忘を残しておきます。

### column-sortableを使わない場合
そもそもLaravelでnullをorder byしたい場合は以下のように、nullをソートしてからそれ以外をソートするように以下のように書く。

```
->orderByRaw('列名 IS NULL ASC')->orderBy('列名')
```
または
```
->orderByRaw('列名 IS NULL DESC')->orderBy('列名', 'DESC')
```

### column-sortableの場合
以下のようにオーバーライドできるとマニュアルにあります。
https://github.com/Kyslik/column-sortable#columnsortable-overriding-advanced

なので以下のようになります。
```
    public function xxxSortable($query, $direction)
    {
        return $query->orderByRaw('列名 IS NOT NULL ' . $direction)->orderBy('列名', $direction);
    }
```

簡単〜
Arduino UNOとマイコン応用I2C超音波距離センサーで遊ぶ(タイマー割り込み)(LPF)



目的
オリジナルI2C超音波距離センサーをつかい
任意の時間でローパスフィルター(LPF)を掛けた値の表示


![o_con367.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/246925c8-b3b3-ef5a-6f3b-131afeac1316.jpeg)


![o_con366.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/f1134685-4825-7952-7f40-d2af1aa9a7ab.jpeg)




https://qiita.com/caa45040/items/b74c0e26e768fdf750a3



```c++


//i2c_master_interrupt_HC_SR04_UNO_1

#include <Arduino.h>
#include <Wire.h>

// 340m 1000ms,34m 100ms,3.4m 10ms

// 1/100秒の指定
#define AA 50 
#define BB (65536-((62500/100)*AA))


//初期化
void setup()
{
 
  //シリアルポートの初期化
  Serial.begin(9600);

  //I2Cの初期化
  Wire.begin(); //UNO

  //タイマー割り込み
  TCCR1A = 0; // 初期化
  TCCR1B = 0; // 初期化
  //TCNT1 = 3036; 
  TCNT1 = BB;
  TCCR1B |= (1 << CS12);  //CS12 -> 1  prescaler = 256
  TIMSK1 |= (1 << TOIE1); //TOIE -> 1

} //setup

int  h1,h2,h3;
int  p;
char in_l;

//int  h;

ISR(TIMER1_OVF_vect) {

  //Serial.println(millis());

  Serial.print("80,");  
  Serial.print( (int)in_l ); //UNO
  Serial.print(",0");
  Serial.println(" ");

  //TCNT1 = 3036;
  TCNT1 = BB;

}//ISR


//メインループ
void loop()
{

  int  l=0;

  unsigned char b = 200;

  //読み込み
  Wire.requestFrom(8, 1);

  while(Wire.available())  {    // 要求より短いデータが来る可能性あり
    b = Wire.read();       // 1バイトを受信
  }//while

  if( b <= 139 ) {
    l = b + 60;
  } else {
    l = ((int)(b - 140 + 20)) * 10;
  }

  //Serial.print("80,");

  // h = (h/2)+(h/4)+(l/4)
  // h = (h * 0.75) + ( l * 0.25 )
  // h = (h>>1)+(h>>2)+(l>>2); 
  
  p = (h1+h2+h3+l)>>2;
  h3 = h2;
  h2 = h1;
  h1 = l;
  in_l = (char)(p/10);

  //Serial.print( (int)in_l ); //UNO

  //Serial.print(",0");
  //Serial.println(" ");

  delay(20); // 0.5秒の待ち

} //loop





```
mysql dump seperate files

```
#!/bin/bash
[ $# -lt 3 ] && echo "Usage: $(basename $0) <DB_HOST> <DB_USER> <DB_NAME> [<DIR>]" && exit 1

DB_host=$1
DB_user=$2
DB=$3
DIR=$4

[ -n "$DIR" ] || DIR=.
test -d $DIR || mkdir -p $DIR

echo -n "DB password: "
read -s DB_pass
echo
echo "Dumping tables into separate SQL command files for database '$DB' into dir=$DIR"

tbl_count=0

for t in $(mysql -NBA -h $DB_host -u $DB_user -p$DB_pass -D $DB -e 'show tables') 
do 
    echo "DUMPING TABLE: $DB.$t"
    mysqldump -h $DB_host -u $DB_user -p$DB_pass $DB $t | gzip > $DIR/$DB.$t.sql.gz
    tbl_count=$(( tbl_count + 1 ))
done

echo "$tbl_count tables dumped from database '$DB' into dir=$DIR"
```
```
#!/bin/bash
[ $# -lt 3 ] && echo "Usage: $(basename $0) <DB_HOST> <DB_USER> <DB_NAME> [<DIR>]" && exit 1

DB_host=$1
DB_user=$2
DB=$3
DIR=$4

[ -n "$DIR" ] || DIR=.
test -d $DIR || mkdir -p $DIR

echo -n "DB password: "
read -s DB_pass
echo
echo "Dumping tables into separate SQL command files for database '$DB' into dir=$DIR"

tbl_count=0

for t in $(mysql -NBA -h $DB_host -u $DB_user -p$DB_pass -D $DB -e 'show tables') 
do 
    echo "DUMPING TABLE: $DB.$t"
    mysqldump -h $DB_host -u $DB_user -p$DB_pass $DB $t | sed 's/^CREATE TABLE /CREATE TABLE IF NOT EXISTS /' | gzip > $DIR/$DB.$t.sql.gz
    tbl_count=$(( tbl_count + 1 ))
done

echo "$tbl_count tables dumped from database '$DB' into dir=$DIR"
```
```
#!/bin/bash
[ $# -lt 3 ] && echo "Usage: $(basename $0) <DB_HOST> <DB_USER> <DB_NAME> [<DIR>]" && exit 1

DB_host=$1
DB_user=$2
DB=$3
DIR=$4

[ -n "$DIR" ] || DIR=.
test -d $DIR || mkdir -p $DIR

echo -n "DB password: "
read -s DB_pass
echo
echo "Dumping tables into separate SQL command files for database '$DB' into dir=$DIR"

tbl_count=0

for t in $(mysql -NBA -h $DB_host -u $DB_user -p$DB_pass -D $DB -e 'show tables') 
do 
    echo "DUMPING TABLE: $DB.$t"
    mysqldump -h $DB_host -u $DB_user -p$DB_pass $DB $t > $DIR/$DB.$t.sql
    tbl_count=$(( tbl_count + 1 ))
done

echo "$tbl_count tables dumped from database '$DB' into dir=$DIR"

```
```
#!/bin/bash
[ $# -lt 3 ] && echo "Usage: $(basename $0) <DB_HOST> <DB_USER> <DB_NAME> [<DIR>]" && exit 1

DB_host=$1
DB_user=$2
DB=$3
DIR=$4

[ -n "$DIR" ] || DIR=.
test -d $DIR || mkdir -p $DIR

echo -n "DB password: "
read -s DB_pass
echo
echo "Dumping tables into separate SQL command files for database '$DB' into dir=$DIR"

tbl_count=0

for t in $(mysql -NBA -h $DB_host -u $DB_user -p$DB_pass -D $DB -e 'show tables') 
do 
    echo "DUMPING TABLE: $DB.$t"
    mysqldump -h $DB_host -u $DB_user -p$DB_pass $DB $t | sed 's/^CREATE TABLE /CREATE TABLE IF NOT EXISTS /' > $DIR/$DB.$t.sql
    tbl_count=$(( tbl_count + 1 ))
done

echo "$tbl_count tables dumped from database '$DB' into dir=$DIR"
```

```
for s in *.sql ; do mysql -u user -p'password' -h db database  < $s &   done
```
ssh接続で初めてのホストへの接続を確認されないようにする方法

## はじめに

sshコマンドで接続するのが初めてホストの場合、以下のように確認される。

```
The authenticity of host '123.456.XXX.XX (123.456.XXX.XX)' can't be established.
RSA key fingerprint is SHA256:OVFZORWKLs6yOQh9SJl5N1pnXXXXXXXXXXXXXXXXXXX.
Are you sure you want to continue connecting (yes/no)?
```
直訳は以下。接続先ホストが信頼できるかどうかを確認している。

```
このホストが『123.456.XXX.XX（123.456.XXX.XX）』として本物か確認できていません
RSAキーのフィンガープリントはSHA256：OVFZORWKLs6yOQh9SJl5N1pnXXXXXXXXXXXXXXXXXXXです。
接続を続行してもよろしいですか（はい/いいえ）？
```

（※追記
最初、一行目は「ホスト「123.456.XXX.XX（123.456.XXX.XX）」の信頼性を確立できません」と訳していましたが、[コメント](https://qiita.com/akko_merry/items/71789fcc889eabdea405#comment-334c9c364a5eb9cd94a2)にて、`authenticity`の本来の意味をより詳しく教えていただきましたので修正いたしました。ありがとうございます！）

フィンガープリントとは、接続先の公開鍵から計算されたハッシュ値のこと。

この確認をされないようにする方法を2つメモしておきます。

## 方法
### (1) sshコマンドにオプションを追加

`StrictHostKeyChecking=no` オプションを追加する。

【オプションなし】
```
ssh 123.456.XXX.XX
```
↓
【オプションあり】

```
ssh -o StrictHostKeyChecking=no 123.456.XXX.XX
```


### (2) SSHクライアントのconfigファイルに設定

ユーザー単位では`~/.ssh/config`
システム全体では`/etc/ssh/ssh_config`

以下のように設定する。
```
host 123.456.XXX.XX
	StrictHostKeyChecking no
```

※パーミッションは600にしておかないとエラーが出る。

```
chmod 600 ~/.ssh/config
```

（今回の話とはズレるけど、このファイルにはこれ以外にもユーザー名、ポート番号等登録しておくとsshコマンドを簡潔に書くことができるらしい。
参考：https://qiita.com/passol78/items/2ad123e39efeb1a5286b  ）


## StrictHostKeyCheckingについて
`StrictHostKeyChecking`の取りうる値は

- yes
- no
- ask (デフォルト)

デフォルトが`ask`なので冒頭のように確認される。

## 2回目以降の接続でなぜ確認されなくなるのか
冒頭の確認で`yes`と入力した場合、`known_hosts`ファイルにに接続先ホストの公開鍵が登録される。
すると、2回目以降はsshコマンドによって自動的にホスト認証が実施される。
（登録された公開鍵とサーバーの公開鍵が一致しているかを確認する）



※`known_hosts`はテキストファイル。
ファイルの場所は、システム全体では`/etc/ssh/known_hosts`、
ユーザー単位の場合`~/.ssh/known_hosts`。


## 今回、接続確認をしない設定にする理由

「初回の接続確認をなくす ＝ 安全性も低くなる」ということなので、どうしても必要な時だけに留めるべきです。

それでも今回確認されないようにしたかった理由は、

- 接続元であるDockerのコンテナから`~/.ssh`ディレクトリ内のファイルが消えてしまうことがあり（原因追求できてないけどコンテナの再起動が原因？？）
- 初回の接続で`~/.ssh/known_hosts`ファイルに接続先の公開鍵が登録できても、ファイル自体が消えてしまうとまた接続の際に確認されるようになってしまい
- 特に今回は定期的に実施する自動処理の中でssh接続をしたく、確認があるとエラーで処理が止まってしまう

というのを防ぎたかったからです。

ちなみに、同じ理由（`~/.ssh`ディレクトリ内のファイルが消えてしまう）から、今回は2つの方法のうち「(1). sshコマンドにオプションを追加」で対応しました。
（「(2) SSHクライアントのconfigファイルに設定」だと`~/.ssh/config`に設定してもファイルが消えたら設定も消えてしまうので）


いろんなケースがあるかと思いますが、今回は当該システムや接続先ホストが社内でのみ使用するものであり、他のセキュリティ対策もしているので問題ないかと対応をしました。


※内容に間違いがありましたら教えていただけますと幸いです。

※追記
コメントにて、最初に公開鍵を登録しておく方法を教えていただきました。
ありがとうございます。
勉強になるのでぜひ読んでみてください！



## 参考
https://journal.lampetty.net/entry/wp/391
https://urashita.com/archives/34227
https://www.softel.co.jp/blogs/tech/archives/1414
https://blog.mothule.com/tools/ssh/tools-ssh-basic#known_hosts%E3%81%A8%E3%81%AF
https://rurukblog.com/post/ssh-fingerprint/
Storyboardを無効化する

## やること

- main.storybordの削除
- .xcodeprojの編集
- Info.plistの編集
- SceneDelegate.swiftの編集

## main.storybordの削除

main.storybordを削除するだけ

## .xcodeprojの編集

`General > Deployment Info`

Main Interface を空にする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648522/c9145eb2-8271-4fb2-b8e7-e42be7b1802f.png)

## Info.plistの編集

`Information Property List > Application Scene Manifest > Scene Configuration > Application Session Role > Item 0`

Storyboard Nameを削除
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648522/903b3c0a-d709-54d4-bc21-30a09c3a5d2e.png)



## SceneDelegate.swiftの編集

SceneDelegate内のwindowはstoryboardを使う場合、自動で初期化されている

storybordを無効化したことでwindowが初期化されなくなるため

rootViewControllerを指定して初期化する必要がある

```swift
class SceneDelegate: UIResponder, UIWindowSceneDelegate {

    var window: UIWindow?

    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        guard let windowScene = (scene as? UIWindowScene) else { return }
        let window = UIWindow(windowScene: windowScene)
        window.rootViewController = ViewController.init()
        self.window = window
        window.makeKeyAndVisible()
    }

	//以下略
}
```
Arduinoでキー変換器を作る（BLE編）

## 初めに

https://qiita.com/sushisushiBoo/items/7b7513f83a0b9cb3344d

でArduino Pro MicroとUSB Host Shieldにてキーボードのキー変換器を作りました。
しかし、接続するつもりのノートPCのセキュリティのせいでUSBキーボードを認識しないという罠に。。。。。
しばらく放置していましたが、BLEキーボードは認識することを発見したのでリベンジします。

Switch ScienceさんからPro Micro互換のBLE搭載Arudinoが売られているをを発見したのがきっかけです。
[ISP1807搭載Microボード（Pro Microピン互換）](https://www.switch-science.com/catalog/6939/)

また、以前に参考にさせていただいたサイトでも上記のボードの利用例を紹介されていましたので、
USB Host Shieldライブラリへのパッチ適用など参考にさせていただきました。
東京お気楽カメラ[ISP1807Microボード用のUSB Host Shield Library2.0の修正](https://okiraku-camera.tokyo/blog/?p=13128)

## BLEボードの動作確認
Switch Scienceさんのページに沿って環境を整えたらボードのサンプルからblehid_keyboardを書き込み。PCではBluetoothキーボード`SSCI ISP1807 Micro Board`として認識してペアリングできました。シリアル入力をそのままキー入力として動作することが確認できました。

## USB Host Sheildの動作確認
上述の東京お気楽カメラさんの記事のとおりにライブラリに`ARDUINO_SSCI_ISP1807_MICRO_BOARD`のifdefを追加します。
ライブラリのサンプルの`USBHIDBootKbd`を書き込見ます。
キー操作が読み取れていることが確認できました。

## キー変換器を作る
USB Host Shieldからの読み取り部分は基本的に同じですが、`sendKeyreport()`をBLE対応に変更する必要があります。
また、inoファイルに全て実装しわかりにくいのでクラスとして分離しました。

https://github.com/sushisushiboo/BLEHIDKeyboardAndMouse
S3 Glacier Deep Archive に写真を格安で保存しよう！(アップロード編)

# はじめに
この記事は[S3 Glacier Deep Archive に写真を格安で保存しよう！(料金編)](https://qiita.com/taku-y-9308/items/93c8dc5c8f86f9563acf)の続きです。


# アップロードする
S3にアップロードする方法は2種類あります。
1. マネージメントコンソールからGUIでアップロード
2. AWS CLIでアップロード

簡単にアップロードできるのはマネージメントコンソールですが、アップロード速度が遅く大容量のデータを上げると途中で固まります。
ですので、大容量のデータをアップロードする際はCLIから行う方がいいです。

## AWS CLIのインストール
以下の記事を参考にインストール＆IAMユーザーの作成までおこなってください。
ちなみにリンク先ではIAMユーザーにアタッチするポリシーは「IAMReadOnlyAccess」で行っていますが、これだと今回の用途には使えないので「AmazonS3FullAccess」で読み替えてください。

https://dev.classmethod.jp/articles/lim_aws_cli_start/

## AWS CLIを使ってアップロード
### バケットを作成
S3に保存するためには、データを保存するためのバケット（バケツみたいなイメージ）が必要となります。
マネージメントコンソールからでも作成できますが、以下のコマンドで作成することも可能です。
以下に注意しながらバケットを作成しましょう。

>バケット名はグローバルに一意で (Amazon S3 全体?で一意)、DNS に準拠している必要があります。
バケット名には、小文字の英文字、数字、ハイフン、およびピリオドを使用することができます。バケット名の先頭と末尾は文字または数値とし、ハイフンまたは別のピリオドの横にピリオドを使用することはできません。


~~~shell
$ aws s3 mb s3://bucket-name
~~~
### インストール確認
~~~shell
$ aws --version
aws-cli/2.4.7 Python/3.8.8 Darwin/19.6.0 exe/x86_64 prompt/off
~~~

### 該当ファイルまで移動
~~~shell
$ cd uploadphotos
~~~

### S3にファイルをアップロード
~~~shell
$ aws s3 sync . s3://my-bucket/path --storage-class DEEP_ARCHIVE
~~~
syncコマンドでは自動的にオプションをつけなくても再帰的にコピーしてくれます。

### ファイルの確認
~~~shell
$ aws s3 ls s3://mybacket-name
~~~
さらにその配下のディレクトリ内を見たい場合は
~~~shell
$ aws s3 ls s3://mybacket-name/directory-name
~~~
みたいな感じで見ることができます。
S3 Glacier Deep Archive に写真を格安で保存しよう！(料金編)

# はじめに
突然ですがみなさん撮りためた写真ってどうしてますか？
実家に僕や兄弟が小さかった頃の写真や動画が100GB以上HDDに保存されているんですが、
2台のHDDで冗長は組まれているもののちょっと怖いので両親にS3の使用を提案してみたときの話です。

長くなりそうなので、今回は料金の確認編です。

アップロード編はこちら
[S3 Glacier Deep Archive に写真を格安で保存しよう！(アップロード編)](https://qiita.com/taku-y-9308/items/6294b7198c72fb98768e)

# 想定読者
・S3を一度でも使ったことがある方
# S3とは
言わずとしれたAWSのストレージサービスですね。
保存した分だけ課金される従量課金制で、無制限に保存することができます。
## S3 Glacier Deep Archiveとは
S3にはストレージクラスというものがありまして、一言でまとめると利便性によって1GBあたりの値段が変わります。
S3 Glacier Deep Archive　は安い代わりに「保存したデータをダウンロードしよう！」と思ってから実際にダウンロードができるようになるまで半日〜2日かかります（笑）

保存したものがすぐに取り出せるけど高い
↑
↓
取り出すのにめっちゃ時間がかかるけどめっちゃ安い

みたいな感じです。
| ストレージクラス | 単価 | 取り出しにかかる時間 |
|---------------|-----| ---- |
| S3 スタンダード| 0.023USD/GB | すぐ |
| S3 Glacier Deep Archive | 0.00099USD/GB | 12~48時間 |

これくらい違います。
100GB保存しても12〜13円/月です。

## S3の料金体系
これが割とややこしく、Googleドライブなどのストレージサービスとは料金体系が異なります。

また Glacier Deep Archiveには**最低利用期間180日が設定されています。**
180日以内に削除してしまうと、一気に180日までの残り料金が請求されてしまいますので注意してください。
といっても大した値段はないですが。。。

以下**特に記載なければバージニア北部リージョンの値段となります。**

S3の料金=PUT/GETなどのリクエスト料金+保存料金+取り出し料金

先に僕が写真4500枚・27GBを保存している時の料金を公開しておきますね。
アップロードした月はリクエスト料金がかさむので少し高くなりますが、その後触らずに保存しているだけだとこれくらいの料金で収まります。
|月|料金|
|--|--|
|2月|0.26USD|
|3月|0.03USD|
|4月|0.03USD|
### リクエスト料金
S3に保存されているデータに対して以下のリクエストを行うときにかかる料金です。
PUT、COPY、POST、LIST、GET　など

PUT：S3に対してデータを送信する際に発生するリクエスト
COPY：S3内でデータをコピーする際に発生するリクエスト
POST:S3に対してデータを送信する際に発生するリクエスト
LIST:S3内のデータを一覧で表示する際に発生するリクエスト
GET:S3内のデータを取り出すときに発生するリクエスト

PUTとPOSTの違いなんですが、おそらくブラウザからデータを送信するかCLIで送信するかの違いかなと思ってます。
ブラウザからデータを送信する時はHTTPのPOSTリクエストを使うからっぽいですね。
https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPOST.html

ちなみに値段に関しては、
PUT、COPY、POST、LIST >>>越えられない壁>>>ほか全てのリクエスト
って感じです。
|PUT,COPY,POST,LIST|他全てのリクエスト|
|-----------------|--------------|
|0.05USD/1,000 リクエスト|0.0004USD/1,000 リクエスト|

1つファイルをアップロード（PUT）すると1PUTリクエストなので
1000ファイルアップロードすると、0.05USDかかる計算ですね。

### 保存料金
こちらは保存している限り毎月かかる料金です。
バージニア北部リージョンのほうが半分位の値段なので特にこだわりがなければバージニア北部リージョンを選択すればよいかと思います。
もちろん、安い分消失のリスクがあるとかではないです。
|リージョン|料金|
|--------|----|
|バージニア北部リージョン|0.00099USD/GB|
|東京リージョン|0.002USD/GB|

### 取り出し料金
取り出し料金には2つの内訳があり、
・取り出しリクエスト料金
・転送料
となってます。
#### 取り出しリクエスト料金
これはダウンロード可能になるまでの時間で変わってきます。
S3 Glacier Deep Archiveの場合
|取り出しオプション|料金|時間|
|---|---|---|
|標準|0.10USD/1,000リクエスト|12時間以内|
|大容量|0.025USD/1,000リクエスト|48時間以内|

特に急ぎでなければ、大容量でいいかなと思います。
#### 転送量
これは取り出すデータの大きさによって課金されます。
|取り出しオプション|料金|時間|
|---|---|---|
|標準|0.02USD/GB|12時間以内|
|大容量|0.0025USD/GB|48時間以内|

なので、今僕が保存している写真4500枚・27GBを大容量オプションで取り出そうとすると
|料金タイプ|料金|
|---|---|
|取り出しリクエスト|0.5USD|
|転送量|0.0675USD|
|**合計**|**0.5675USD**|

となります。

# まとめ
ここで最後に僕の使い方で結局いくらかかるのかをまとめておきます。
写真4500枚・27GB
|どんな月か|料金|
|--|--|
|アップロードした月| 0.26USD|
|通常|0.03USD|
|ダウンロードする月| 0.5675USD|

最初と最後だけ少し料金がかかりますが、保管中は破格の値段で使うことができます。

次は実際にアップロードしてみましょう。

[S3 Glacier Deep Archive に写真を格安で保存しよう！(アップロード編)](https://qiita.com/taku-y-9308/items/6294b7198c72fb98768e)
「新機能と改善のために最新のPowerShell をインストールしてください」対処法。

# 前座

新しいバージョンは率先して人柱になって入れていく。私は速攻でWindowsもリリース初日にWindows11にした人間だ。


・・・前置きはさておき、PowerShellも最新版の7.2.3が4/26にリリースされた。

https://github.com/PowerShell/PowerShell/releases

https://qiita.com/probabilityhill/items/f56c9b2882936c296c0e

早速.msiファイルをダウンロードし上記リンクで設定。しかし、私が常時利用しているのはWindows Terminal!

![スクリーンショット (16).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/688801/6f39bd78-6114-15e7-eec7-675c63b316a7.png)


```
新機能と改善のために最新の PowerShell をインストールしてください!https://aka.ms/PSWindows
```

このような文言が、あなたのWindows Terminalに起動時表示されていないだろうか？
今回はこの文言の対処法を教えたいと思う。成功すれば

```
PowerShell 7.2.3
Copyright (c) Microsoft Corporation.

https://aka.ms/powershell
Type 'help' to get help.

PS C:\Users\*******>
```
という表記になるはずだ。

# 対処法

まず、現状の確認。$PSVersionTable コマンドを実行すると以下のようになった。

```
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

新機能と改善のために最新の PowerShell をインストールしてください!https://aka.ms/PSWindows

PS C:\Users\******> $PSVersionTable

Name                           Value
----                           -----
PSVersion                      5.1.22000.651
PSEdition                      Desktop
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
BuildVersion                   10.0.22000.651
CLRVersion                     4.0.30319.42000
WSManStackVersion              3.0
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
```
・・・。
・・・・・・・。
```
PSVersion                      5.1.22000.651
```

・・・PowerShell 5のままじゃん。7.2.3入れたはずなのに。

ということでPowerShell 7にしましょう。

デスクトップの左下の虫眼鏡マークからPowerShell 7 の所在を検索。
右クリックでプロパティを表示させるとリンク先が見つかった。

![スクリーンショット 2022-04-29 184230.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/688801/91fe6339-3ec0-ab89-e496-6cff6ef7d311.png)

私のPCではリンク先は
```
D:\Download\PowerShell\7\pwsh.exe -WorkingDirectory ~
```

と表記されていたので-WorkingDirectoryを削除してダブルクオーテーションで囲み以下のように体裁を整えた、

```
"D:\Download\PowerShell\7\pwsh.exe"
```
これをWindows Termianlの設定でコマンドラインの部分に貼り付けた。

![スクリーンショット 2022-04-29 184329.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/688801/5e4ee798-26bc-29e7-5401-0fc9b7545129.png)

設定を保存後、再起動してみた。

![スクリーンショット 2022-04-29 185741.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/688801/8dafcb02-edde-6512-40e9-00bf10056db5.png)

・・・成功！$PSVersionTableで確認してみても

![スクリーンショット 2022-04-29 190109.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/688801/7b144716-28a9-3d61-a20b-b39fd36c8182.png)

しっかり7.2.3になった。よかったよかった。では！
# 参考

https://zenn.dev/kitamu7/articles/b037ab3dcff298

https://qiita.com/probabilityhill/items/f56c9b2882936c296c0e
NFT投資し続ける必要がある5つの要因

中国が暗号通貨の売買を違法とし、四川省のすべての採掘場を閉鎖するという決定以来、暗号通貨の価値は低下しているように見え、最近の通貨サークルニュースは、ほとんど朗報ではない。 

あなたはまだ暗号通貨に自信があり、あなたの周りのゴシップに不安を感じている場合。HODL が仮想通貨に投資し、その期待に応えるまで、同じ通行人として、あなたのアイデアに従うことを<a href=https://coinledge.io/>加密藝術</a>奨励したいと考えています。 

<b><h2>1. 暗号通貨は、独立した無修正資産です

なぜ暗号通貨に投資したのか覚えていますか? 10人中9人の投資家が、暗号通貨ニュースの解説を見て、その独立性を理解したため、保有に参入したと信じています。 
確かに、従来の法定通貨とは異なり、暗号通貨は、最高の政治機関や金融部門でさえ、インフレによって暗号通貨の本来の価値を希釈できない場合でも、永遠に印刷されません。 さらに、暗号通貨は盗難防止の非常に高い性質を持っているので、保有者が自発的に譲歩しない限り、第三者によって課税または没収されること<a href=https://coinledge.io/>NFT頭像</a>はほとんど不可能です。

<b><h2>2. 真の金融の自由をもたらす

金融の自由とは、無限の富を意味するのではなく、他人に邪魔されず、自由に自分のお金を操作する権利です。
理論的には、新世代の消費者をアルゴリズム通貨のデジタル経済に参加させることは、中央銀行とそのコストと監督を必要としません。 特に、スマートコントラクトの応用は非常に広く、NFTアバターなどのプロジェクトも恩恵を受けることができ、このような中心化された世界が可能になり<a href=https://coinledge.io/>幣圈新聞</a>ます。 彼らの命令は、ブロックチェーン上の誰もが見ることができるコード化されたオープンソースのアルゴリズムに基づいて発行されました。

<b><h2>3.数字だけではない

実際、あなたが投資しているのは、数字の平凡なリストだけでなく、<a href=https://coinledge.io/>NFT藝術品</a>にリンクされている投資です。 
NFTs は、通常、ユニークで供給が限られており、本質的にデジタル希少性を作成します。 NFTs と暗号通貨は同じではありませんが、互いに非常に密接な関係にあり、どちらかの浮き沈みは他方のパフォーマンスに影響を与えます。 したがって、NFTs の価値を信じるなら、当然、同じソースの暗号通貨を捨てるべきではありません。 

<b><h2>4. より良い未来のために

確かに、<a href=https://coinledge.io/>加密貨幣新聞</a>通貨は時々過度に浮かんでいるように見えますが、ほとんどの人は、新しい技術インフラストラクチャとしてブロックチェーンの可能性を信頼し、いつか、ラップトップ、iPhone、クラウドストレージが行ったように、ブロックチェーンが世界により大きな価値を創造すると確信しています。 

例えば、エンタープライズブロックチェーンのCasperLabsは、投票権、サプライチェーンの透明性、暗号アートの販売、予約、コンサートチケット、VIPメンバーコミュニティ、 ID 保護などの用途は、より良いプロセスを作成します。 したがって、適切なリスク選好を持ち、新興プロジェクトを支援したい投資家は、5年から10年で意味があると思われる特定のプロジェクトのトークンを購入することで、行動に参加したい場合があります.
 
<b><h2>5. ブロックチェーンは、大きな可能性を秘めています

ブロックチェーンは、暗号通貨の祖先であり、後期には様々な<a href=https://coinledge.io/>NFT作品</a>ートを育み、異なる市場により多くの活力をもたらしました。 

ブロックチェーンは、海運から小売、銀行管理、ヘルスケアまで、多くの産業でGame Changerとして知られており、ブロックチェーンは分散元帳を通じて不可能な新しい経済活動を実現することができます。 この可能性は、現状に甘んじる私たちにとって、より良い期待を抱いている私たちにとって、関連する資産を保有し続けるように説得するのに十分であると信じています。
SharpSVNを使ってリポジトリとリポジトリ内のファイルのリビジョンを取得する

# はじめに
本記事では、SharpSVNを使ってリポジトリとリポジトリ内のファイルのリビジョンを取得する際に困ったので、備忘録としてその方法をまとめます。

# SharpSVNとは
SubversionをC#から簡単に操作するためのライブラリです。
Subversionで管理するリポジトリやファイルの情報の取得などSubversionのクライアントとしての機能をいくつか提供しています。
詳細は[こちら](https://github.com/AmpScm/SharpSvn)のGitHubリポジトリを参照ください。

# SharpSVNを使ってリポジトリのリビジョンを取得する
リポジトリのリビジョンを取得する方法に関しては、[こちら](https://csharp.hotexamples.com/jp/examples/-/SvnLogArgs/-/php-svnlogargs-class-examples.html)の記事などでも紹介されていて検索しても引っかかることが多いです。
以下にコードを示しますが、SVNから情報をとってくるクライアントを作ったのちにGetLogメソッドでログを取得します。このログの1つ1つがリビジョンの情報を持っています。

```cs
/// <summary>
/// リポジトリのリビジョン情報を表示する
/// </summary>
public void ShowRepositoryRivisions()
{
    // クライアントの作成
    var client = GetSvnClient();
    
    // 認証情報の設定
    client.Authentication.Clear();
    client.Authentication.DefaultCredentials = new NetworkCredential(ユーザー名,パスワード);
    
    var repositoryUrl = リビジョンを取得したいリポジトリのURL;
    var repositoryUri = new Uri(repositoryUrl);

    // リビジョン取得用の引数を作成
    var svnLogArgs = new SvnLogArgs();
    // 取得し始めるリビジョン番号を指定
    // 以下の場合は、100番以下の番号を持つリビジョンのみが取得できる
    svnLogArgs.Start = 100;
    // 取得するリビジョンの数を指定
    // この場合は20個のリビジョンが取得できる
    svnLogArgs.Limit = 20;

    // リビジョンを取得
    Collection<SvnLogEventArgs> revisionList;
    client.GetLog(repositoryUri, svnLogArgs, out revisionList);

    // リビジョン内容を表示
    foreach (var revision in revisionList)
    {
        Console.WriteLine($"リビジョン番号：{revision.Revision}");
        Console.WriteLine($"コミット時のコメント：{revision.LogMessage}");
        Console.WriteLine($"コミットしたユーザー名：{revision.Author}");
        Console.WriteLine($"コミット日時：{revision.Time.ToString()}");
    }
}
```

# SharpSVNを使ってリポジトリ内のファイルのリビジョンを取得する
リポジトリ内のファイルを指定してリビジョンを取得する場合にもリポジトリの場合と同様にGetLogメソッドを使えばよいです。
以下にコードを示しますが、差分は利用するURLがリポジトリのURLからリポジトリ内のファイルのURLに変わることです。

```cs
/// <summary>
/// リポジトリ内のファイルのリビジョン情報を表示する
/// </summary>
public void ShowRepositoryFileRivisions()
{
    // クライアントの作成
    var client = GetSvnClient();
    
    // 認証情報の設定
    client.Authentication.Clear();
    client.Authentication.DefaultCredentials = new NetworkCredential(ユーザー名,パスワード);
    
    // ここでリポジトリ内のファイルのURLを使うことが差分
    var fileUrl = リビジョンを取得したいリポジトリ内のファイルのURL;
    var fileUri = new Uri(fileUrl);

    // リビジョン取得用の引数を作成
    var svnLogArgs = new SvnLogArgs();
    // 取得し始めるリビジョン番号を指定
    // 以下の場合は、100番以下の番号を持つリビジョンのみが取得できる
    svnLogArgs.Start = 100;
    // 取得するリビジョンの数を指定
    // この場合は20個のリビジョンが取得できる
    svnLogArgs.Limit = 20;

    // リビジョンを取得
    Collection<SvnLogEventArgs> revisionList;
    client.GetLog(fileUri, svnLogArgs, out revisionList);

    // リビジョン内容を表示
    foreach (var revision in revisionList)
    {
        Console.WriteLine($"リビジョン番号：{revision.Revision}");
        Console.WriteLine($"コミット時のコメント：{revision.LogMessage}");
        Console.WriteLine($"コミットしたユーザー名：{revision.Author}");
        Console.WriteLine($"コミット日時：{revision.Time.ToString()}");
    }
}
```

# さいごに
SharpSVNを使ってリポジトリとリポジトリ内のファイルのリビジョンを取得する方法をまとめました。
リポジトリであってもリポジトリ内のファイルであっても同じGetLogメソッドが利用できるようですね。
【Python】pythonでtweetしてみた

## 概要
pythonでtweetしてみた。

## 前提条件
Pythonが既にインストールされていること。

## API（tweepy）のインストール
コンソールを開いて下記のコマンドを実行する。

```
pip install tweepy
```

## APIキーとアクセスキー、トークンの取得
下記のURLを参考に認証に必要なキー情報を取得する。

http://kakedashi-xx.com:25214/index.php/2021/05/23/post-2475/#toc8

## Pythonでツイートを実行
Essentialだと下記のエラーが出たため<a href="https://qiita.com/penguinprogrammer/items/b220be0c203eaaad015a">tweepy + Twitter API V2でツイート</a>のプログラムを参考にしました。ありがとうございます。

```
53 - you currently have essential access which includes access to twitter api v2 endpoints only. if you need access to this endpoint, you’ll need to apply for elevated access via the developer portal. you can learn more here: https://developer.twitter.com/en/docs/twitter-api/getting-started/about-twitter-api#v2-access-leve
```

実際に実行したプログラムは下記になります。

```py
import tweepy

# Twitter Deverloper Portalで取得
#取得したAPI Key
ck = 'xxxxxxxxxxxx'
#取得したAPI Key Secret
cs = 'xxxxxxxxxxxx'
#取得したAccess Token
at = 'xxxxxxxxxxxx'
#取得したAccess Token Secret
ats = 'xxxxxxxxxxxx'

client = tweepy.Client(consumer_key=ck, consumer_secret=cs, access_token=at, access_token_secret=ats)

client.create_tweet(text="pythonからツイートテスト")

```

## 実行結果

実行した結果は以下のようになります。
![tweet.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2056482/dbc236ac-025c-e08b-45fd-f8d723223167.png)

Twitter関係のAPIはめんどくさい印象でしたが、意外と簡単にできました。
次は定期的にツイートできるようにしてみようかなと思います。
【Django】インストール方法

## インストール方法

インストール方法は、ディストリビューション固有のパッケージをインストールするのか、 最新の公式リリースをダウンロードするのか、あるいは最新の開発版を取得するのかに よって、若干異なります。
以下はpipにてインストールする方法になります。

1. pip で公式リリースをインストールする。
これは Django をインストールするのにお勧めの方法です。
2. pip をインストールします。最も簡単なのは、スタンドアロンの pip インストーラを使うことです。ディストリビューションに既に pip がインストールされている場合、それが古ければ 更新する必要があるかもしれません。古い場合、インストールが失敗します。
3. 仮想環境の作成と起動が完了したら、コマンドを入力します。

```
$ python -m pip install Django
Collecting Django
  Downloading Django-4.0.4-py3-none-any.whl (8.0 MB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 8.0/8.0 MB 995.6 kB/s eta 0:00:00
Collecting asgiref<4,>=3.4.1
  Downloading asgiref-3.5.0-py3-none-any.whl (22 kB)
Collecting sqlparse>=0.2.2
  Downloading sqlparse-0.4.2-py3-none-any.whl (42 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 42.3/42.3 KB 4.3 MB/s eta 0:00:00
Installing collected packages: sqlparse, asgiref, Django
Successfully installed Django-4.0.4 asgiref-3.5.0 sqlparse-0.4.2
```
binaryファイルからインストールする場合は以下にbinaryファイルがあるためダウンロードすること。
https://pypi.org/project/Django/#files

## 動作確認

以下コマンドで正常にインストールされていることを確認する
```
$ python
Python 3.10.2 (main, Mar 31 2022, 22:06:08) [Clang 13.1.6 (clang-1316.0.21.2)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import django
>>> print(django.get_version())
4.0.4
```

以上がDjangoのインストール方法になります。
[Python実践]Loggingに挑戦してみよう！《応用編》〜公式ドキュメントをもとに解説〜

# はじめに

今回はPythonの「**Logging**」の応用について解説していこうと思います！

「**Logging**」の基礎についてはこちらの記事にまとめてあります。

https://chaldene.net/logging

「**Logging**」はPythonの実務などでよく使われるので、Pythonエンジニアを目指している方は是非この記事でマスターしていってください！

この記事はPythonの公式ドキュメントを参考にしています。

Pythonに限らず、プログラミング言語の公式ドキュメントは非常に読みにくいので、この記事でわかりやすく解説していきます。

「**Loggingよく見かけるんだけど全くわからない...**」

「**Pythonエンジニアを目指して学習中**」

「**Pythonスキルのレベルアップをしたい！**」

このような人のお役に立てれば幸いです。

それでは早速本題に入っていきましょう！

:::note
「Logging」はPythonの基礎を理解していないと難しいので、Pythonの基礎を理解していない人は以下を参考に学習してください！
:::

https://chaldene.net/python-book

# ロギングとは？

まずは「Logging」がどういったものなのかなどの概要から見ていきましょう。

「Logging」とは以下のようなものです。

:::note
- プログラムが実行されているときに起こったイベントを追跡してくれる。
- 重要度を設定して、特定のイベントが発生したことをメッセージと共に知らせてくれる。
:::

より詳しくはこちらにまとめてあります。

https://chaldene.net/logging

# 細かくみてみる

ロギングは「**Logger**」クラスのインスタンスにメソッドに呼び出して実行されています。

https://docs.python.org/ja/3/howto/logging.html

「**ロガー**」は、どこでイベントのログが取られたかを明らかにしてくれます。

## 名前の確認

まずはロガーの名前を確認してきましょう。

```python
logger = logging.getLogger(__name__)
print(logger)
# <Logger __main__ (WARNING)>
```

`__main__`とWARNINIG が表示されていますね。

`__main__`は実行されているファイルのことで、`WARNINIG` はデフォルトの重要度レベルのことです。

`__name__`と指定することが推奨されています。

## 明示的に自分で指定

次に明示的に「**ロガー**」の名前を指定してみましょう。

```python
logger = logging.getLogger("かるでね")
print(logger)
# <Logger かるでね (WARNING)>
```

自分が指定した通り、**かるでね**と出力されていますね。

## 重要度レベル変更してみる

では次に重要度レベルを変更してみましょう。

```python
import logging

logging.basicConfig(level=logging.ERROR)

logger = logging.getLogger(__name__)
print(logger)
# <Logger __main__ (ERROR)>
```

３行目で`ERROR`に設定してみると、出力部分が`WARNINIG`から`ERROR`に変わってますね。

## 他のファイルで実行されたロガー名を確認

名前が`__main__`だとよくわからないので、別ファイルのロガー名を確認してみましょう。

まずは`test.py`に以下を記入してください。

```python
import logging

def log_info():
    logger = logging.getLogger(__name__)
    return logger
```

次に`main.py`に以下を記入してください。

```python
import logging
import test

logger = logging.getLogger(__name__)
print(logger)
print(test.log_info())

# <Logger __main__ (WARNING)>
# <Logger test (WARNING)>
```

`main.py`のロガーは`__main__`と表示されています。（ファイル名がmain.pyだからではなく、「**実行されているファイル**」という意味です。

`test.py`の方は`test`と表示されています。

これで`__name__`が実行されているファイル名を参照していることがわかります。

## root

`root`とはロガー階層の一番上に位置しているものです。

![ブログ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570269/f0c23ec5-8328-de0e-4b76-d5a74f5f252a.png)

こんな感じのイメージですね。

ちなみに普通にロギングで出力されたメッセージを見るとひっそり出力されているのが確認できます。


```python
import logging

logging.warning('Warningだよ！！！')
# WARNING:root:Warningだよ！！！
```

真ん中に`root`というのがしっかりありますね。

# 続き

これより先は以下の記事にまとめています。

https://chaldene.net/logging-senior

より詳しく**Logging**について学ぶことができるので、興味がある方はぜひ！
（もちろん無料です！）
ESP32でOV2640の初期化に失敗する

## 環境
Hardware:M5Stack PoE Camera
IDE:Vscode PlatformIO Arduino Framework
使用ライブラリ:[esp32_camera](https://github.com/espressif/esp32-camera "esp32_camera")

## 症状
esp32_cameraライブラリで初期化時に
`esp_camera_init(): Camera probe failed with error 0x20004`
と出て初期化できない。deinit、initを繰り返しても無駄。

## 試行錯誤からわかった　初期化の可否が変わること
- camera_config_tのledc_timerの番号
- 初期化処理の後にあるコードの内容によっても変わる
- CPU周波数によっても変わる
- CPU周波数が高いと失敗しやすい

初期化処理の後のコードの内容によっても初期化の可否が変わるというのが謎。
esp_cameraライブラリのissueではパーティションスキームを変えるのも有効と言われているが変化はなかった。

https://github.com/espressif/esp32-camera/issues/102
esp_cameraライブラリのissueから引用

>この問題は設定とは関係なく、むしろesp32-camモジュール自体の設計不良による非決定論的な問題です（mcuやカメラが十分な電力を得ていない）。上記の「修正」はすべて瞬間的な運に過ぎず、因果関係はありません（ただし、様々な設定の変更がモジュールの電力消費に影響するため、間接的には影響します。この問題は、2つの複合的な部分から構成されています。カメラの検出不良と、ブラウンアウトです。どちらも散発的なものです。確実な起動のための唯一の有効な回避策は、まず無線LANを無効にし（起動時に大きな電力を消費します）、少し待ってからカメラを初期化し、さらに少し待ってから無線LANを起動し、おそらく最初は電力レベルを低く設定し、初期化後にそれを大きくすることです。電源があまり低下しないことが確実な場合、またはその可能性を気にしない場合は、ブラウンアウトを無効にすることもできます（「真の」ブラウンアウトは、起動に失敗する頻度に比べて通常まれであるため）。更新：起動コードを変更し、検出失敗のたびにカメラを終了させ、成功するまでループで再度起動させるようにしました。しかし、これだけでは、gpioのisrハンドラも終了させないとうまくいきません。しかし、その場合でも、espは電源再投入まで認識に失敗し続けます。これは、単にdeinit/initを呼び出すだけでは、mcuやカメラの状態を完全にリセットするのに十分でないため、再度検出しようとすることを意味します。つまり、自分でボードを設計するか、deinit が本当に各 gpio ラインの状態を元に戻すのか、そしてどれが特に関連するのかについての洞察を誰かが提供し、これらを手動で切り替えられるようにしない限り、特効薬のような解決策はありません。そうすれば、カメラ検出を最初からやり直すことが可能になります。私自身は、これを理解するほど深く掘り下げていませんし、今は優先順位が低いのです。

確証は無いが、個体差が生じるところからアナログ的な要因が絡んでると推測する。一応オシロでOV2640の初期化時の電源ラインを見たがブラウンアウトが発生しそうなほど電圧降下は発生していなかった。
競馬予想AI 勉強メモ#1 pandas DataFrameの特定行の抽出方法

競馬予想AI作成中にpandasのDataFrameの特定行を抽出したくなった際のメモです。
（参照：https://www.yutaka-note.com/entry/pandas_access#DataFrame%E3%81%AE%E8%A1%8C%E5%88%97%E5%80%A4%E3%82%92%E6%8A%BD%E5%87%BA%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95）

特定の行を指定｜df.loc[インデックス名, : ] または df.loc[インデックス名]

以上。これだけ！！
herokuでlaravelのエラーログを確認する

こんばんは、kumaです！

herokuではデフォルトではwebサーバーのエラーのみしか吐いてくれないので、laravelのエラーログを確認できるように設定します。

## 設定方法
コンソールで以下のコマンドを入力する。

```
heroku config:set LOG_CHANNEL=errorlog
```

これだけで終了です！

今回は短いですが、これで終わりにします💦
GCSにあるCSV群をBigQueryへ取り込む

# はじめに

[こちらの記事](https://qiita.com/yo16/items/3d350a383db973e8d5b2)で、大きなCSVを日付ごとのファイルに分割しました。これをもとに、BigQueryのシャーディングテーブル（テーブル名にサフィックスで日付がついているもの）を作成する手順です。
※ ブラウザだけでできます。

# 初期状態
- GCS、BigQueryともに、同じプロジェクトの前提です。
## (1) GCS
```:バケットとファイル（全部で848ファイル）
owid-covid-data
├─ owid-covid-data_20200101.csv
├─ owid-covid-data_20200102.csv
├─ owid-covid-data_20200103.csv
├─ ・・・
└─ owid-covid-data_20220427.csv
```
## (2) BigQuery
```:プロジェクトとデータセット
sample-proj1
└─ test_dataset_1
```

# やりたいこと・最終形
```:【最終形】BigQueryのプロジェクトとデータセット
sample-proj1
└─ test_dataset_1
    ├─ owid-covid-data_20200101
    ├─ owid-covid-data_20200102
    ├─ owid-covid-data_20200103
    ├─ ・・・
    └─ owid-covid-data_20220427
```

# 手順
## (1) GCPのCloud Shellを起動
- GCPの上のバーの右のほうに、Cloud Shellを起動するアイコンがあるのでクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/1fb2f4f1-9c4c-087a-9ead-544a425d8f57.png)
- 画面の下に、1/3～1/4くらいのShellの画面が出てくる。

## (2) シェルスクリプトを作成
- 後で実行するシェルを作成。もうこれがほぼすべて。
```bash:import_csv.sh
#!/bin/bash

# owid-covid-data内のファイルをリストし、１つ１つでループ
for file_full_path in `gsutil ls gs://owid-covid-data`
do
	# ファイル名（ファイル名/より左を削除）
	file_name=${file_full_path##*/}
	# ベース名（ピリオドより右を削除）
	file_basename=${file_name%.*}
	
	# テーブル名（データセットとベース名を結合）
	table_name=test_dataset_1.${file_basename}
	
	# 念のためファイルの存在を確認
	if [ ${#file_full_path} -gt 0 ]; then
		# CSVからBigQueryへインポート
		# --autodetect: テーブルの列定義を、ファイルから自動検出
		# --source_format=CSV: 形式はCSV（省略可能）
		# テーブル名、元ファイル
		bq load --autodetect --source_format=CSV ${table_name} ${file_full_path}
		echo ${table_name}
	fi
done
```
- 下記のGCPコマンドを利用している。Cloud Shellで試してみるとよい。
  - `gsutil ls gs://owid-covid-data`で、バケット内のファイル一覧を取得できる
  - `bq load --autodetect --source_format=CSV test_dataset_1.owid-covid-data_20200101.csv owid-covid-data_20200101`でGCSのCSVからBigQueryにテーブルを１つ作成できる

## (3) シェルスクリプトを実行
```
sh import_csv.sh
```
- １回どーんと実行するだけ。
- ただし、内部的には`bq load`の１回１回の呼び出しごとに数秒かかるので、CSV数が多いと時間がかかる。

# おわりに
今回はうっかり848個のファイルを使ってしまったので時間は結構かかりましたが、放置しておけばよいので、それでも特に問題ないです。
Qiitaのエラー3種類。あきらめない。新人応援

今日、Qiitaでいろいろエラーが出た。そのうちの一つ。

# 404Not Found
お探しのページは一時的にアクセスができない状況にあるか、移動もしくは削除された可能性があります。 また、URL、ファイル名にタイプミスがないか再度ご確認ください。

# Qiitaはメンテナンスのためサービスを一時的に停止しています。
復旧するまで今しばらくお待ちください。
なお、Twitterで最新情報を配信しております。

# 502: Bad Gateway が何回連続して出るか。

https://qiita.com/kaizen_nagoya/items/a905790f273d910b6310

自分のページの先頭を出そうとして、２回に１回は出る。
どうしてQiitaが放置しているかは不明。


# 接続を諦めないことが大事。

手段としてオススメ。

1. 違う機材で接続。
パソコンでエラーがでたらスマフォでつないでみる。
スマフォでエラーがでたらパッドでつないでみる。

2. 違うブラウザで接続
chromeでだめならSafari
SafariがだめならFireFox

3. 再起動
パソコンでも、スマフォでも、電源の入れ直してみるのは有効。
どこかのキャッシュにエラーになる要因が溜まっている可能性がある。

4. 時間をおいてみる。
サーバ側のキャッシュがエラーの原因になったり、
サーバ側の処理がいっぱいでエラーになることは毎日ある。

すこし時間をおいて接続してみるのも手かも。

Qiitaのエラーに関する記事は、後でここに列記する予定。
ChromebookのLinux環境でImageMagickを使いたい

未実施：やること記録

```
sudo mkdir /usr/share/fonts/[font_name]
cd ~/temp
sudo mv [font_1].ttc [font_2].ttc /usr/share/fonts/[font_name]
sudo chmod 755 /usr/share/fonts/meiryo -R
```

fontチャッシュを更新と表示の確認

```
sudo fc-cache -fv
```

ImageMagickインストール

```
sudo apt update && sudo apt upgrade -y
sudo apt install imagemagick
```
Excel VBAを使ってMySQL(MariaDB)からデータを取得

# はじめに
Excel VBAを使用してMySQL(MariaDB)からデータ取って来るまでの記事です。
今回は以下のバージョンで動作確認しました。
調べてみると同様の記事が多くて恥ずかしいのですが、これは自分用に・・・備忘として投稿します。
<dl>
<dt>OS</dt>
<dd>Windows10</dd>
<dt>DB</dt>
<dd>MariaDB DB-10.4.14</dd>
<dt>Excel</dt>
<dd>Microsoft 365(64bit)</dd>
</dl>

# ODBCドライバーをインストール
「ODBC MySQL」などの文言で検索してください。
下記のサイトが見つかると思います。

https://dev.mysql.com/downloads/connector/odbc/

ダウンロードする際、64bitと32bitがありますが、Excelの版に合わせてください。
Excelが64bit版なら、64bitのドライバーを選びます。

# VCランタイムをインストール
ODBCをインストールしようとすると、VCランタイムが無いよ！とエラーが表示されることがあります。
「visual c++ runtime」などの文言で検索してください。
例えば、下記のサイトからダウンロードします。

https://www.microsoft.com/ja-jp/download/details.aspx?id=40784

Excelが64bit版ならX64、Excelが32bit版なら、X86を使用します。
上の例ではバージョンは2013ですが、なるべく新しいものを使った方が良いかと思います。


# MySQLでの準備
予めMySQLにhugaというユーザーを作成し、パスワードはhogeにしています。
テスト用のデータベースtestを作成し、sampleというテーブルを追加。データを用意しておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/362334/786a78a4-ae81-48c0-fa47-567663d5c53a.png)

ユーザーhuga君に、データベースtestへのアクセス権限を与えます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/362334/57e22f1d-8ec4-cf72-f0ae-2149b8c806d9.png)


# Excel VBA から MySQL へ接続
**ADO**を使用しています。接続の所で用いられる**接続文字列**は「ADO 接続文字列」で検索すると色々出てきます。


```vb:Module1
Function testMysql()
    
    Dim cn As Object ' ADOコネクション
    Dim rs As Object ' ADOレコードセット
    Dim r As Range
    Dim i As Long
    
    ' ADOコネクションを作成
    Set cn = CreateObject("ADODB.Connection")
    
    On Error GoTo errorTrap
    
    ' 接続
    cn.Open _
        "DRIVER={MySQL ODBC 8.0 Unicode Driver};" & _
        "SERVER=localhost;" & _
        "DATABASE=test;" & _
        "UID=huga;" & _
        "PWD=hoge;"
    
    ' SQLの実行
    Set rs = cn.Execute("SELECT * FROM sample")
    
    ' 出力開始セル
    Set r = Range("A1")
    
    Do Until rs.EOF ' レコード数だけループ
        For i = 0 To rs.fields.Count - 1 ' フィールド数だけループ
            r.Offset(0, i).value = rs.fields(i) ' セルへ出力
        Next
        Set r = r.Offset(1, 0)  ' 出力セルを一行下へ
        rs.MoveNext             ' 読取レコードも次の行へ
    Loop
 
    ' 解放
    rs.Close
    cn.Close
    Set rs = Nothing
    Set cn = Nothing

Exit Function
' エラー時の処理
errorTrap:
    MsgBox (Err.Description)
    Set rs = Nothing
    Set cn = Nothing
    End
End Function
```
## 処理結果
こんな感じで、サクッとデータを取得できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/362334/eddfcfc9-70bd-e387-c734-14ce9e4e1bba.png)
webpackとは

wecpackとはモジュールバンドラー。
複数のモジュールの依存関係を解決して一つにまとめる、いわゆるバンドリングするもの。

なぜモジュールをバンドリングするのか
ウェブブラウザとサーバー間ではHTTP/1.1という通信プロトコルで通信をしている。（最近はHTTP/2で通信するサーバーが増えている。）HTTP/1.1では一度に処理できるリクエストの数が限られているので、リクエストが増えるとパフォーマンスが落ちる。
なので、ひとつにまとめたほうがパフォーマンスを落とさなくてすむ。
開発することはなるべく機能をわけ、実行するときは機能をまとめる。これを解決してくれるのがモジュールバンドラ。

# 参考記事
https://zenn.dev/antez/articles/58307946cf4f3e
https://qiita.com/minato-naka/items/0db285f4a3ba5adb6498
【JavaScript】多次元配列を作成するシンプルな方法【ワンライナー】

## 概要
JavaScriptだと多次元配列を直接宣言できないらしい。
ググってみると、入れ子のfor文で作成するのがセオリーみたい。

配列作るだけなのに冗長だなぁと思って、シンプルにしてみた。

## セオリー
３行５列の配列をfor文で作る場合こんな感じ。
```javascript
var array = [];
for(var i=0; i<3; i++){
  array[i] = [];
  for(var j=0; j<5; j++){
    array[i][j] = '';
  }
}
```
`array[i][j]`に 0 を入れておけば、各要素が数値型になるのでそのまま計算可能。

分かりやすいけど、ただの変数宣言と続けて記述すると、ぼてっとして見える。

## シンプルに
セオリーでは要素の個数だけ縦横に宣言していく感じだけど、考え方を変えてみる。
```javascript
var array = [];
for(var i=0; i<3; i++) array.push(Array(5));
```
空の配列に、要素が５つの配列を３回プッシュしてやれば、３行５列の多次元配列になる。

見た目もスッキリ^^ （ちなみに各要素は`null`）

セオリーでも触れた数値型にしたければ、for文の中を`array.push(Array(5).fill(0))`にしてやれば、全要素が 0 になる。

## ショートハンド
可読性は落ちるけど、ワンライナーにしてみた。
```javascript
for(a=[]; a.length<3;) a.push(Array(5));
```
for文の初期値で配列を宣言。
繰り返しの中で配列の要素が増えていくので、要素数を繰り返し終了の条件にすれば、変化式も省略できちゃう。

### おしまい