OmniAICreator/Qiita-1.07M huggingface dataset:
Visual Studio 2019 IDEでASP.NETのViewの一部に赤線が出るのを解決する

# 障害

```html:hogeview.vbhtml
@Styles.Render("~/Content/CSS/Style")
```

上記でいうと、"Styles"の部分に赤線が表示され、マウスホバーすると「Stylesは宣言されていません。アクセスできない保護レベルにあります」というメッセージが表示されます。参照が解決されていないようです。

しかしビルドは通り、発行も行われ、実際にウェブ上で表示させてもエラーは出ません。

ネットでは「Viewフォルダ内のWeb.configにSystem.Web.Optimizationのnamespaceを追加せよ」とあり、確認しましたが、既に追加されています。

```xml:ViewフォルダのWeb.config（の一部）
  <system.web.webPages.razor>
    <host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
    <pages pageBaseType="System.Web.Mvc.WebViewPage">
      <namespaces>
        <add namespace="System.Web.Mvc" />
        <add namespace="System.Web.Mvc.Ajax" />
        <add namespace="System.Web.Mvc.Html" />
        <add namespace="System.Web.Optimization"/>
        <add namespace="System.Web.Routing" />
	  </namespaces>
    </pages>
  </system.web.webPages.razor>
```

# 解決策

ネットを漁ったところ、同じ点で困っている方がいらっしゃって、解決されていました。

https://social.msdn.microsoft.com/Forums/sqlserver/ja-JP/6d089d57-b7d5-4847-ba83-c6b2579ab1c5/aspnet?forum=aspnetja

おおもとはこちらのstackoverflowのページの情報です。

http://stackoverflow.com/questions/30311355/visual-studio-2015-not-syntax-highlighting-razor-nor-intellisense?lq=1

曰く、Visual Studioを閉じた状態で、以下のフォルダを削除します。

> %LocalAppData%\Microsoft\VisualStudio\<visual_studio_version_number>\ComponentModelCache

Visual Studioのバージョン番号は[こちらのページ](https://en.wikipedia.org/wiki/Microsoft_Visual_Studio#History)で確認できます。

私の場合、Visual Studio 2019ですが、"16.0_xxxxxxxxx" のようなフォルダ名になっていました（xxxの部分は実際には何かのidのようでした）。

その後Visual Studioを起動すると、もはや赤線は表示されておらず、マウスホバーすると定義を参照してくれました。

同じ症状でお困りの方は、騙されたと思ってやってみてください。
TypeORMでロールバックの実装

# 初めに
TypeORMを使用してDB操作を実装しているときに、「あっ、エラーが発生した時のロールバック処理も実装しないと」と思い、実装したプログラムを紹介します。

# 環境
* Windows10
* typeorm 0.2.34
* typescript 4.3.2
* node 14.17.0
* Azure Database for MySQL サーバー

# コード
## Entityファイル
```entity/CrawlerHistory.ts
import { Column, Entity, PrimaryGeneratedColumn } from "typeorm";

@Entity("crawler_history")
export class CrawlerHistory {
  @PrimaryGeneratedColumn()
  readonly id?: number

  @Column("varchar", { name: "status", length: 30 })
  status!: string

  @Column("text", { name: "message" })
  message!: string

  @Column("datetime", { name: "create_date" })
  createDate!: string
}

```

## メインファイル
1ファイルで紹介したかったため1ファイルにすべて詰め込んでありますが、
適宜管理しやすいようにファイルを分けたほうがいいと思います。

```index.ts
import { createConnection, EntityManager, getManager } from "typeorm";
import fs from 'fs'
import { CrawlerHistory } from "./entity/CrawlerHistory";

//IIFE 即時関数
(async function main() {
  //db接続
  const connection = await createConnection({
    type: "mysql",//※1
    host: "{your host}",
    port: 3306,
    username: "{your user}",
    password: "{your password}",
    database: "{your database}",
    synchronize: false,
    ssl: { ca: fs.readFileSync('./ssl/DigiBalRoot.crt.pem') },//※2
    logging: false,
    entities: ["entity/**/*.js"],//※3
    migrations: ["migration/**/*.js"],
    subscribers: ["subscriber/**/*.js"],
    cli: {
      entitiesDir: 'entity',//※3
      migrationsDir: 'migration',
      subscribersDir: 'subscriber',
    }
  }).catch(err => { throw err; })

  if (connection) {//接続の確立
    console.log('connection open')
    await getManager().transaction(async (transactionalEntityManager) => {//※4
      await createCrawler_history({
        status: 'INFO',
        message: '登録しました',
        createDate: new Date().toISOString()
      }, transactionalEntityManager).then(() => console.log('登録'))
    }).catch(async () => {//※7
      console.log('ロールバックの実行')
    })
  } else {
    console.log('接続が失敗しました。')
  }
  await connection.close()//※5
  console.log('connection close')
})()


const createCrawler_history = async (body: CrawlerHistory, transactionalEntityManager: EntityManager) => {
  //DB接続
  await transactionalEntityManager.save(CrawlerHistory, body)
  throw new Error　//※6
}

```

- `※1`
今回使用するDBがmysqlのため`mysql`とします。
波括弧{}で囲われた部分は使用するDBの情報に置き換えてください。

- `※2`
AzureDBの設定で接続のセキュリティ項目にて、SSL接続を強制にするを有効にしているとpemファイルが必要になります。
保存したpemファイルのパスに置き換えてください。
今回の例ではindex.ts直下にsslフォルダを作成しその中に保存しました。

- `※3`
entityのファイルを作成した場所のパスです。

- `※4`
トランザクション処理です。
今回は1つしか実行していないが、この内部に書かれた関数内で例外が発生すると、実行していた SQL がロールバックされる。

- `※5`
接続の切断メソッドです。

- `※6`
今回の例ではこの場所でErrorを出している。
正常に動かす場合はこの行をコメントアウトする。

- `※7`
DBに関するものしかロールバックされないため、前に別の処理を行っていた場合はここでその処理についてロールバックする必要がある。
例：私の場合はIBMCloudのDiscoveryに文書を登録し、
そのあとに実行ログを残していたため、登録した文書を削除する処理を記述しました。



# 終わりに
TypeOrmはまだまだできることが多いので調べつつ、またいろいろ記事にしていけたらと思います！
Xilinx ZCU102向けPYNQビルドと確認(v2.6対応)

[ZCU102](https://japan.xilinx.com/products/boards-and-kits/ek-u1-zcu102-g.html)用にPYNQ環境を構築しようと調べたところ、[とても参考になる記事](https://qiita.com/jin0g/items/42d53fd1eca42ec17c0f)がありました。
しかしファイル名等、現在では環境がかなり変わってきたので、`image_v2.6.2`をベースにビルド方法と動作確認を備忘録として残しておきます。
# 前提となる環境
- Ubuntu 18.04
- Vitis 2020.1
- Petalinux 2020.1

# 事前準備
次のファイルを~/に用意します。
- **ZCU104**用PYNQ Image (zcu104_v2.6.0.img) (from: http://www.pynq.io/board.html)
- ZCU102 BSP 2020.1 (xilinx-zcu102-v2020.1-final.bsp) (from: https://japan.xilinx.com/support/download.html) 

# ビルド実行
以下のスクリプトを実行します。
スクリプトの中の`./scripts/setup_host.sh`の時点でQEMU等をコンパイル・インストールするので、Ubuntu 18.04のroot権限が必要です。
CPUがRyzen 9 5950X搭載のUbuntu 18.04でビルドは約30分かかりました。
また`PYNQ`ディレクトリ全体で約33GB消費します。

```sh
# pynq
git clone https://github.com/Xilinx/PYNQ.git -b image_v2.6.2 --depth 1
cd PYNQ

# ZCU102 setting
cp -rf ./boards/ZCU104 ./boards/ZCU102
rm -rf ./boards/ZCU102/petalinux_bsp/
mv ./boards/ZCU102/ZCU104.spec ./boards/ZCU102/ZCU102.spec
sed -i -e "s/104/102/g" ./boards/ZCU102/ZCU102.spec

# copy files
cp ~/xilinx-zcu102-v2020.1-final.bsp ./boards/ZCU102/
mkdir ./sdbuild/prebuilt
cp ~/zcu104_v2.6.0.img ./sdbuild/prebuilt

# install qemu，crosstool-ng
cd ./sdbuild/
./scripts/setup_host.sh

# path
PATH=/opt/qemu/bin:/opt/crosstool-ng/bin:$PATH
source /<path/to>/Petalinux/2020.1/settings.sh
source /<path/to>/Vitis/2020.1/settings64.sh

# build
sudo echo
make BOARDS=ZCU102 PREBUILT=./prebuilt/zcu104_v2.6.0.img

```

# 動作確認
ビルドが完了すると、`PYNQ/sdbuild/output`に`ZCU102-2.6.0.img`という名でイメージファイル(約7GB)が生成されます。
これをSDカードに書き込みます。
自分はWindowsにコピーして、[rufus](https://rufus.ie/ja/)でSDカードに書き込みました。

SDカードをZCU102に挿入してブートさせると、DisplayPort出力からPYNQのデスクトップ環境が立ち上がります。
![Screenshot 2021-09-28 14-50-22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32925/0779d79d-1c71-3451-cf7d-ddd86c713247.png)
Chromiumブラウザーから`localhost`を入力すると、Jupyter Notebookに入ることができます。パスワードは`xilinx`です。
![Screenshot 2021-09-28 14-51-19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32925/9cb53f81-1379-62f3-29cf-e0ceaa55b52a.png)

# ザイリンクス デバイス向けの認定 Ubuntu
本題からは逸れますが、Xilinx用Ubuntuイメージがリリースされています。
https://japan.xilinx.com/products/design-tools/embedded-software/ubuntu.html

Ubuntuのバージョンは20.04のようです(PYNQは18.04)。ZCU102に対応しており、すぐに確認することができます。
![Screenshot 2021-09-28 14-58-50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32925/119306d8-c05d-3412-9ad8-58fb8e8fcd0f.png)
[Wikiページ](https://xilinx-wiki.atlassian.net/wiki/spaces/A/pages/2057043969/Snaps+-+xlnx-config+Snap+for+Certified+Ubuntu+on+Xilinx+Devices)を参照すると、Vitisプラットフォームに対応したユーティリティがあるようですね。
今後はPYNQがXilinx Ubuntuに取り込まれていくのでしょうか。ユーザーとしては気になるところです。
機械学習の初心者の僕が困りがちなこと解決法まとめ

最近機械学習を始めたのですが困ったことが多々あった（ある）のでその解決法などを随時書いていこうと思います。
また、こんなことに困ってこう解決した！や私の解決法よりももっと便利なイイ方法があるという方はぜひ教えていただけると幸いです。


**目次**
>1.read_csvのオプション
>2.NaN以外の欠損値の置き換え法
>3.データの中の項目の型変更
>4.実際にテストした際に困った点
>5.データの精度を向上させる

##1.read_csvのオプション
私は今signateで勉強をし始めたのですが、そのデータの形は.tsvでした。
いつも通りの下記のような方法で読み込みをすると

```python
sample = pd.read_csv('train.tsv')
```
![スクリーンショット 2021-09-28 18.43.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/764631/aa87ef7e-c9fa-cc5b-63fd-12536bb9aa36.png)
のような形になってしまい、収まりがつきません。
データを見るとわかるのですが、"\t"というもので区切られているのがわかるので、オプションの sep=""を使い、区切りを認識してあげると良いです。
今回は、以下の文をすることで正しい形にすることができました。

```python
sample = pd.read_csv('train.tsv',sep="\t")
```
![スクリーンショット 2021-09-28 18.51.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/764631/ffba688a-3ee9-ff4d-f59c-52ebe22ecf1f.png)



また、いろいろなオプションがあるので自分のデータにあっている方法を使うと良いと思います。

https://note.nkmk.me/python-pandas-read-csv-tsv/
などを参考にさせていただきました。

##2.NaN以外の欠損値の置き換え法

先程のデータと比べ合わせてみて欲しいのですが、なぜかhorsepowerの項目がfloatではなく、object型として認識されています。
![スクリーンショット 2021-09-28 18.57.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/764631/2444b727-ec77-9115-d7da-f28135ec1fe2.png)
これでは、describe()とかを使ってもうまく表示されません。そこで原因を探します。

データを見てみると、horsepowerの項目のデータに"?"という文字があります。これのおかげでおそらく変な型になっているのだと思います。
![スクリーンショット 2021-09-28 19.01.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/764631/bf99cc8e-be4b-587d-8fc1-5691445cbffc.png)
今回はこれを欠損値NaNに変更しようと思います。

```python
#データを確認して"?"をNaNに変換
sample = sample.replace("?", np.nan)
```

をしてあげると![スクリーンショット 2021-09-28 19.05.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/764631/9ffbf3a1-35f2-2218-f43c-921951cd7789.png)
となり、うまく欠損値を”？”に変更することができました。

##3.データの中の項目の型変更
上記で、うまくデータを欠損地に当てはめることができましたが、まだデータの型がobjectのままです。
なのでこれをうまいこと変更してあげなければなりません。
データの型を変更するには以下のようにしました。

```python
sample["項目名"] = sample["項目名"].astype(np.変更したい型)
```


![スクリーンショット 2021-09-28 19.08.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/764631/a1b3fcca-cdb8-cff1-75a9-72ca9cd675c9.png)

これでdescribeで概要等を確認することができました。

##4.実際にテストした際に困った点(2021/09.30追記)
テスト用データにも訓練データと同じような処理をしてあげるのですが、今回私は"?"データの行を除外するという処理をしていたため、テスト用のデータの出力の数が少なくなってしまいました。
これでは提出できないので、"?"のデータを平均値や中央値、（もしくは？データを同じように機械学習してその値を当てはめるとか・・？）で補う必要があります。
ですので今回は
![スクリーンショット 2021-09-30 14.53.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/764631/3818fa23-9198-f683-d091-394bebf602df.png)
のようにして補いました。
この方法だとどんな値でも適当に中央値が与えられてしまい、機械学習に悪い影響を与えてしまうと思っているので改善したいと考えています。

##5.データの精度の向上の試行(2021/09.30追記)

SIGNATEの1つ目の講座には主に2つのデータ精度の向上のための方法が載っていたのでその方法を試しています。
今回出場したコンペティションはこちらです。

https://signate.jp/competitions/121

1つ目はデータをダミー変数化するということです。
今回のデータセットで言うとcar nameというのがあり、その項目にある法則があるのでそれをダミー変数貸してあげます。
2つ目は対数化です。

```python
df['追加する項目']= np.log(df['対数化する項目'])
```
で対数化することができます。
なぜ精度が向上するのかはSIGNATEの講座内で語られているので受講したり調べてみたりしてください。
この方法で少しだけ精度を向上することができました。
![スクリーンショット 2021-09-30 15.05.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/764631/c26db3fa-c7c9-8d69-64c5-635074971c34.png)


現在ではこれだけですがこれからわからないことがあれば随時追加していこうと思います。
日本語カラムを自動的に英字カラムに変換するReactのWebアプリを作ってみた

BigQueryにcsvファイルなどのデータをロードする際に、カラム名のユニコード対応が未だにされていないことで、もしカラム名が日本語の場合はヘッダーを英数字に変換する必要が出てくる。
少量のカラムであれば、手で変換して行けば良いかもしれませんが、大量のカラムがある場合にはかなり手間がかかる作業になります:confounded:
このようなシーンで活躍しそうな、日本語カラムのcsvファイルを自動的に英字カラムに変換してデータをロードさせるツールを作ってみました。

https://github.com/yasudakn/column-name-auto-generator

### ツールの使用感
csvファイルを読み込ませると、text列に元のカラム名、そしてtranslated textに変換された英字を出します。

以下は、国土交通省の台風位置データを読み込ませた画面の例です。
見ての通り、一部で変換出来ない文字があることがわかります。この画面上で編集することが出来ます。

また、type列でインポート先のデータ型をここで決めることも出来るようにしています。最初は全てstring型に固定させてます。string型から適切な型を選ぶと良いです。
(まだ、bq load --autodetectのような、データ型の自動推定まではやれていません。)


![スクリーンショット 2021-09-28 1.50.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/636318/f2dc81aa-2a4e-5819-f07d-2c14a3990193.png)


数字から始まっている文字もBigQueryのカラム名に使えないため編集します。
この例ではtypeもデータに合わせて、integer, floatに変えてしまってます。

![スクリーンショット 2021-09-28 1.12.48_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/636318/75d29f67-138a-20b2-befb-5c2981846e4e.png)

最後に、Create Tableボタンを押すと、BigQueryにテーブルを作ってデータをインポートさせます。

以下はデータが入ったBigQueryのテーブル情報とプレビューです。

![スクリーンショット 2021-09-28 10.56.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/636318/cb9f1908-50a3-b320-35f3-67aa9df79a07.png)

画面で指定した通りのフィールド名とデータ型でスキーマが定義されています。
英字のみで分からなくならないように、元のカラム名はディスクリプションに入れています。

![スクリーンショット 2021-09-28 10.57.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/636318/64d54029-152d-b44a-eab2-4f66d9e1f1ff.png)

指定したデータ型ですべのデータがインポート出来ています。

---

今回のサンプルデータとして、以下を使用しています。

- [国土交通省 - 気象予報_天気予報・台風の資料](https://www.data.go.jp/data/dataset/mlit_20140919_0747) - 
[台風位置表のCSVデータ（2021年）](https://www.data.jma.go.jp/yoho/typhoon/position_table/table2021.csv)


:::note info
ファイルのエンコードにutf-8対応させていません。
国土交通省の元のファイルはsjisだったため、文字化けしてしまいます。
nkfなどを使って、utf-8に変換する必要があります。
:::

### 何を使って実装しているか

次回の投稿で、内部の実装を簡単に説明したいと思ってます。
https://qiita.com/yasudakn/items/864320b55cbcd1cf7558
Solana testnet validator を運用するメモ

運用して問題ないことを確認するのに 大体 1~2 ヶ月くらいかかる感じです.

## PC 環境

testnet で 最低 threadripper 8 core + 3 GHz + 64 GB で動作はします.

https://qiita.com/syoyo/items/7f2ab6167c0d4311fcba

筆者は Ryzen 3950x や threadripper 1950x など保有していますが, メモリ 256 GB 環境でやりたかったので x299 + 10940x にしてみました. solana validator 運用あきらめることになったら Filecoin miner として流用するためです.
(x399 は 256 GB 対応マザーがあまり中古で出回っていない)

ledger 用 SSD は chia マイニングの DC class NVMe SSD を流用しました.
通常の SATA SSD でも(速度的に)問題ないとは思います.

CPU 性能は今後 TPS(transaction per second)増えるに連れて増やしていかないとかもです. GPU があれば GPU を使うのも手です. 処理ノードはクラスタ化して負荷分散させるのもできます(ただしおうちで validator 建てる場合, イントラネット早くないとだめ. おうち InfiniBand 推奨)

## ネット環境

現時点(2021/09)では 100 Mb/s マンション共有回線(アップロード速度が重要)でもなんとかなります.
(TPS(transaction per second) 2,500 くらい)

`solana catchup` してきちんとキャッチアップできるか確認しましょう.

### VPS

VPS などを挟む場合は, VPS サービスが帯域制限などしていないか確認しましょう.

とりあえず Indigo VPS は validator 起動すると速攻でアクセス制限がかかりました(ping などの通信が外部に出ていかない)

筆者は nginx で VPS で UDP proxy 建てましたが, logrotate などしていなかったため, worker_connection 足りない関連のエラーでエラーログがべらぼーに出て数十分で VPS のディスク領域食いつぶしてしまうという問題に遭遇しました(とりあえずエラーログ出さないように suppress して解決)


## 稼働実績

validators.app や solanabeach で確認できます.

https://www.validators.app/?locale=en&network=testnet

緑の丸が多いと振る舞いのよい validator と判定されます.
特に最初の３つが緑になるようにしましょう.
(ネット回線を強くする)


https://solanabeach.io/validators?cluster=testnet


## leader

leader node にならないと報酬などもらえません.
leader になれる確率はステーク量に比例します.
ネットワーク速度(トランザクション処理速度)も影響あるようです.

discord で delegation program に申し込むと 5,000 SOL くらいステークしてくれるようですが, **discord は選ばれしユーザーしかログインできません**.

一般の庶民や主ふの場合, testnet であればとりあえず airdrop のスクリプトで頑張れば一日 2000 SOL くらい手に入ります.
(1 回の airdrop 上限は 1 SOL, また頻繁に行うと rate limit にひっかかる)
 

## warm up, cool down

ステークを増やしても, すぐには反映されません.
warm up といって数 epoch こなしてから反映されます.
(いきなり多量のステークを持って悪意ある操作をする validator を排除するため)

https://docs.solana.com/running-validator/validator-stake#validator-stake-warm-up

ステーク量増やしたら(or 減らしたら), 反映されるまで気長に(1 週間くらい)待ちましょう.

## 障害

testnet 自体がダウン(負荷テスト)というのがありました.
discord では通知されていたようなので, 選ばれし testnet validator ユーザーは知ることができましたが, public な通知は無いようでした.

public に障害情報など知らせてくれるチャネルがほしいですね.

## mainnet 運用を目指して

testnet 運用して問題なければ次は mainnet 運用狙いたいですね.
mainnet になるとデータセンターで運用や帯域保証回線の利用も考えないとでしょう.
ご家庭で運用する場合は戸建てで 1 Gbps ~ 10 Gbps は必須でしょう.

mainnet 運用では delegation program でステークしてもらえるには最低 100 SOL(100 日運用できる)の搬出が必要です. 2021/09/28 時点で 160 万円くらいです!
【Salesforce】Ant移行ツールのメタデータリリース検証手順

SalesforceのAnt移行ツールでメタデータをリリース検証する手順を記載します。

## Salesforceの接続情報を入力する
build.propertiesの各パラメータに以下の接続情報を入力する。

|パラメータ|値|
|:-:|:-:|
|sf.username|Salesforceログイン用のユーザ名|
|sf.password|Salesforceログイン用のパスワード|
|sf.serverurl|SalesforceサーバのURL|

``` build.properties
# build.properties
#

# Specify the login credentials for the desired Salesforce organization
sf.username = <Insert your Salesforce username here>
sf.password = <Insert your Salesforce password here>
#sf.sessionId = <Insert your Salesforce session id here.  Use this or username/password above.  Cannot use both>
#sf.pkgName = <Insert comma separated package names to be retrieved>
#sf.zipFile = <Insert path of the zipfile to be retrieved>
#sf.metadataType = <Insert metadata type name for which listMetadata or bulkRetrieve operations are to be performed>

# Use 'https://login.salesforce.com' for production or developer edition (the default if not specified).
# Use 'https://test.salesforce.com for sandbox.
sf.serverurl = https://login.salesforce.com

sf.maxPoll = 20
# If your network requires an HTTP proxy, see http://ant.apache.org/manual/proxy.html for configuration.
#
```

## メタデータをリリース検証する
- codepkgフォルダのpackage.xmlにリリース対象のメタデータを入力する

``` package.xml
<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
    <types>
        <members>SampleDeployClass</members>
        <members>SampleFailingTestClass</members>
        <name>ApexClass</name>
    </types>
    <types>
        <members>SampleAccountTrigger</members>
        <name>ApexTrigger</name>
    </types>
    <version>51.0</version>
</Package>
```

- codepkgフォルダにリリース対象のメタデータを格納する
- ターミナルで以下のAntコマンドを実行してメタデータをリリース検証する

``` テストコードを実行する場合.
ant deployCodeRunLocalTests
```

``` テストコードを実行しない場合.
ant deployCodeCheckOnly
```

- Salesforceのリリース状況画面でメタデータのリリース検証状況を確認する

## 参考
■Salesforce 組織への変更のリリース
https://developer.salesforce.com/docs/atlas.ja-jp.daas.meta/daas/forcemigrationtool_deploy.htm
【Salesforce】Ant移行ツールのメタデータ取得手順

SalesforceのAnt移行ツールでメタデータを取得する手順を記載します。

## Salesforceの接続情報を入力する
build.propertiesの各パラメータに以下の接続情報を入力する。

|パラメータ|値|
|:-:|:-:|
|sf.username|Salesforceログイン用のユーザ名|
|sf.password|Salesforceログイン用のパスワード|
|sf.serverurl|SalesforceサーバのURL|

``` build.properties
# build.properties
#

# Specify the login credentials for the desired Salesforce organization
sf.username = <Insert your Salesforce username here>
sf.password = <Insert your Salesforce password here>
#sf.sessionId = <Insert your Salesforce session id here.  Use this or username/password above.  Cannot use both>
#sf.pkgName = <Insert comma separated package names to be retrieved>
#sf.zipFile = <Insert path of the zipfile to be retrieved>
#sf.metadataType = <Insert metadata type name for which listMetadata or bulkRetrieve operations are to be performed>

# Use 'https://login.salesforce.com' for production or developer edition (the default if not specified).
# Use 'https://test.salesforce.com for sandbox.
sf.serverurl = https://login.salesforce.com

sf.maxPoll = 20
# If your network requires an HTTP proxy, see http://ant.apache.org/manual/proxy.html for configuration.
#
```

## メタデータを取得する
- unpackagedフォルダのpackage.xmlに取得対象のメタデータを入力する

``` package.xml
<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
    <types>
        <members>*</members>
        <name>ApexClass</name>
    </types>
    <types>
        <members>*</members>
        <name>ApexTrigger</name>
    </types>
    <version>51.0</version>
</Package>
```

- ターミナルで以下のAntコマンドを実行してメタデータを取得する

```
ant retrieveUnpackaged
```

- retrieveUnpackagedフォルダ内にメタデータの取得結果が格納される

## 参考
■Salesforce の接続情報の入力
https://developer.salesforce.com/docs/atlas.ja-jp.daas.meta/daas/forcemigrationtool_connect.htm

■Salesforce 組織からのメタデータの取得
https://developer.salesforce.com/docs/atlas.ja-jp.daas.meta/daas/forcemigrationtool_retrieve.htm
【Salesforce】Ant移行ツールのインストール手順

SalesforceのAnt移行ツールを使用するには、JavaおよびAntのインストールが必要です。

## Java JDKをインストールする
ターミナルで以下のコマンドを実行する。
Java JDKのバージョンが確認できない場合は、Java JDKをインストールする。

```
java -version
```

## Antをダウンロードする
以下のAntダウンロード用URLよりAntをダウンロードする。

■Antダウンロード用URL
http://ant.apache.org/bindownload.cgi

## Antの環境変数を設定する
Antの「bin」ディレクトリを環境変数に追加する。
ターミナルで以下のコマンドを実行して環境変数が設定できたことを確認する。

```
ant -version
```

## Ant移行ツールをダウンロードする
以下のURLよりAnt移行ツールをダウンロードする。

■Ant 移行ツールのインストール
https://developer.salesforce.com/docs/atlas.ja-jp.daas.meta/daas/forcemigrationtool_install.htm
laravelでPostgreSQLのbyteaに画像を格納したときのメモ

<<環境>>
・PHP 7.4
・laravel8
・PostgreSQL12

PostgreSQLのbytea型に画像データを保存する必要が出て、
クエリービルダでうまく行かずにPDOを使用して実装した際の処理内容です。
テーブルには
・ID
・バイナリデータ(img_bin)
・MimeType(mimetype)
・ファイル名
のカラムを持つ前提で、データの挿入を行います。

<pre>
$id = レコードのID
$file = $request->file('file');							// リクエストのファイルを取得
$org_logo_filename = $file->getClientOriginalName();	// アップされたオリジナルのロゴファイル名取得(デバッグ等で使用)
$mimetype = $file->getClientMimeType();					// 画像を表示する際のmimetypeとして使用
$tmp_path = $file->getRealPath();						// 実画像のパスを取得
$fp = fopen($tmp_path, 'rb');							// 画像ファイルのファイルポインタ取得

// PDOを使ってデータの挿入
$db = DB::connection('pgsql')->getPdo();	// PDOオブジェクト取得
$db->setAttribute($db::ATTR_ERRMODE, $db::ERRMODE_EXCEPTION);
$stmt = $db->prepare("INSERT INTO simple_location_prop VALUES (?,?,?,?)");
$stmt->bindParam(1, $id);
$stmt->bindParam(2, $fp, $db::PARAM_LOB);
$stmt->bindParam(3, $mimetype);
$stmt->bindParam(4, $org_logo_filename);
$stmt->execute();
$arr = $stmt->errorInfo();	// エラー情報の取得
</pre>
保存したデータを取り出す際は、
<pre>
$db = DB::connection('pgsql')->getPdo();
$stmt = $db->prepare("SELECT mimetype, img_bin FROM テーブル名 WHERE id=?");
$stmt->execute(array($id));
$stmt->bindColumn(1, $mimetype, $db::PARAM_STR, 256);
$stmt->bindColumn(2, $lob, $db::PARAM_LOB);
$stmt->fetch($db::FETCH_BOUND);
・
・
・
header('Content-Type: ' . $mimetype);
fpassthru($lob);
</pre>

今回はこれで実装しましたが、PDOを使わなくても実装できないかこれから試行。

参考
https://symfoware.blog.fc2.com/blog-entry-1267.html
AWS初学者がちょっとした分析基盤作ってみたのでメモ

# はじめに
AWSをほとんど使ったことがなかった私がAWS上でちょっとしたものを作る際に、
`考えていたこと`や`調べたサイト`などをメモ書きとして残します。⚠︎自分用のため読みづらかったらすみません。。

# 作りたいもの
定期的に特定のアプリのAppStoreレビューをスクレイピング => 整形 => データ格納 => 集計 => 可視化をAWS上でできるように構築したい

# 作る前注意点
`AWS 高額請求`や`GCP 高額請求`で検索するとやらかした話が思った以上に出てくる。。

- [10日間 で AWS Lambda 関数を 28億回 実行した話](https://blog.mmmcorp.co.jp/blog/2019/12/25/lambda-cloud-bankruptcy/)
- [BigQueryで150万円溶かした人の顔](https://qiita.com/itkr/items/745d54c781badc148bb9)
- [AWS 高額請求 |クラウド利用の注意点！高額請求事例と対策方法](https://www.3sss.co.jp/tis/media/aws-high-billing/)

そのため下記は必ず
- `AWS 高額請求 対策`などで検索して認証や予算、請求アラートなどの設定
- 各ツールの`料金設定`を確認
- EC2などのインスタンスはすぐ`削除`(AWSを学ぶ上では立ち上げ続ける必要はないはず)
- 極力`サーバーレス`を意識(安価になることが多い)


# 学習手順
### 1. どこから学べば良いか分からん。とりあえずUdemyで学んでみる
- [Udemy これだけでOK！ AWS 認定ソリューションアーキテクト – アソシエイト試験突破講座](https://www.udemy.com/course/aws-associate/)
- [~~Udemy AWS Certified Data Analytics Specialty 2021 - Hands On!~~](https://www.udemy.com/course/aws-data-analytics/) => 英語動画かつ基礎知識が無さすぎて無理でした。。

`AWS初期設定`と`分析基盤`に関係ありそうな動画だけ視聴しながらハンズオンし`AWSに慣れる`

ただ`どんなツールが必要か？どのように連携させるか？`がまだ掴めない-> 似たようなものを作ってる記事を見つけて真似することから始めた方が良いかも。

### 2. 同期の方が分析基盤構築のアウトプットをQiita記事に
- [Youtube APIデータをBigQueryへロードする作業を自動化する](https://qiita.com/matsu0130/items/4849ebb3681e827274d3)

今回APIは使わないが作りたいものは似ているかも！AWSではどのように実現できるのか？

### 3. GCPとAWSの対応が把握する
- [GCP と AWS サービス対応表・比較表](https://cloud-ace.jp/column/detail124/)

~~AWS Batch~~ (`labmda 定期実行`と検索したら`Event Bridge`が良いと判明), SNS or SQS, Lambda, S3, Athena or Bigquery, QuickSightを使えば実現できるのでは？

それぞれのツール概要を[AWSサービス別資料](https://aws.amazon.com/jp/aws-jp-introduction/aws-jp-webinar-service-cut/#ai-wn)で把握する。


### 4. それぞれのモジュールを少しずつ繋げていく

`AWS Lambda スクレイピング`, `Lambda 外部ライブラリ使用方法`, `Lambda S3保存`, `Lambda SNS 連携`, `Lambda S3トリガー`, `Athena QuickSight 連携`などで検索しコードを改修&繋げていく
- [AWS LambdaでPython外部ライブラリのLayerを作る前に](https://qiita.com/polarbear08/items/202752d5ffcb65595bd9)
- [AWS Lambdaを使ったAmazon SNSへのメッセージ送受信](https://business.ntt-east.co.jp/content/cloudsolution/column-try-29.html)
- [QuickSightとAthenaを活用！データ分析入門](https://techblog.nhn-techorus.com/archives/6202)


# 実際に作ったもの
![AWS-ARC.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225073/1aa85dbd-8920-7837-fd81-72f6088c4ac9.png)

詳細は後日追記予定
[UE4] BoxとSphereの重なり判定

#【概要】
通常、UE4でBoxとSphereの重なりを判定したい場合、BoxComponentとSphereComponentのCollisionを作成しOverlapにより判定を行う。
しかし、諸々の都合上Component無しで重なりを判定したい状況があった為、判定を独自に実装してみた。
主に自分で忘れない為の備忘録用。

#【解説】
基本的な考え方は、以下のサイト様を参考にさせて頂いた。

https://developer.mozilla.org/ja/docs/Games/Techniques/3D_collision_detection#sphere_vs._aabb

実際の手順に沿って解説していく。
###1.相対座標に変換
上記サイトの方法では、Sphereの座標をBox内にクランプすることで、Sphereから最も近いBoxの範囲内の座標を求めている。
しかし、Boxが斜めになっていた場合そのままクランプするのは難しい為、最初にSphereの座標をBoxから見た相対座標に変換する。
計算式は以下のようになる。(W = ワールド原点、B = Boxの座標、S = Sphereの座標)

```math
^{B}\boldsymbol{T}_{S} = (^{W}\boldsymbol{T}_{B})^{-1} \, \times \, ^{W}\boldsymbol{T}_{S}
```
Transformの変換については以下で解説しています。

https://qiita.com/ykobayashi0/items/18fe76a33dc7435ae029

###2.Sphereから最も近いBoxの範囲内の座標を求める
1で得たBoxから見たSphereの相対座標を、Box内にクランプする。
`FVector::ClampVector`という便利そうな関数がエンジンにあったので、今回はこれを使ってみた。

###3.求めた座標をワールド座標系に変換
2でSphereから最も近いBoxの範囲内の座標を求められたが、これはBoxから見た相対座標になっているので、ワールド座標系に再変換する。
計算式は以下のようになる。(P = Sphereから最も近いBoxの範囲内の座標)

```math
^{W}\boldsymbol{T}_{P}= \, ^{W}\boldsymbol{T}_{B} \, \times \, ^{B}\boldsymbol{T}_{P}
```

###4.Sphereと重なっているか判定
3までの手順で、Sphereから最も近いBoxの範囲内のワールド座標を求めることが出来た。
あとはこの座標からSphereの座標までの距離が、Sphereの半径以下だった場合、BoxとSphereが重なっていると判定出来る。
この距離の計算をする場合、実際の距離で計算すると平方根の計算が走る為、二乗された状態で計算した方が計算コストが安く済む。


#【結果】
以上を踏まえ出来上がったのがこちら。
Transformの計算は使わないと忘れていきそうなので、積極的に使っていきたい。

```
bool MyLibrary::IsSphereInBox(const FVector& SphereLocation, float SphereRadius, const FVector& BoxLocation, const FRotator& BoxRotation, const FVector& BoxExtent)
{
	const FVector SphereLocationInBoxSpace = (FTransform(BoxRotation, SphereLocation) * FTransform(BoxRotation,BoxLocation).Inverse()).GetLocation();
	const FVector ClosestPointToBoxInBoxSpace = ClampVector(SphereLocationInBoxSpace, -BoxExtent, BoxExtent);
	const FVector ClosestPointToBoxInWorldSpace = (FTransform(BoxRotation, ClosestPointToBoxInBoxSpace) * FTransform(BoxRotation,BoxLocation)).GetLocation();
	return FVector::DistSquared(SphereLocation, ClosestPointToBoxInWorldSpace) <= FMath::Square(SphereRadius);
}
```
【Excel】仕事が捗るショートカット集

#はじめに
今回は「仕事が捗るショートカット集」をテーマに、Excelのショートカットをいくつか紹介しようと思います。
資料作成などを通して私が便利だなと感じたものを、私の独断と偏見でいくつか紹介します。
使用環境はWindows10になります。

※書式関連のショートカットキーをアップデート　2021/11/1

#対象読者
・Excel初心者
・Excelで資料作成をする人

#ショートカット集
###基本ショートカット10選
おそらく誰もが知っているであろうショートカットです。

|No.  |コマンド  |操作キー  |
|---|---|---|
|1  |コピー  |Ctrl + C  |
|2  |切り取り  |Ctrl + X  |
|3  |貼り付け  |Ctrl + V  |
|4  |上書き保存  |Ctrl + S  |
|5  |全選択  |Ctrl + A  |
|6  |元に戻す  |Ctrl + Z  |
|7  |直前の操作を繰り返す  |Ctrl + Y  |
|8  |検索  |Ctrl + F  |
|9  |印刷  |Ctrl + P  |
|10 |セルの書式設定  |Ctrl + 1  |

###応用ショートカット10選
ここからは知らなかったというショートカットもあるのではないでしょうか。

|No.  |コマンド  |操作キー  |
|---|---|---|
|1  |置換  |Ctrl + H  |
|2  |セルを個別に選択  |Ctrl + セルをクリック  |
|3  |フィルターをかける  |Shift + Ctrl + L  |
|4  |シートの再計算  |Shift + F9  |
|5  |入力された部分まで全選択  |Shift + Ctrl + 矢印  |
|6  |SUM関数  |Shift + Alt + =  |
|7 |数式の表示  |Shift + Ctrl + `  |
|8  |数式と値のクリア  |Alt + H → E → C  |
|9  |データの一番最後まで移動  |Ctrl + 矢印  |
|10  |選択中のセルを編集状態にする  |F2  |


上記からいくつか私が特に知って捗るなと感じたものを詳しく紹介します。

#####1.置換 : Ctrl + H
こちらは選択した値を任意の値に一括で置き換えることができるショートカットです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2017201/1ce0b6c3-6579-b0a0-2b46-ad4f7e9bb14c.png)
Ctrl + H　で「りんご」を「もも」に置き換える。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2017201/9c0cb44c-835e-b829-2298-eb44075c5a3a.png)
「りんご」の文字列を「もも」に置き換えることに成功しました。

#####3. フィルターをかける : Shift + Ctrl + L
こちらは選択したセルにフィルターをかけることができます。先ほどの表にこのショートカットでフィルターをかけるとこのようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2017201/3818f849-4e1b-fc10-9a37-941db2f71e59.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2017201/c238e196-0fe9-924c-d7b2-7293b2515020.png)
このようにたった一瞬でフィルターをかけることができました。

#書式関連
| No. | コマンド | 操作キー |
|:-:|:-:|:-:|
| 1 | 行幅の最適化 | Alt + H + O + A |
| 2 | 列幅の最適化 | Alt + H + O + I |
| 3 | 行の高さの指定 | Alt + H + O + H |
| 4 | 列の高さの指定 | Alt＋H＋O＋W |
| 5 | セル内文字を折り返して表示する | Alt + H + W |
| 6 | セルを結合して中央揃え | Alt + H + M + C |
| 7 | セル結合の解除 | Alt + H + M + U |
| 8 | 外枠を引く（罫線）  | Alt + H + B + S |
| 9 | 罫線なしにする | Alt + H + B + N |

#まとめ
今回はExcelの便利なショートカット集を記事にしました。ショートカットは使えるようになるとものすごく作業効率を上げてくれるものです。実際にExcelを触りながら使ってみることで定着が早くなると思います。見るだけだとすぐに忘れてしまうので、どんどん使いながら覚えていくと良いということです（自戒もこめて）。
次は便利な関数などまとめていけたらと思います。
Neo4j 常用Cypher

```
// 検索
MATCH p = (a:hostA) -[ABLink:link]-(b:hostB)
WHERE a.host = '値'
RETURN a,ABLink,b

// 削除node
MATCH (p:Person)
WHERE p.name = 'name'
DELETE n

//削除node Relation
MATCH p = (a:hostA) -[ABLink:link]-(b:hostB)
WHERE a.host = '値'
DETACH DELETE p
```
[iOS15にて]NavigationBarのBackGroundColor,TitleTextが見えなくなる

#iOS15にしましたらNavigationBarの色が見えなくなりました。

iOS15で、なるようです...

本当は上に赤いバーが白文字であるのですが消えてますね...ボタンも見えません。
新しい機能をつけてアップデートしたばかりなのに...:joy:


![Simulator Screen Shot - iPhone 13 mini - 2021-09-28 at 16.57.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1248272/f8856582-1956-cc6d-eb4e-ed0bd7292ab2.png)





```swift:UIViewController
        if #available(iOS 15.0, *) {
            let appearance = UINavigationBarAppearance()
            appearance.configureWithOpaqueBackground()
            appearance.backgroundColor = UIColor.red
            //これ付けないと文字がblackになりました。
            appearance.titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.white]
            navigationController?.navigationBar.standardAppearance = appearance
            navigationController?.navigationBar.scrollEdgeAppearance = appearance
            
        }
```

![Simulator Screen Shot - iPhone 13 mini - 2021-09-28 at 17.00.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1248272/8c8a1613-d8c7-9a78-25ea-238ab09bb096.png)

出ました:cracker::cracker::cracker::cracker::cracker:


#参考サイト
https://zenn.dev/ariiyu/scraps/0e309cc095cd3f

https://stackoverflow.com/questions/69111478/ios-15-navigation-bar-transparent
【PHP】PHPのarray_mapのコールバック関数 ※多次元配列対応

```PHP
<?php
$people = [
    ['name' => '太郎',  'age' => 33],
    ['name' => '洋子',  'age' => 37],
    ['name' => '美玖',  'age' => 21],
    ['name' => '信也',  'age' => 15],
    ['name' => '裕次郎','age' => 45],
    ['name' => '魁',    'age' => 8],
    ['name' => '達郎',  'age' => 55],
    ['name' => '真治',  'age' => 29]
];
```
### 全て2倍にする処理

無名関数(クロージャ)
```PHP
$value = array_map(function($num){
    return $num['age'] * 2;
}, $people);

var_dump($value);
```
アロー関数
```PHP
$value = array_map(fn ($var) => $var['age'] * 2, $people);
var_dump($value);
```
コールバック関数
```PHP
function double($nun){
    return $nun['age'] * 2;
}

$value = array_map('double', $people);
var_dump($value);
```
# 結果
```
array(8) {
  [0]=>
  int(66)
  [1]=>
  int(74)
  [2]=>
  int(42)
  [3]=>
  int(30)
  [4]=>
  int(90)
  [5]=>
  int(16)
  [6]=>
  int(110)
  [7]=>
  int(58)
}

```
AI platform Trainingでカスタムコンテナを使った学習を行い、`The replica master 0 exited with a non-zero status of 127. To find out more about why your job exited please check the logs: https://...`と言われる時

## 結論
DockerfileでENTRYPOINTではなくCMDを使っていたことが原因だった。

```python
# NG
CMD [ "python3", "./main.py" ]

# OK
ENTRYPOINT [ "python3", "./main.py" ]

```

[公式ドキュメント](https://cloud.google.com/ai-platform/training/docs/custom-containers-training#using_gpus_with_custom_containers)ではENTRYPOINTを使うように指示されているのに、勝手に変えたのが良くなかった。
ローカル環境ではCMDでも動いてしまうので注意。

CMDの場合、CMDで指定した全てのコマンドが`docker run`時に渡されたコマンドで置き換えられるが、ENTRYPOINTの場合は`docker run`時に渡された引数をオプションに付けるだけとなる。
CMDで指定してしまうと、`gcloud ai-platform jobs submit training`時に渡したオプションでpythonの実行コマンド自体が置き換えられてしまい、エラーとなったと思われる。
indexOfをforするのはよくない

WebGL用に自前の関数で4Mb程度のobj読み込みをした
ポリゴン命令の頂点の重複除去をしたあと
index bufferの生成にindexOfを
全ポリゴン命令約21万に対して回していたら43秒掛かった
なんだこれは
# indexOf
どちらも検索開始位置を第二引数に指定できる
そこから配列の中を一つづつ検索していく
これは目的の要素を配列の最後に置いて二つを走らせることでわかる

一つだけのインデックスを調べたいのならこれでも十分だが
全要素に対して検索をすると膨大な時間がかかる

並べ替えや重複除去の操作をした後に
全要素の位置を配列に記録する等の用途であれば
先に辞書を作った方が良いことは明らか

#Map
new Map()はObject.fromEntries()のように引数に[[key,value]...]を渡すことでMapを作ることができる
今回はkeyに値を持ってvalueにインデックスを持たせたいがこれは.map()で簡単に作れる

```js
new Map(array.map((x,i)=>[x,i]));
```
このMapにインデックスが欲しい値を渡すと値が最後に登場するインデックスを取得できる
最初のインデックスが欲しければ

```js
new Map(array.reverse().map((x,i)=>[x,i]));
```

※追記(2022/1/15)
書いていて多少不安は残るがmapの中の関数はArrayコンストラクタでも動く
Entriesは一番目と二番目の要素のみ保証されていれば良いらしい
つまり

```js
new Map(array.map(Array));
```
短いね
#速い
重複のある配列Aから重複を除去した配列Bの対応を明確にする目的で
Aと同じ長さのBのインデックスの羅列Cを取得する
Aの長さは208353 Bの長さは34834 である

```js:indexOf
C=A.map(x=>B.indexOf(x));
```
```js:Map
const map=new Map(B.map((x,i)=>[x,i]));
C=A.map(x=>map.get(x));
```
indexOfを使ったコードは43秒ほど掛かったが
Mapを使ったコードでは300ms周辺で済んだ
Mapの代わりにObjectも使ってみたが平均して20msほどObjectの方が遅かった
#indexOfをforするなら先に辞書を作ろう
"可変長引数"の意味がやっとわかった初心者

まずは普通のパターン。

```
def arg_loop(pro):
     for athlete in pro:
             print(athlete)
 
arg_loop('堀口','那須川','Dustin Pague','Floyd Mayweather')

#結果
TypeError: arg_loop() takes 1 positional argument but 4 were given
```
普通は関数は1つしか取れないので4つも与えても対応してくれません。そこで便利なのが可変長引数です。4つでも5つでも与えた分だけ(=可変長)、下のように結果を返してくれます。引数proの前に「*」をつけるだけです。


```
def arg_loop(*pro):
     for athlete in pro:
             print(athlete)
 
arg_loop('堀口','那須川','Dustin Pague','Floyd Mayweather')

#結果
堀口
那須川
Dustin Pague
Floyd Mayweather
```
参考文献：https://dev.classmethod.jp/articles/what-does-asterisk-mean-at-args/
Direct Link 2.0+Transit Gatewayで複数のClassicアカウントに接続する

Direct Link 2.0の接続先としては、これまでClassic（DLと同一アカウント）やVPC（DLと同一アカウントでも別アカウントでも可）でしたが、新たに、Transit Gateway（DLと同一アカウント）に接続可能になりました。

これにより、オンプレミスからDirect Link 2.0でIBM Cloudに入り、さらにTransit Gatewayをハブにして複数のClassic環境に接続できるようになりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59627/5f7da7a5-bfbc-6a9c-1a1f-a6d03a0f262d.png)

下記の手順で構成します。

なお、今回の新機能で構成の自由度が上がりましたが、多数の環境に接続する場合は下記もご確認ください。

作成可能なTransit Gateway自体の個数や接続先環境の数
https://cloud.ibm.com/docs/transit-gateway?topic=transit-gateway-helpful-tips

Transit Gatewayに繋ぐ場合、オンプレミスから広告できるprefixは120まで
https://cloud.ibm.com/docs/dl?topic=dl-how-to-order-ibm-cloud-dl-connect#before-you-begin-connect

# Direct Link 2.0をオーダー

Direct Link 2.0をオーダーします。これまでと違う点は、接続先タイプとして「Transit Gateway」を選択します。従来通りVPCや同一アカウントのClassic環境に繋ぐ場合は「直接リソース」を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59627/f9d088ae-4b8b-4091-46eb-cc4a0605cdc5.png)

# Transit Gatewayの接続先としてDirect Linkを選択

Transit Gatewayの設定画面で、「ネットワーク接続」のタイプとしてDirect Linkを選択します。
前の手順で作成したDirect Linkが表示されるので選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59627/11a7d46a-deb2-ed28-eb17-7db98d78c9f7.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59627/2f227249-3a88-0d2e-295d-1c537e8e4290.png)


# Transit Gatewayに接続先のClassic環境を追加

続いて、一般的なTransit Gatewayの設定と同様、接続したいClassic環境を指定します。
別アカウントのClassic環境への接続手順は[こちら](https://qiita.com/testnin2/items/a57fc659c82d99ba0602)をご参照ください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59627/d1bce4de-b074-61cb-a394-7468ebe84f1b.png)

接続先のアカウント側に、処理待ちのステータスでTransit Gatewayが表示されるので、承認します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59627/78519d34-fc5c-030e-0604-1ce9badd4223.png)

別アカウントにあるClassic環境を2つ接続し、Transit Gatewayに、Direct Linkが1つとClassic環境が2つ、接続された状態になりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59627/be4153b8-92d5-9615-a55a-b0c6900fff42.png)



# 疎通確認

Transit Gatewayに接続された環境同士は相互に通信可能になりますので、下記の通信が可能です。
・オンプレミスとアカウント2
・オンプレミスとアカウント3
・アカウント2とアカウント3

（最初の図の再掲）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59627/5f7da7a5-bfbc-6a9c-1a1f-a6d03a0f262d.png)

# 構成のバリエーション

下記の構成も可能で、この場合、アカウント2とアカウント3は通信できません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59627/bb28621d-7639-0496-7386-5f92e943435c.png)


また、アカウント1にリソースを配置することも可能です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59627/8eaabecb-7a72-4998-8a41-e3c120904259.png)
MySQLで、カラムの型を変更する

# はじめに
開発環境はrailsのデータベースを使用しており、本番環境では「Amazon RDS」の「MySQL」を使用していた。
そこでカラムの型を変更する必要があったので、下記のコードを実行したら問題なく変更できた。

# 結論
MySQLに接続し、以下のコードを実行してください

```
ALTER TABLE [テーブル名] MODIFY [カラム名] [変更したい型];
```

#経緯
開発環境のRailsで緯度、経度を登録しているテーブルがあり、それぞれのカラムを`float`で登録していました。

しかし、本番環境の「Amazon RDS」にそのまま移行すると、登録していた数値が正しく表示されませんでした。

おかしいと思って調べてみると、`float`は単精度浮動小数点実数と言って有効桁数が7桁までとのこと。

一方で、`double`というデータ型であれば、倍精度浮動小数点実数と言って有効桁数が１６桁まであるようです。

なので、対象のデータ型を`float`から`double`に変更すれば良さそうだと気づきました。

#実行

1.MySQLに接続し、データベース一覧を確認します

```
SHOW DATABASES;
```

2.上記のリストの中から、該当のデータベースに移動します

```
USE [データベース名];
```

3.テーブルの一覧を表示します
　変更したいテーブルを確認します

```
SHOW TABLES;
```

4.現状のテーブル構成を確認しておきましょう

```
DESC [該当のテーブル名];
```

5.それでは、実際にカラムのデータ型を変更してみましょう

```
#NOT NULL制約をつけたい場合は、最後にNOT NULLをつけてください
ALTER TABLE [テーブル名] MODIFY [カラム名] [変更したい型] NOT NULL;

#例として、テーブル名:check_points、カラム名: latitude、変更したい型: DOUBLEだった時
ALTER TABLE check_points MODIFY latitude DOUBLE NOT NULL;
```

6.テーブルが変更されたことを確認してください

```
DESC [該当のテーブル名];
```

以上の作業で、無事にカラムのデータ型を変更することができました！


#参考になった記事

https://qiita.com/t-fuku/items/e2a05ebc2ad1db259615

http://www.kusa.ac.jp/~kajiura/c/data/newpage1.htm
Unity2020のStarterAssetsで、TPSプレイヤーだけSceneに出したいとき

# この記事でできること
- Unity2020で、StarterAsstesをつかって、TPSプレイヤーだけを新規Sceneに追加することができる。

# 準備
- 新規SceneにあるMainCameraは削除しておく。

Starter Assets はこちらから([アセットストアのURL](https://assetstore.unity.com/packages/essentials/starter-assets-third-person-character-controller-196526))
![20210928a06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191635/e1e8b8eb-889d-1ec2-70a8-bc4ac13fb70d.png)

# 人型のTPSプレイヤーを出す場合
- Sceneに必要なプレファブデータ
 - グレーアウトのオブジェクトは無視して大丈夫です。(カプセル型のTPSプレイヤーのため)

![20210928a07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191635/2cdb1361-2bc9-2784-9c71-6004f7b1b119.png)

![20210928a08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191635/f9e31503-3808-d5a9-4fcc-c1bb424711b2.png)

# カプセル型のTPSプレイヤーを出す場合
- Sceneに必要なプレファブデータ
 - グレーアウトのオブジェクトは無視して大丈夫です。(人型のTPSプレイヤーのため)

![20210928a09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191635/5e392b71-0a92-9ab9-6609-264db36a750f.png)

![20210928a10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191635/d13f9bb6-2116-3cc6-6ae7-1eacc06837ef.png)

# こちらの記事もどうぞ
[unity2019LTSにスタンダードアセットを入れたあとのエラー回避方法](https://qiita.com/sanpeita/items/31cc55bea1ef59b10bdf)
[Unity2019以降でスタンダードアセットのFPSコントローラだけインポートする方法](https://qiita.com/sanpeita/items/053f0ed2d19c5ad11bb9)
selectableItemBackgroundBorderless が効かない場合の対処法

## 概要

Viewのサイズをはみ出した ripple エフェクトを適用したい時に便利な `selectableItemBackgroundBorderless` は、特に親のViewGroupが `ConstraintLayout` である場合に ripple が出ないといった意図しない挙動をすることがあります。

根本的な解決策を見つけるまでに時間がかかったので、自分用に調査したメモをまとめておきます。


## 結論

`selectableItemBackgroundBorderless`が効かない場合は、`selectableItemBackgroundBorderless`を適用しているViewを `android:background="@android:color/transparent"`を設定した`FrameLayout` でラップする。


## なぜそうなるのか

[StackOverflowの回答に的確な説明](https://stackoverflow.com/a/37757154)があったので、重要な部分の抄訳をしておきます。

> **Explanation:**
> "Borderless buttons draw their content on the closest background. Your button might not be having background between itself and the ImageView, so it draws underneath the ImageView."

> ボーダーレスボタンのコンテンツは最も近いbackgroundに描画されます。ボタンとそのそばにある `ImageView` の間にはbackgroundが存在しておらず、結果として `ImageView` の下に描画されます。


## 参考

* https://stackoverflow.com/questions/31948189/material-ripple-effect-hidden-by-other-view-in-layout
* https://stackoverflow.com/questions/45513451/selectableitembackgroundborderless-not-working/48189247#48189247
[Swift]UILabelの好きな場所に画像を追加し、行間を設定できる拡張メソッド

## やりたい事
UILabelの先頭に画像を追加して、Labelが複数行になった際の行間を追加できるメソッドを作る。
（Labelの末尾に画像を追加するなら、比較的簡単だけど…末尾以外だとちょっとややこしい:frowning2:）

- Labelが複数行で行間を設定できる
- textの先頭に画像を置く

↓イメージはこんな感じです。。。（※下記のコードを実行してもこのイメージの様にはなりません）


「:cat: ねこさんかわいい
　かわいいねこさん」


## コード

```.swift
extension UILabel {
    func setupSpacingAndImage(
        _ text: String, spacingHeight: Float, image: UIImage, at index: Int, size: CGSize? = nil
    ) {
        let attributedString = NSMutableAttributedString()

        let attachment = NSTextAttachment(image: image, font: font, size: size ?? image.size, alignment: .center)
        attributedString.append(NSAttributedString(attachment: attachment))
        attributedString.append(NSAttributedString(string: text))

        let style = NSMutableParagraphStyle()
        style.lineSpacing = CGFloat(spacingHeight)

        let attributes: [NSAttributedString.Key: Any] = [
            .paragraphStyle: style
        ]
        attributedString.addAttributes(attributes, range: NSRange(location: index, length: attributedString.length))

        self.attributedText = attributedString
    }
}
```

### 使い方

```.swift
// 引数imageは非Optionalなので、オプショナルバインディング
guard let image = UIImage(named: "imageName")
label.setupSpacingAndImage("Labelに表示したい複数行のテキスト", spacingHeight: 6, image: image, at: 0, size: CGSize(width: 16, height: 16))
```

### 引数の簡単な説明

**"Labelに表示したい複数行のテキスト"**
-> Labelのtextとして設定したい文字。引数名は省略しています。

**spacingHeight: 6**
-> 行間の高さを設定。

**image: image**
-> 挿入したい画像

**at: 0**
-> 何文字目に画像を挿入するか。メソッド内では、` at index: Int`によりatで設定した値をindexとして使用しています。

**size: CGSize(width: 16, height: 16))**
-> 画像のサイズです。ここを設定しない場合は、画像本来のサイズを設定します。
MongoDB 検索基礎

```
// NOT NULL
db.getCollection('AAA').find({'項目名':{$ne:null}})

// あいまい検索
db.getCollection('AAA').find({'項目名':{$regex:/キーワード/}})
db.getCollection('AAA').find({'項目名':/キーワード/})

// AND検索
db.getCollection('AAA').find({$and:[{'項目名1':'値'},{'項目名2':'値'},...]})

// OR検索
db.getCollection('AAA').find({$or:[{'項目名1':'値'},{'項目名2':'値'},...]})

// AND　と　IN 組み合わせ検索
db.getCollection('AAA').find({$and:[{'項目名1':'値'},{'項目名2':{\$\in:['値１','値２',...]}},...]})
db.getCollection('AAA').find({$and:[{'項目名1':'値'},{'項目名2':{\$\all:['値１','値２',...]}},...]})  --要検証

// $elemMatch 階層中の値ミスマッチ防ぐ　AA.BB AA.CC
// AA.BB AA.CC 両方満足
db.getCollection('AAA').find({'AA':{$elemMatch:{'BB':'値','CC':'値'}}})　---ケース要検証

//削除
db.getCollection('AAA').deleteOne({"AA":"値"});　　//一レコード削除
db.getCollection('AAA').deleteMany({"AA":"値"});　　//複数レコード削除

//sort
db.getCollection('AAA').find({}).sort({"AA":1});　　//1:昇順；-1降順

```
何もないところをタップでキーボードを閉じるを実現する

![hide-keyboard-on-tapping-other-area (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/56635/e2735ef6-b486-0355-8347-7e3edabe9781.png)

## 概要

チャット風アプリを作っていると 「何もないところタップしたらキーボードに閉じる」 という挙動を入れたくなります。そのための方法を2つ考えてみたので紹介します。

## 方法1

「何もないところ」は具体的にいうとキーボードや `EditText` 部分以外の `RecyclerView` の領域になります。なので、素直に`RecyclerView`のアイテムに対してクリックリスナーをセットしてその中でキーボードを閉じるコードを書いてあげればよさそうです。

```kotlin
groupieAdapter.setOnItemClickListener { _, _ ->
  hideKeyboard()
}
```

## 方法2

もう1つは **「フォーカス」** を利用する方法です。 `EditText` 以外の View にフォーカスが移動したらキーボードを閉じるという作戦です。

```kotlin
editText.onFocusChanged { gainFocus, _, _ -> 
  if(!gainFocus) {
    hideKeyboard()
  }
}
```

:::note info
フォーカスについての詳しいことは 公式ドキュメント https://developer.android.com/guide/topics/ui/ui-events.html](https://developer.android.com/guide/topics/ui/ui-events.html を参照のこと。
:::


あとは `RecyclerView` のアイテムの layout ファイルに以下を追記して、アイテムがフォーカスを取得できるようにします。

```diff
++ android:focusable="true"
++ android:focusableInTouchMode="true"
```

方法2は 例えば ダイアログやボトムシートを開いた時にキーボードを閉じたいといった場合にも応用が効きやすいという点で優れていると言えそうです。任意の View にフォーカス可能性を設定しておきさえすれば、その View にフォーカスが移動した時にキーボードが閉じてくれるからです。
Pythonのクラスメソッドで自身の型を返す方法

# 概要
- 自身のインスタンスを返すクラスメソッドを作成する際、下記のように返り値の型をクォーテーションで囲む必要がある

``` Python
@classmethod
def create(cls,
            name: str,
            age: int
            ) -> 'User':
```

- これはファイルの先頭で`from __future__ import annotations`を呼ぶことで解消できる

``` Python
from __future__ import annotations
from dataclasses import dataclass


@dataclass
class User:
    name: str
    name_in_lowercase: str
    name_in_uppercase: str
    age: int

    @classmethod
    def create(cls,
               name: str,
               age: int
               ) -> User:
        return User(name=name,
                    name_in_lowercase=name.lower(),
                    name_in_uppercase=name.upper(),
                    age=age)

    def print_description(self):
        print(f'name: {self.name}\nname_in_lowercase: {self.name_in_lowercase}\nname_in_uppercase: {self.name_in_uppercase}\nage: {self.age}')


def main():
    user = User.create(name="John Titor", age=36)
    user.print_description()


if __name__ == "__main__":
    main()

```

- 実行結果

```sh
name: John Titor
name_in_lowercase: john titor
name_in_uppercase: JOHN TITOR
age: 36
```

# 参考
- [Pythonでクラスの引数や戻り値の型アノテーションに自己のクラスを指定する \- Qiita](https://qiita.com/MtDeity/items/fa6cfc4fff8f58140caa)
Vue3 + TypeScriptにMaterial Design Icon(mdi)を導入する

# はじめに
導入する際に、思いのほか苦戦したので備忘録として投稿します。

# 導入
必要となる2種類のパッケージをインストールします。

```zsh
yarn add mdi-vue @mdi/js
```

mdi-vueはTypeScriptに対応していないようなので、ルートディレクトリの`shims-vue.d.ts`でdeclareしてあげます。

```shims-vue.d.ts
declare module 'mdi-vue/v3';
```

最後にmain.tsのcreateAppに以下の記述を追記します。

```main.ts
import mdiVue from 'mdi-vue/v3';
import * as mdiJs from '@mdi/js';

createApp(App)
  .use(mdiVue, { icons: mdiJs })
  .mount('#app')
```

# 使い方
後はmdi-vueで説明されているように、使いたい場所に以下のように記述してあげます。

```Home.vue
<template>
  <mdicon name="react" :width="30" :height="30" />
</template>
```

# 参考文献
- [MaterialDesign-JS](https://github.com/Templarian/MaterialDesign-JS)
- [mdi-vue](https://github.com/therufa/mdi-vue)
- [Material design icons for vue.js](https://bestofvue.com/repo/therufa-mdi-vue-vuejs-icons)
- [githubmemory.com](https://githubmemory.com/repo/therufa/mdi-vue/issues/61)
[Flutter] Webツール開発で使ったパッケージ紹介

# はじめに🔰

Flutter2 が正式リリースされたので、Flutterを用いてWebツールの開発をしてみました。
~~クソゲー~~ **神ゲーである**ドラクエ10のベルト装備を管理するためのWebツールです。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510027/f6d897d8-2ee2-7190-5c2c-39f46ae92535.png">

https://belmer-71509.firebaseapp.com/#/



# パッケージ紹介🎉

開発する際に使用したパッケージの中で、特に使い勝手がよかったものをいくつかご紹介します。

アプリ全体の状態管理は**BLoC**のパッケージを使用しています。
そのため、BLoCパターンと親和性の高いパッケージを多く使用しています。

**Firebase** や **AwesomeDialog** のパッケージについては、独自の紹介記事が多いため割愛します。



## 状態管理

### [flutter_bloc | Flutter Package](https://pub.dev/packages/flutter_bloc)

BLoCを使いやすいようにウィジェット化してくれているパッケージです。
自前で`StreamController`などを使って作る必要がなく、**イベントや状態の定義**も分かりやすく作れます。

使い方については公式や以下の記事が参考になりました。
https://qiita.com/tomon9086/items/9e5098f37aa6ae375e70
https://qiita.com/yokori/items/39e9033df8f7983f6112



## フォーム状態管理

### [flutter_form_bloc | Flutter Package](https://pub.dev/packages/flutter_form_bloc)

こちらもBLoCを使用したフォーム状態管理用のパッケージです。
**入力チェック**や**フィールド**、**イベント**が一通り揃っています。

独自の入力フォーム(画像アップロードやダイアログ選択)もカンタンに実装出来るため、使い勝手が良かったです。

[**チュートリアル**](https://giancarlocode.github.io/form_bloc/#/) が非常にわかりやすいため、とりあえず触ってみたいという方にもオススメです。

<img width="400" name="CustomeInputField" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510027/a015e092-1a44-3ed1-8e28-f019dc26b16a.gif">



### [reactive_forms | Flutter Package](https://pub.dev/packages/reactive_forms)

最終的には使用しませんでしたが、評判が良く使いやすいです。
`flutter_form_bloc`が一時期継続サポート終了しており、Nullsafety対応されてなかった際に使っていました。

機能も豊富で継続してアップデートされているため、**新規で使用するのであればこちらをオススメ**します。



## テーブルレイアウト

### [table_sticky_headers | Flutter Package](https://pub.dev/packages/table_sticky_headers)

Webでよくある**固定行・固定列**を表現するために使用しました。
スマホではめったに使わないレイアウトですが、使い勝手が良かったです。

<img width="700" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510027/a8f6a0ca-900e-a20e-10b0-5c48db29ec33.gif">



## アニメーション

### [flutter_sequence_animation | Flutter Package](https://pub.dev/packages/flutter_sequence_animation)

名前の通り、**定義したアニメーションを順番に実行**してくれるパッケージです。

今回は使用しませんでしたが、`CustomPainter`と合わせてローディング表示も作成できます。
https://qiita.com/yakuran1/items/138992a11c81654a4ffc



## アコーディオン表示

### [expandable | Flutter Package](https://pub.dev/packages/expandable)

`ExpansionTile` などの**展開↔縮小表示をListTile形式以外で表現する**ためのパッケージです。
スマホレイアウトでも使用頻度は高くオススメです。	



## ブラウザ表示

### [url_launcher | Flutter Package](https://pub.dev/packages/url_launcher)

**`<a>`リンクと同じような使い方**が出来ます。
使い方がカンタンで、認知度も高いので軽く紹介しておきます。



## JSONエンコード (デコード)

### [json_serializable | Dart Package](https://pub.dev/packages/json_serializable)

API等でJSON形式のデータをやり取りする場合にオススメのパッケージです。
[**json_annotation**](https://pub.dev/packages/json_annotation) と [**build_runner**](https://pub.dev/packages/build_runner) のセットで使用すると、モデルクラスのガワだけ作ればエンコード(デコード)を気にせず使用する事が出来ます。

使用方法は以下の記事が参考になります。
https://qiita.com/kurun_pan/items/455a1e7d6bbd91f0f1f3



# まとめ💮

**たのしい！！！(KONAMI感)**😊

これを機に紹介したパッケージを使用して頂ければ幸いです！

ちなみに上記の中には含みませんでしたが、
完全にWebページとして開発を行うのであれば、[**jsパッケージ**](https://pub.dev/packages/js)を使用して**JSライブラリを使用する**ことも可能です。

夢が広がりますね🤯
Qiita はじめてみた

#Background
Qiita初心者向けにというか、自分の学習のために作成しました。
これから駆け出しエンジニアとして、少しずつアウトプットできたらいいなと思います。

#Thesis statements
[1.他の人のMarkdownを見る方法](#1他の人のMarkdownを見る方法)
[2.見出しの書き方](#2見出しの書き方)
[3.コードの挿入](#3コードの挿入)
[4.リンクの挿入](#4リンクの挿入)

#Body

###1.他の人のMarkdownを見る方法
まずはQiitaを始めよう！と思っても何もわからない０の状態だと何から始めればわからないことが多いと思います。
そんな時は先人がたの例を参考にするのが一番わかりやすいのでは？
やり方は簡単

```
参考にしたいURL ＋　.md
```
以上です。

---
###2.見出しの書き方
文頭に\#をつけることで見出しを作成できます。
そして\#の数で大きさを変更。
htmlの「h1」や「h2」みたいなもの。

```:example
#見出しh1
\#見出しh1
###見出しh3
\###見出しh3
#####見出しh5
\#####見出しh5
```
---
###3.コードの挿入
次にコードの入れ方。（よく見る黒っぽいbar）
基本は\`\`\`(バッククオート3つ)でコードを挟みます。

\`\`\`
参考にしたいURL ＋　.md
\`\`\`
と書けば

```
参考にしたいURL ＋　.md
```
という感じになります。

:::note info
information
` はバッククオートです。（正解）
' はクォーテーションです。（間違い）
:::

---
###4.リンクの挿入
リンクの挿入は、\[リンクテキスト](URL)と書きます。

\[参考にした資料](https://qiita.com/shizuma/items/8616bbe3ebe8ab0b6ca1)

と記入すると。。

[参考にした資料](https://qiita.com/shizuma/items/8616bbe3ebe8ab0b6ca1)

という感じになります。

#Conclusion
まず今回学習したことが基本になると思います。
他の誰かの参考になれば幸いです。