OmniAICreator/Qiita-1.07M huggingface dataset:
docker-composeを使ってMySQLをローカルで起動した

業務でMySQLを使っていて、家の環境でも勉強できるようにしておきたいので、環境構築をしてみました。

Docker使いこなせないコンプレックスもあったので、
(というかDockerの概念くらいしか正直分かってなかった・・・)
MySQL用のコンテナを手を動かしてたててみることにしました。

お急ぎの方は記事の一番下に最終的な`docker-compose.yml`を配置したので参照してください。

## 前提

 - Docker Desktopを起動していること
 - macの場合は以下でインストールできるはずです。
    - `brew install docker`

## 公式のドキュメントを見つける

最初何からすればいいか分からなかったので、色々調べてたら公式のドキュメントを見つけました。

https://hub.docker.com/_/mysql

`docker-compose`はこちらみたいなファイルがあったので、それをそのまま使ってみる。

```docker-compose.yml
# Use root/example as user/password credentials
version: '3.1'

services:

  db:
    image: mysql
    command: --default-authentication-plugin=mysql_native_password
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: example

  adminer:
    image: adminer
    restart: always
    ports:
      - 8080:8080
```

上記を`docker-compose.yml`という名前で保存して、`docker-compose up -d`を実行すればOK。
自分は以下エラーが起きました。

```
ERROR: no matching manifest for linux/arm64/v8 in the manifest list entries
```

M1チップだとでるエラーみたいです。以下を`services.db`配下に追記します。

```yml
platform: linux/x86_64
```

上記を追加して、再度`docker-compose up -d`を実行するといろいろダウンロードがはじまります。すげー。
これで終わってしまった。知ってれば一瞬だなぁと感心しました・・・

## adminerを使ってアクセスしてみる

`docker-compose.yml`に書いてある`Adminer`でDBを閲覧できるものみたいで、コンテナ起動後に`http://localhost:8080`にアクセスすると`Adminer`の画面が表示されます。
`user:root`、`password:example`で入力するとログインできます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/561891/d7c64709-e472-4dd7-8f60-c464049c63f3.png)

## dockerコンテナに入らずともmysqlに繋がるようにする

cliで操作できるようにしたかったのですが、いちいちdockerに入るのも面倒だったので、ローカルから繋げられるようにしました。
`ports`に以下を追加。

```yml
    ports:
      - 3306:3306
```

これで、cliから入れるようになりました。以下で接続できるはずです。
`mysql -uroot -pexample -h 127.0.0.1`

mysqlクライアントのインストールがまだであれば、以下コマンドでインストールできるはずです。

```zsh
brew install mysql-client
export PATH="/opt/homebrew/opt/mysql-client/bin:$PATH"
```

## 最終的なdocker-compose.yml

```docker-compose.yml
# Use root/example as user/password credentials
version: '3.1'

services:

  db:
    platform: linux/x86_64 # M1チップ対応のため追記
    image: mysql
    command: --default-authentication-plugin=mysql_native_password
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: example
    ports:
      - 3306:3306

  adminer:
    image: adminer
    restart: always
    ports:
      - 8080:8080
```

なんだか最初はハードル高いと思い込んでいたのですが、
手を動かしてみたら結構簡単にできてびっくりしました。。

最後まで目を通していただきありがとうございました・・・！！
bq-visualizerをローカルホストで起動する

# 概要
bq-visualizerをご存知でしょうか。
色々と記事があるので詳しくはそちらをご確認いただくとして、ざっくりいうとBigQueryのジョブの実行結果を見やすく加工してくれるツールです。  
[GitHubにてGoogleがソースコードが公開されており](https://github.com/GoogleCloudPlatform/professional-services/tree/master/tools/bq-visualizer)、また[開発者の方が一般公開もされていて](https://bqvisualiser.appspot.com/)、こちらを利用している方もいらっしゃるかと思います。

https://github.com/GoogleCloudPlatform/professional-services/tree/master/tools/bq-visualizer

https://bqvisualiser.appspot.com/

しかしながら、BigQueryのジョブ情報を外部のサイトにuploadするのはセキュリティ的にどうなんだというのもあり、できれば会社のネットワーク内で利用できないかと考え、じゃあ立てたらええやんということでやってみました。  
なお、筆者はAngularとか詳しくないので、とりあえずlocalhostで立ち上げるまでを頑張りました。  
また、「とりあえず建てる」を目標としたので、細かいところは目をつぶっています。実際に社内で運用しようとしたらもっと色々考えることはあるはず。

要するにこの記事は自分用のメモです。

# 手順
## ローカルで資材の準備

1.Dockerfileを書く

```Dockerfile
FROM node:16.10.0-stretch

RUN npm install -g @angular/cli && ng config -g cli.packageManager yarn
WORKDIR /projects
```
2.Githubからクローン  
なるべく余計なファイルはダウンロードしないようにします。

```bash
git clone -b master --single-branch https://github.com/GoogleCloudPlatform/professional-services.git --depth 1
```

3.ビルド＆コンテナ起動

```bash
docker-compose up --build -d
```

4.コンテナに入る

```bash
docker-compose exec node bash
```

## コンテナ内での作業
1.bq-visualizerの階層まで移動して色々インストール

```bash
cd professional-services/tools/bq-visualizer/

yarn

# このまま起動しようとすると↓のエラーが出るので、typescriptのバージョンを下げる
# The Angular Compiler requires TypeScript >=4.2.3 and <4.4.0 but 4.5.2 was found instead.
npm uninstall -d typescript
npm install -d typescript@4.3.5
```

2.起動

```bash
yarn run ng serve --host=0.0.0.0
```

3.http://localhost:4200/ にアクセスで起動確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254900/3a476f5f-55ee-f5a2-f968-76760458e4ad.png)

# 注意点
- 手順の中にも書きましたが、TypeScriptのバージョンが合わずに起動しない場合があります。  
これの解決策がわからず、とりあえずuninstall&installで回避しました。  
TypeScriptのバージョンはどこに書いてあるんだろうか・・・
- 筆者の環境はMacです。Docker Desktop On Macのデフォルトのメモリでは足りず、エラーが発生しました。  
とりあえず8.00GBに設定したら起動できましたが、適切な値はまだ調べていません。

# 今後
最終的にはAppEngineあたりに乗せて社内で使えるようにしたいなと考えていますが、その前に見えているだけでもいくつかの課題があります。

- TypeScriptのバージョンコントロールがダサい
- docker-composeよくわかってない
- Angularよくわかってない
- メモリどれくらい必要かわかってない

まずはこの辺を調査＆勉強したいと思います。。
ApexのSObjectで「指定の名前のキーがあるか」調べる

ApexのsObjectで「指定の名前のキーがあるか」調べるメソッドはisSet()
(MapだとcontainsKey())

```
Account account = new Account(LastName = 'あ', FirstName = null, Phone = '');
System.debug('***1 ' + account.isSet('LastName')); // true
System.debug('***2 ' + String.isNotBlank(account.LastName)); // true
System.debug('***3 ' + account.isSet('FirstName')); // true
System.debug('***4 ' + String.isNotBlank(account.FirstName)); // false
System.debug('***5 ' + account.isSet('XXX')); // false
System.debug('***6 ' + String.isNotBlank(account.XXX)); // false
System.debug('***7 ' + account.isSet('Phone')); // true
System.debug('***8 ' + String.isNotBlank(account.Phone)); // false
```

参考：
https://developer.salesforce.com/docs/atlas.ja-jp.apexcode.meta/apexcode/apex_methods_system_sobject.htm#apex_System_SObject_isSet
【個人開発】バチェラーの優勝予想をする放置ゲームを開発しました

> 最初から優勝者を当てていたのに、その証拠がなく誰にも自慢できなかった。

これがバチェラー・ジャパン シーズン2（2018）を見終えたときから
自分の中に残っていたモヤモヤであり、本アプリ開発の背景です。

## サービス概要
[![Image from Gyazo](https://i.gyazo.com/06ced0101bbc63e1f402b3bd7a900bdf.jpg)](https://bachelor-derby4.herokuapp.com/)
文字通り「バチェラー・ジャパン シーズン4」の優勝予想をするシンプルなゲームです。
1分で遊べて人間観察力の自慢ができるサービスです。

https://bachelor-derby4.herokuapp.com/

## 使用技術
- Ruby
- Ruby on Rails(API)
    - slim
    - sorcery
    - jwt
    - meta-tags
- JavaScript
    - axios
    - bootstrap
- Vue.js
    - Vuex
    - VueRouter
    - VeeValidate
- Heroku

##　ルール
[![Image from Gyazo](https://i.gyazo.com/3e9b10c5d08396f826bcfa8ee8bfac39.jpg)](https://bachelor-derby4.herokuapp.com/)
「途中で予想を変えるとマイナスだが、予想した人が脱落するともっとマイナスになる」
というルールを作ることでゲーム性も持たせました。

## 使い方
基本的には**①ユーザー登録**と**②候補者BET**の2アクションで完結します。

①ユーザー登録は手軽さ重視でメールアドレスを要求しなかったところと、
　ニックネームにTwitterユーザー名を登録してもらい番組終了後の上位者発表ツイートで
　メンションすることで盛り上がりの一因となるようにしたところが工夫した点です。
VeeValidateでのユニーク制約がどこにも書いてなくて苦戦しました。
[![Image from Gyazo](https://i.gyazo.com/fe9d35a3853997ed28718123ac26ef14.png)](https://gyazo.com/fe9d35a3853997ed28718123ac26ef14)

②BETは「一覧から1人選択」→「確認モーダル出現」→「BET」の3フローです。
[![Image from Gyazo](https://i.gyazo.com/58ee8405bdcdfdeb393781cd7b008498.jpg)](https://gyazo.com/58ee8405bdcdfdeb393781cd7b008498)
[![Image from Gyazo](https://i.gyazo.com/f50f94e8fb6925647658f93f7293ed86.jpg)](https://gyazo.com/f50f94e8fb6925647658f93f7293ed86)
びっくりするくらいドンピシャのイラストが見つかったのが思い出です。

ちなみに今回使ったイラストサイトは以下の2つです。
どちらも**無料**で**登録不要**で**商用利用可**で**カラー変更可**で**SVGダウンロード可**という神サービスでした。
https://undraw.co/illustrations
https://storyset.com

## 頑張りポイント

###　①時間との勝負
もうこれがすべてです。
10月末にアイデアを思いつき11月初旬に着手したのですが、11月25日放送開始なので宣伝期間など考えると
2週間くらいしか猶予がないにも関わらず、使ったことのないVue.jsを採用するというドMっぷり。
でも、間に合わないとやってきたことがすべてパーになるというプレッシャーが逆に良かったのかもしれません。

###　②テーブル設計
頑張りというよりは工夫した点です。
今回はユーザーの配点を減らしていく処理が必要なのですが、ユーザーや管理者の「操作」によって処理すると
操作ミスのリスクが残ると考え、ユーザーと管理者の作った「履歴」によって処理する設計にしました。

ER図は以下の通りですが、ここは長くなりそうなので詳細は別記事でフォーカスしていこうと思っています。
（別記事ができたらリンク貼っておきます）
[![Image from Gyazo](https://i.gyazo.com/e4d6c0b1d30cd881f4dae9dd3477cb49.jpg)](https://gyazo.com/e4d6c0b1d30cd881f4dae9dd3477cb49)
これにより操作ミスのリスクを低減できるだけでなく、コントローラもシンプルなCRUDのみの記述にすることができました。

## 改善ポイント

###　パスワード忘れた時のパスワードリセット機能
ユーザーがパスワードを忘れたときにメールアドレスのみ送信してもらい、
そのアドレスにパスワードリセット用の特別なURLを送ることで
ユーザーにパスワードを再設定してもらうアレです。

sorceryを使っているのでwikiどおりにやれば簡単にできるはずなのですが、今回は手軽さを求めて
メールアドレスをユーザーに要求しなかったばかりにこれが一気に難しくなりました。

パスワードリセット申請の時だけメールアドレス入力してもらえばいいじゃん！と思いましたが、
ニックネームに秘匿性がないので悪意のある第三者が
自分のメールアドレスを入力することで乗っ取りができてしまうと思われます。
（乗っ取ってもそんなに出来ることないですが、、、）

なので、やるとしたら
　①ニックネームにはTwitterユーザー名の入力を強制。
　　忘れたときはニックネームでユーザーを特定し、DMでパスワード再設定用URLを送る。
　　（使ったことないけどTwitterAPIとか使えばDM自動送信くらいはできそう）
　②そもそもユーザー認証方法をTwitter認証一本に絞る。
　③やっぱりメールアドレスも登録してもらう（めっちゃ謝る）。
のどれかかなーとか考えていたら放送まで5日を切ってしまいタイムアップ。

使っていただく際は、パスワードを忘れないように祈っています。

###他にも使っていただいて改善点などあればご指摘いただけると幸いです。
https://bachelor-derby4.herokuapp.com/

コード：
https://github.com/a0ki-github/bachelor_derby4
【SAP-C01試験対策】AWS Gatewayの一覧

# はじめに
AWSの公式ドキュメントを参考に「Gateway」と名の付くサービスをまとめます。

https://docs.aws.amazon.com/index.html

# 背景
本記事はAWSソリューションアーキテクトプロフェッショナルに合格するために、[Udemyの模擬試験](https://www.udemy.com/course/aws-53225)を解いて分からなかった部分を勉強してまとめるものです。

試験対策用のため、分からない知識を補足したり試験で問われなさそうなところを省略したりしながらまとめています。
なるべくわかりやすい記載を心がけますが、最終目的は自己学習用であるということをご容赦ください。

#Gateway一覧
AWS Management Consoleの検索バーにGatewayと打ち込んだら出てくる機能を参考に書き出しました。漏れがあったらすみません。

|サービス名|機能名|接続|
|:--|:--|:--|
|VPC|インターネットゲートウェイ|VPCとインターネット|
|VPC|Egress Only<br>インターネットゲートウェイ|VPC(IPv6)とインターネット|
|VPC|NAT ゲートウェイ|プライベートサブネット内の<br>インスタンスとVPC外|
|VPC(VPN)|カスタマーゲートウェイ|[サイト間VPN](#サイト間VPN)のユーザ側|
|VPC(VPN)|仮想プライベートゲートウェイ|[サイト間VPN](サイト間VPN)のAmazon側(1つ)|
|VPC<br>(Transit Gateway)|[Transit ゲートウェイ](#Transit Gateway)|オンプレミスと複数VPC<br>[サイト間VPN](サイト間VPN)のAmazon側(複数)|
|Direct Connect|[Direct Connectゲートウェイ](#Direct Connect Gateway)|プライベートVIFと全リージョンのVPC|
|Storage Gateway|[Storage Gateway](#Storage Gateway)|オンプレミスとS3、Glasier、EBS|
|API Gateway|API Gateway|APIと利用元|

※VPCのキャリアゲートウェイ、Outpostsのローカルゲートウェイは[模擬試験](#背景)で見たことがないので割愛します。

# 補足
## [サイト間VPN](https://www.slideshare.net/AmazonWebServicesJapan/202110-aws-black-belt-online-seminar-aws-sitetosite-vpn)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/951272/8a82bdb8-3ef0-f5ed-ed9d-a91d5acb3027.png)

##[Transit Gateway](https://www.slideshare.net/AmazonWebServicesJapan/20191113-aws-black-belt-online-seminar-aws-transit-gateway)

中央ハブを介して VPC とオンプレミスネットワークを接続。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/951272/8e24ec61-c402-7be2-b0ec-4f2f417c43bd.png)


## [Direct Connect Gateway](https://d1.awsstatic.com/webinars/jp/pdf/services/20210209-AWS-Blackbelt-DirectConnect.pdf)

Direct Connect(VIF)とVGWの間で利用。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/951272/146d7b07-c38a-cd41-0f35-a6d674d6fa58.png)


## [Storage Gateway](https://d1.awsstatic.com/webinars/jp/pdf/services/20170125_AWS-BlackBelt-StorageGateway_20170223Update.pdf)

- ファイルゲートウェイ：NFSインターフェースで提供
- ボリュームゲートウェイ：iSCSIブロックインターフェースで提供
- テープゲートウェイ： iSCSI仮想テープライブラリ(VTL)インターフェースで提供
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/951272/2f1eb0e3-d1fd-154c-ada4-81cb020b3d5f.png)
※[iSCSI](https://www.fujitsu.com/jp/products/computing/storage/lib-f/tech/interface/iscsi/)：IPネットワークを利用してSAN（Storage Area Network）を構築するプロトコル規格
【備忘録】foreachの基本的な使い方

Laravelを１から勉強しており、foreachの基本的な使い方を忘れないために備忘録です。
間違っていることがありましたらご指摘ください。
画像のような本を管理するアプリに例えて考えていきます。

![スクリーンショット 2021-11-21 23.07.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/985164/f37b2f60-de36-8d97-1289-69b4545337c8.png)

### booksテーブルには以下のようなカラムが作成されていることとします。

```php:booksテーブルにあるカラムの一部抜粋
id
book_name
created_at
```

### bookコントローラーには以下のようにindex関数が定義されていることとします。

```php:BookController
class BookController extends Controller
{
  public function index()
  {
      // DBよりBookテーブルの値を全て取得
      $books = Book::all();

      // 取得した値をビュー「book/index」に渡す
      return view('book/index', compact('books'));
  }
```

### ビュー(blade)でテーブルを作成

```php:resources/views/index.blade.php
<table class="table table-striped">
  <thead>
    <tr>
      <th>ブックナンバー</th>
      <th>ブック名</th>
      <th>作成日</th>
    </tr>
  </thead>
  <tbody>
    @foreach ($books as $book)
    <tr>
      <td>{{ $book->id }}</td>
      <td>{{ $book->book_name }}</td>
      <td>{{ $book->created_at }}</td>
    </tr>
    @endforeach
  </tbody>
</table>
```

このコードのポイントは、ここです。

```php:resources/views/index.blade.php
<tbody>
    @foreach ($books as $book)
    <tr>
      <td>{{ $book->id }}</td>
      <td>{{ $book->book_name }}</td>
      <td>{{ $book->created_at }}</td>
    </tr>
    @endforeach
  </tbody>
```

予めコントローラーで変数＄booksを定義しておいたことにより、
ビューでforeach構文を使うことで、変数＄booksに渡したデータベースのデータを
１つずつ(＄books as ＄book)表示させることができるのです。

その結果、記事のTOPに添付したような表（テーブル）を作成することができるのです。

▼参考にさせていただいた記事

https://www.kamome-susume.com/foreach-table/#index_id0
インフラエンジニア学習 CCNA 1121

MACアドレス
・データリンク層
・ネットワーク内で識別する

IPアドレス
・ネットワーク層
・ネットワーク全体で識別する
※IPアドレスの方が対象が広範囲

IPの役割
・IPアドレス
・ルーティング
・分割と再構築

IPの特徴
・階層型の論理アドレスを使用する
・ベストエフォート型の配信を行う
・コネクションレス型のプロトコル
・インターネット層のプロトコル

IPv4に含まれるフィールド
・TTL
・チェックサム
・プロトコル


TCPに関連するもの
・ポート番号
・シーケンス番号
・ウィンドウ
・セグメント
・フロー制御


３ウェイハンドシェイク
・SYN:コネクションの確立を要求する。
・ACK:確認応答であることを示す。
１番目　SYN=1、ACK＝0
２番目　SYN=1、ACK=1
３番目　SYN=1  ACK=1


TCP
・コネクション型
・同期通信
・高信頼性
・シーケンス番号による順序制御
・データ単位はセグメント

UDP
・コネクション型
・ベストエフォート型
・確認応答なし
・オーバーヘッドが小さい
・音声やビデオストリーミングに適している
・データの単位はデータぐらむ

※TCPは信頼性のあるデータ通信
※UDPは効率の良いデータ通信


TCPでは最初に３ウェイハンドシェイクを確立してからデータを転送する。

UDPはVoIPやビデオデータなどリアルタイム性のあるデータ転送に適している。
信頼性を必要としない少量のデータを転送する際に使用される。


ARP
・宛先IPアドレスに対応するエントリがない場合、ARPリクエストを送信
・宛先IPアドレスに対応するエントリがある場合、パケットを転送

イーサネットフレームの宛先MACアドレスは、ARPによって取得する。
ARPメッセージはイーサネットヘッダにで直接カプセル化する。


ICMP
・ICMPはインターネット層のプロトコル。
・IPのエラー通知や制御メッセージを送信する。
・pingはICMPのエコー要求とエコー応答を使用。
・tracerouteもICMPのエコー要求を使用。
・ルータはパケットを転送できないとき、パケットを破棄して送信者にDestination Unreachableで通知する。
TypeORMのtransformerの仕組みが分からなかったので記事を書いたら理解できた話

# 概要
今までは都道府県のデータをDBテーブルに登録して管理していました

しかし、TypeORMの`transformer`という仕組みを利用すれば都道府県テーブルをDBで管理する必要が無くなりました！

その方法を導入した職場のエンジニアさんから教えてもらったので備忘録として紹介します


# やり方

## 固定データを管理・操作するマスタークラスを作成します

:::note info
今回は都道府県ID・都道府県名のみ管理するためinterfaceを定義します
constructorで定義したIMaster型を受け取ります
:::

<details><summary>サンプルコード</summary><div>

```
export class Master {
  private readonly masters: IMaster[]
  
  constructor(masters: IMaster[]) {
    this.masters = masters
  }

  findNameById(id: number) {
    return this.masters.find((v) => v.id === Number(id))
  }

  findIdByName(name: string) {
    return this.masters.find((v) => v.name === name)
  }
}

export interface IMaster {
  id: number
  name: string
}

```
</div></details>


## 都道府県データをIMaster化します

:::note info
先程定義したImaster型の通り都道府県ID・都道府県名を定義します
固定データを管理するmasterクラスをextends（継承）して親クラスのconstructorを呼び出します（super)
:::

<details><summary>サンプルコード</summary><div>

```
import { IMaster, Master } from './master.master'

const PREFECTURE: IMaster[] = [
  {
    id: 1,
    name: '北海道',
  },
  {
    id: 2,
    name: '青森県',
  },
  // 省略します
  {
    id: 47,
    name: '沖縄県',
  },
]

class PrefectureMaster extends Master {
  constructor() {
    super(PREFECTURE)
  }
}

export const Prefecture = new PrefectureMaster()
```
</div></details>


## transformerを利用してEntityを定義します

:::note info
from = 読み込み時にはImaster型から都道府県IDだけ
to = 書き込み時にはまず都道府県IDを受け取り該当する都道府県のImaster型をDBに登録します
:::

<details><summary>サンプルコード</summary><div>

```
  @Column('tinyint', {
    unsigned: true,
    comment: '都道府県ID',
    transformer: {
      from(id: number): IMaster {
        return Prefecture.findNameById(id)
      },
      to(value: IMaster): number {
        return value.id
      },
    },
  })
  prefecture_id: IMaster
```
</div></details>

# 参考文献

https://stackoverflow.com/questions/59760551/typeorm-column-value-from-sanitized-other-column-value

https://typeorm.io/#/entities/column-options

# 最後に

読んでいただきありがとうございます。
今回の記事はいかがでしたか？
・こういう記事が読みたい
・こういうところが良かった
・こうした方が良いのではないか
などなど、率直なご意見を募集しております。
【RealmSwift】AnyRealmValue型で様々なデータ型を取り扱う

# はじめに

RealmSwiftのバージョン10.8.0から、様々なデータ型を保有できるAnyRealmValue型が実装されました。
（公式サイトでの解説は[こちら](https://docs.mongodb.com/realm/sdk/ios/data-types/anyrealmvalue/)） 

使い方次第ではなかなか便利そうなのですが、2021年11月現在日本語での解説記事が見当たらないため、簡単に情報をまとめてみました。

- 環境
    - Xcode: v13.0
    - RealmSwift: v10.19.0

（RealmSwiftそのものの使い方については説明を省きますので、適宜他の解説記事をご参照ください）

# AnyRealmValue型の使い方

AnyRealmValue型には、Int、Float、Bool、Stringといった一通りの型のデータを入れることができます（具体的な入れられる型の一覧については、冒頭の公式サイトへのリンクをご参照ください）。
代入にあたっては専用のメソッドを用います。例えばInt型のデータを入れたい場合、

```swift
@Persisted var anyValue: AnyRealmValue = .int(0)
```
で入りますし、String型なら

```swift
anyValue = .string("Hello world")
```
でOKです。

データを取り出す時は、入っている型を判定した上で処理を行うことが可能です。
例えばSwiftUIにおいて「AnyRealmValue型のプロパティにint型の値が入っている時だけその中身を表示し、そうでない時はその旨を表示する」という挙動を実装したい場合、

```swift
if case let .int(value) = item.anyValue {
     Text("Int: \(value)")
}else{
     Text("anyValueに入っているのはInt型ではありません。")
}
```
とすればOKですし、もちろん.intの部分は他の型に変えることができます。

# Objectを取り扱う

AnyRealmValue型には値だけでなくObject（これは一般のオブジェクトではなく、Realmのデータモデルを定義したクラスを指すことにご注意ください）を入れることもできます。例えば以下のようなRealmのデータのモデルを定義し、

```swift
class SandBoxInside: Object, ObjectKeyIdentifiable {
    @Persisted var text = "Hello."
    @Persisted var value = 0
    @Persisted var power = 0
    
    override init(){
        super.init()
        value = Int.random(in: 10..<1000)
        power = Int(floor(pow(Double(value), 1.1)))
    }
}
```
このように代入し……

```swift
item.anyValue = .object(SandBoxInside())
```

以下のように記述して、画面に表示してみます。

```swift
if case let .object(value) = item.anyValue {
    Text("Object: \(value)")
}
```
結果として以下のようなテキストが現れると思います。

```
Object: SandBoxInside {
    text = Hello.;
    value = 885;
    power = 1744;
}
```
Objectが保有するプロパティに個別にアクセスしたい場合は、以下のように型キャストを行えばOKです。

```swift
if case let .object(value) = item.anyValue {
    if let objRaw = value as? SandBoxInside {
        Text("\(objRaw.text)")
        Text("value: \(objRaw.value)")
        Text("power: \(objRaw.power)")
    }
}
```

以上、AnyRealmValue型の使い方に関する説明でした。

Realmは長らくデータモデル間での継承が行えないという短所があるようで2021年11月現在も完全な解決はされていないのですが、これを利用することで擬似的にどうにかできるのではないか……とは思っています。
（とりあえず違う型のオブジェクトを全部一つのリストの中で扱いたい、みたいなのはこれでなんとかなるかなと……）
【Ruby のまずいコード】HTML エスケープ

# お題

引数として与えられた文字列を HTML エスケープするコードを書いてください。
HTML エスケープとは，以下の変換を施すこととします。

* `&` →`&amp;`
* `<` →`&lt;`
* `>` →`&gt;`
* `"` →`&quot;`
* `'` →`&#39;`

# コード

## コード 1

```rb
def escape_html(str)
  result = ""
  str.each_char do |char|
    case char
    when '&'
      result << '&amp;'
    when '<'
      result << '&lt;'
    when '>'
      result << '&gt;'
    when '"'
      result << '&quot;'
    when "'"
      result << '&#39;'
    else
      result << char
    end
  end
  result
end
```

## コード 2

```rb
def escape_html(str)
  escape_table = {
    '&' => '&amp;',
    '<' => '&lt;',
    '>' => '&gt;',
    '"' => '&quot;',
    "'" => '&#39;'
  }
  str.gsub(/[&<>"']/){ escape_table[$&] }
end
```

# 問題点

## コード 1

コード 1 は，ある意味で素直というか素朴なコードですね。プログラミング言語をどれか一つ新しく学び始めたとき，誰でもこれに近い発想のコードを書くのではないでしょうか。

Ruby らしい点といえば，`String#each_char` というイテレーターメソッドを使っていることや，条件分岐に `case` を使っていること，また，文字列を破壊的に結合する `<<` を使っていることでしょうか。
これらを知らなければ

```rb
for i in 0..(str.length - 1)
  char = str[i]
  if char == '&'
    result = result + '&amp;'
  elsif char == '<'
  # ...
```

のようなコードを書いてしまうかもしれません。

いずれにしても，コード 1 は効率が悪く，長すぎます。

`str` が 1000 文字なら，1000 回もループします。`str` の中にエスケープすべき文字が一つも無くても 1000 回ループするのです。回るたびに文字列の結合が発生します。

## コード 2

コード 2 は，コード 1 よりは簡潔で，効率も良くなっています。

最大のポイントは `String#gsub` を用いたことですね。エスケープすべき文字を正規表現 `/[&<>"']/` で表し，これにマッチする箇所だけを変換します。`str` が 1000 文字でも，エスケープすべき文字が 3 個しかなければ，ブロックは 3 回しか呼ばれません。
もう一つのポイントは，条件分岐を用いず，ハッシュを使って変換していることです。

このコードは，`String#gsub` の使い方として最適とは言えません（後述）。

メソッドが呼ばれるたびにハッシュ（`escape_table`）が生成される点も気になります。
メソッドが 1000 回呼ばれたらこのハッシュは 1000 回生成されます。使い捨てなのでガーベジコレクションの対象になります。

このハッシュ式をうっかり `gsub` のブロック内に書こうものなら，ブロックが呼ばれるたびに新たにハッシュを生成してしまいます。

こういった効率の悪さが現実のプログラムで性能低下を実際に引き起こすかどうかはケースバイケースです。
短い文字列に対してメソッドが数回呼ばれる程度なら，実行時間の差は測定限界を下回るでしょう。
とはいえ，効率の良いやり方があるなら最初からそのように書きたいものです。


# 改善

## 小手先の改善

コード 2 を少し改善してみます。
ハッシュが毎回生成される問題を回避する簡単な方法は，ハッシュ式をメソッドの外に出すことです。

それから，[String#gsub](https://docs.ruby-lang.org/ja/3.0.0/method/String/i/gsub.html) は第二引数にハッシュを与える用法を採用しましょう。
使い方はリンク先を参照ください。

すると，コードはこんなふうに書けます。

```rb
ESCAPE_TABLE = {
  '&' => '&amp;',
  '<' => '&lt;',
  '>' => '&gt;',
  '"' => '&quot;',
  "'" => '&#39;'
}

def escape_html(str)
  str.gsub(/[&<>"']/, ESCAPE_TABLE)
end
```

欠点は，`escape_html` メソッドでのみ使う定数 `ESCAPE_TABLE` がメソッドの外で定義されていること。
内部で使うものがトップレベル[^toplevel]にあるのはあまりよいスタイルではありません。
本記事のテーマからは離れますが，モジュールを定義して

[^toplevel]: すべてのモジュール定義、クラス定義、メソッド定義の外側のこと。

```rb
module HTMLUtil
  ESCAPE_TABLE = {
    # 云々
  }

  def self.escape_html(str)
    # 云々
  end
end
```

のようにすると，この点は改善されます。

## 最善策

実はこんなことをしなくても，標準添付ライブラリーに専用メソッド [CGI.escapeHTML](https://docs.ruby-lang.org/ja/3.0.0/method/CGI/s/escapeHTML.html) があるのでした（しかも高速）。
こんなふうに使います：

```rb
require "cgi/escape"

p CGI.escapeHTML("Q&A") # => "Q&amp;A"
```

ですので，メソッドを定義する必要すらありません。
**既にあるもの**をそのまま使えばいいのでした。

このメソッドについては，ぜひ以下の拙記事もご覧ください。
[素の Ruby で HTML エスケープするなら cgi/escapeが最強 - Qiita](https://qiita.com/scivola/items/b2d749a5a720f9eb02b1)
Rubyにおける : の意味

#はじめに
Rubyでコードを書いていると、`:`や`::`がよく出てきますが、
いまいちはっきりと理解できていなかったためまとめてみます。

##シンボル

シンボルとは、任意の文字列に`1対1`に対応するオブジェクト
`:hoge`のように表す
下記のように、文字列が都度異なるIDになるのに対し、シンボルではすべて同じIDになる
メリット: メモリの節約(メモリの同じ領域を使用するため)

```ruby
[1] pry(main)> :hoge.object_id
=> 2307228
[2] pry(main)> :hoge.object_id
=> 2307228
[3] pry(main)> "hoge".object_id
=> 300
[4] pry(main)> "hoge".object_id
=> 320
```


##ハッシュのキーにシンボルで使う場合
ハッシュのキーには一般的に文字列ではなく、シンボルを使用する
理由としては、文字列よりも高速で値を取り出すことができるため

```ruby
[1] pry(main)> hash = { name: '太郎', age: 20 }
=> {:name=>"太郎", :age=>20}
```

##キーワード引数
メソッドに引数を渡す場合に、その引数のもつ意味をわかりやすく表現したい場合

##条件演算子
記法は、

```
とある条件 ? 条件がtrueの時 : 条件がfalseの時
```

以下の二つは同じ意味の条件式
`:` を使うことで、簡略に記述することができる


```ruby
score = 80
score > 60 ? "合格" : "不合格"
=> "合格"
```

```ruby
score = 80
if score > 60
 "合格"
else
 "不合格"
end
=> "合格"
```

  


##クラスの外部から定数を参照する場合
外部クラスの定数を参照する際に、::を使用する

```ruby
class Hoge
  FOO = 'Bar'
end

Hoge::FOO
=> "bar"
```

#使用例
validatesメソッドの引数にたくさん:が登場しています。
`:email` `:uniqueness` はシンボル
`:length` `:format` はキーワード引数
`maximum: 255` `with: VALID_EMAIL_REGEX` はハッシュのキーにシンボルを使用している
という意味で使っています。



```ruby
validates :email, presence: true, length: { maximum: 255 },
                    format: { with: VALID_EMAIL_REGEX },
                    uniqueness: true
```

#参考文献
プロを目指す人のためのRuby入門(https://bit.ly/3wmJheK)
Mirakurun　千葉　番組表

sudo mirakurun config channels

nano /usr/local/etc/mirakurun/channels.yml
```
- name: ＴＯＫＹＯ　ＭＸ
  type: GR
  channel: '16'
- name: ｔｖｋ
  type: GR
  channel: '18'
  isDisabled: false
- name: ＴＯＫＹＯ　ＭＸ
  type: GR
  channel: '20'
  isDisabled: false
- name: フジテレビ
  type: GR
  channel: '21'
- name: ＴＢＳ
  type: GR
  channel: '22'
- name: テレビ東京
  type: GR
  channel: '23'
- name: テレビ朝日
  type: GR
  channel: '24'
- name: 日テレ
  type: GR
  channel: '25'
- name: ＮＨＫＥテレ・東京
  type: GR
  channel: '26'
- name: ＮＨＫ総合・東京
  type: GR
  channel: '27'
- name: チバテレ
  type: GR
  channel: '30'
  isDisabled: false
FileMakerでヌルっとトグルスイッチを再現

# はじめに
@OnTheRocks_plzさん、@qbxxdpさんの[「ヌルっとON/OFFボタン」](https://twitter.com/OnTheRocks_plz/status/1419889214569684993)に触発されて、チャレンジしたみたので、その記録。できるかどうか分からないのにチャレンジするのと、できると分かってチャレンジするのは、雲泥の差。しかも、できると分かってチャンレンジしても、全く分からない[ヤツ](#未解決課題)もある。

# 実際の動き
![20211121_SmoothToggleSwitch.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2283446/d523edc5-36e2-7591-90ee-fa72e49a368a.gif)

# 検証環境
macOS Monterey 12.0.1, FileMaker Pro 19.4.1

# 解説
サンプルファイルを見れば分かると思いますが、簡単な解説。

- 11個のボタンを設定したボタンバーを用意。
- 各ボタンのアイコンとして、トグルスイッチのアニメーションを11分割したも画像を設定する。
- 各ボタンは、グローバル変数が、各数値に合わない時は「隠す」設定にしておく。
- 0と1に相当するボタンに、トグルスイッチを変更するスクリプトを設定する。
- グローバル変数は0から1まで0.1刻みでループで変化させる。 
- [ボタンバーは最強](https://twitter.com/OnTheRocks_plz/status/1418726642885615618)らしい。

これでヌルっと動く。トグルするグローバル変数も0.1刻みで値が変更していくので、0/1で値を判定させている場合には、少し注意を要する。

グローバル変数の管理方法については[こちらの記事](https://qiita.com/siebenunddreissig/items/144fa0e2abdbf1519719)を参照してください。[導入の仕方](#導入の仕方)での2個目の導入時においても、関数名を変更するだけで、スクリプトやオブジェクトに設定されているグローバル変数の呼び出し全ての名前が変わるのも、メンテナンス的に役立つ。

# 導入の仕方
1. カスタム関数をインポート。  
サンプルファイルから、"Set.Toggle"、"Get.Toggle"の２つの関数をインポートする。
2. スクリプトをインポート。  
サンプルファイルから、"button_Toggle_Switch()"スクリプトをインポートする。
3. レイアウトオブジェクトをコピー＆ペースト。  
サンプルファイルのレイアウトから、該当オブジェクト（ボタンバー）をコピーし、導入先へペーストする。

もし、2個目のトグルスイッチを導入したい場合には、サンプルファイル上で、

1. カスタム関数の名前を変更。  
サンプルファイルで、"Set.Toggle"、"Get.Toggle"の２つの関数を、たとえば"Set.Toggle2"、"Get.Toggle2"に変更する。この時、それぞれの関数内で用いられているグローバル変数名も同様に変更しておく。
2. スクリプトの名前を変更。  
サンプルファイルで、"button_Toggle_Switch()"スクリプトを、たとえば"button_Toggle_Switch2()"に変更する。  

あとは初回導入時と同じ手順を踏む。

# サンプルファイル
GitHubからダウンロードできます。
<a href="https://github.com/siebenunddreissig/SmoothToggleSwitch"><img src="https://github-link-card.s3.ap-northeast-1.amazonaws.com/siebenunddreissig/SmoothToggleSwitch.png" width="460px"></a>
アカウントはadmin、user、fm1の3つが用意されており、いずれのパスワードもアカウントと同じです。いずれのアカウントも完全アクセスにしてあります。
ファイルオプションでuserでログインするようにしてあります。

# 未解決課題
[「ショウリュウケン」](https://twitter.com/OnTheRocks_plz/status/1422885249885773824)や[「ハイパーオリンピック」](https://twitter.com/OnTheRocks_plz/status/1400615334344679425)は仕組みがさっぱり想像つかない。@p388cellさんの[「うごく五輪」](https://twitter.com/p388cell/status/1418711329775312899)も全く分からない。誰か偉いヒト解説して。
Vue CLI Plugin Electron Builder + TypeScriptでpreloadを設定するとき

# 環境

* Vue: 2.6.11
* Electron: 13.0.0
* Vue CLI Plugin Electron Builder: 2.1.1

# 状況

Electronでの重要な要素の1つに、IPC通信というものがあります。詳細は、下記記事などが参考になります。

https://qiita.com/hibara/items/c59fb6924610fc22a9db

上記記事でも述べられていますが、現在、ElectronでIPC通信を行うときは、contextBridgeを使うことが推奨されています。そして、そのcontextBridgeを使うときは、preloadスクリプトというものを用意します。

以下、メモ書きで恐縮ですが、Vue CLI Plugin Electron Builderを使ってTypeScriptで開発するときに、preloadスクリプトの設定方法を記します。

# 設定方法

## 1. `preload.ts`を作成する

`background.ts`と同じディレクトリに作成します。

```typescript:preload.ts
import { contextBridge, ipcRenderer, IpcRendererEvent } from "electron";

// 以下、contextBridgeを使ったコード
```

## 2. メインプロセスにpreloadを追加

`background.ts`内で`BrowserWindow`をインスタンス化している部分に、`preload`オプションを追記します。`preload.ts`ではなく、`preload.js`である点に注意。

```diff:background.ts
+ import path from 'path'

  const win = new BrowserWindow({
    width: 800,
    height: 600,
    useContentSize: true,
    webPreferences: {
+     preload: path.join(__dirname, 'preload.js'),
    },
  })
```

## 3. プラグインにオプションを追加

`vue.config.js`内に、Electron Builderプラグイン用のオプションを追記します。設定可能なオプションは多数ありますが、その中の1つである`preload`オプションを追記します。

```diff:vue.config.js
  module.exports = {
+   pluginOptions: {
+     electronBuilder: {
+       preload: 'src/preload.ts',
+     },
+   },
  }
```

preloadオプションについては、Electron Builderのドキュメントにも記述されています。

https://nklayman.github.io/vue-cli-plugin-electron-builder/guide/guide.html#preload-files
【Ruby のまずいコード】階乗

# お題

引数として与えられた正の整数の階乗を返すメソッドを定義してください。
`n` の階乗とは，1 から `n` までの整数を掛け合わせたものです。

# コード

## コード 1

```rb
def factorial(n)
  (1..n).inject{ |product, x| product * x }
end
```

## コード 2

```rb
def factorial(n)
  (1..n).inject(&:*)
end
```

# 改善

コード 1 よりコード 2 のほうが簡潔ですが，[Enumerable#inject](https://docs.ruby-lang.org/ja/3.0.0/method/Enumerable/i/inject.html) には引数としてシンボルを与える用法があり，これを使うと

```rb
def factorial(n)
  (1..n).inject(:*)
end
```

と書けます。
コード 2 より 1 字少ないだけですがコード 2 では Proc オブジェクトが作られるのに対し，こちらは作られません。

速度は大して変わらないようですが，`n` が小さいときはこちらのほうが有意に（しかし少しだけ）速いようです。
超簡単!ハンバーガーメニュー

こんにちは!
今回はハンバーガメニューを作成していきたいと思います。
スライドで表示させるメニューについては触れません。
あくまでクリックした時に、3本線から❌に変化するコードを書きます。
# 最終的なコード
<a href="https://daigo0001.github.io/css_clone/">デモページ</a>

```html:index.html
  <div class="ham" id="hamMenu">
    <span class="line top"></span>
    <span class="line middle"></span>
    <span class="line bottom"></span>
  </div>
```

```css:index.css
    .ham{
      position: relative;
      text-align: center;
      width: 100px;
      height: 100px;
      cursor: pointer;
    }

    .line{
      position: absolute;
      width: 100px;
      height: 2px;
      background-color: black;
      transition: ease-in-out 0.5s;
    }
    /*- transitionが適用されるまでに0.5sかかるということになる-*/


    /*-----click前--------*/
    .top{
      top: 20px;
    }

    .middle{
      top: 40px;
    }

    .bottom{
      top: 60px;
    }

    /*-----click後----*/

    .close .top{
      transform: rotate(-135deg);
      top: 50px;
    }

    .close .middle{
      opacity: 0;
      transform: translateX(70px);
      top: 50px;
    }

    .close .bottom{
      transform: rotate(135deg);
      top: 50px;
    }
```

```javascript:index.js
  const ham = document.getElementById('hamMenu');

  ham.addEventListener('click', () => {
    ham.classList.toggle('close');
  });
```

# 解説

ハンバーガーメニューのメインとなる3本線ですが、htmlを見てもらうとわかるように<b>span</b>タグを使って表現します。

hamクラスを`position: relative;`で基準として`position: absolute;`でズラして三本線にします。高さを変えるのはcssを見て貰えばわかる通り、`top, middle, bottom`で変更しています。
これはlineクラスに対して、positionをabsoluteにしているからです。
何も指定しなかったら3本が重なっている状態になるので気を付けてください。

### ❌印
複雑に見えますが、実際は単純な動作で上の線と下の線をそれぞれ45度傾けさせているだけです。

クリックした時に変化させたいので、javascriptを用いて、クリックした時にcssを付与するようにしましょう。


```javascript:index.js
// hamMenuを取得します。これでhtmlでこのidを指定している要素に対しての処理を描くことができます。
  const ham = document.getElementById('hamMenu');

//addEventListenerを使って、idがhamMenuの要素がクリックされたら,,,という処理を描くことができます。
  ham.addEventListener('click', () => {
    ham.classList.toggle('close');
  });
//classList.toggle('class名');
//とすることで、クラス名があれば削除、なければ付与といった処理が行われます
```


要素に対して、動きを与えたい時は`transform`を使います。
今回は回転させる動作をしますが、他にも色を変えたり、透明にしたり、サイズを変えたり横に移動したりと色々なことができます。
角度を変えるには`transform`プロパティの`rotate`を使います

ここで、lineクラスに`transition`を指定するのを忘れないでください。
指定しなくても問題はないのですが、`trantition`を指定することで動き方、transformする時間を指定できます。

1番上の線に`transform: rotate(45deg);`これで45度の回転ができます。
今回は少し動きを変えたいので-135としています。どちらも試してみてください

下の線も同じように`transform: rotate(45deg);`としたいのですが、これだと❌に見えません。なので、反対方向に回転させるようにしましょう。`transform: rotate(-45deg);`とすることで逆回転させることができます。
今回は135とします。

ここで一度確認してください。
回転はちゃんとするけれど、うまく❌にならないことがわかると思います。

これは回転する時に、線の端を基準としているのではなく、要素の中間を基準としているからです。
線の幅に対する値は、100pxとなっているので、同じように`.close .top`と`.close .bottom`にも　50pxを指定します。

cssファイルで、`.close .top`としているのは、`.close `クラスの中の`.top`クラスという解釈ができるからです。つまり`.close`が付与された時の`.top`の挙動ということです。

これで❌にすることができました!

仕上げに真ん中の線も消してあげましょう！
`.close .middle`に`opcity: 0;`とすることで透明になり、見えなくすることができます。
それに加えて、`transform: translateX(70px);`とすることでX軸方向に70px移動しながら透明になる。という動作を描くことができます。

以上でハンバーガーメニューの実装は完了です！

## おまけ
回転量を、135や405、1125と指定してみてください。ぐるぐる回るはずですw
こんな感じで消え方も動き方も変えることができるので、試してみてください!
今回はブラウザの右側に実装することを想定して作ったので、左側に追加したい人は数値の正負を逆にすることでうまくいくかもしれません！
ボタン横並び

## HTML
```html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <link rel="stylesheet" href="style.css">
    <title>Document</title>
</head>
<style>
    
</style>
<body>
    
    <div class="wrap">
        <div class="content">
            <label for="temp">samplesamplesamplesample<br><br>test_test</label>
            <div class="btn01">
                <input type="btn" value="ボタン1">
                <input type="btn" value="ボタン2">
                <input type="btn" value="ボタン3">
            </div>
        </div>
    </div>
</body>
</html>
```

### CSS
```css
* {
    margin: 0;
    padding: 0;
} 

.wrap{
    height: 100vh;
    width: 100wh;
    background-color: grey;
    display: flex;
    justify-content: center;
    align-items: center;
}
.content {
    height: 250px;
    width: 400px;
    background-color: cadetblue;
    
}
.content>label{
    padding: 5px;
    box-sizing: border-box;
    border-radius: 4%;
    display: block;
    width: 100%;
    height: 100px;
    background-color: chocolate;
}
.btn01 {
    height: calc(100% - 100px);
    display: flex;
    justify-content: space-around;
    align-items: center;

}
.btn01 input{
    background-color: rgb(163, 241, 241);
    color: white;
    text-align: center;
    border: none;
    border-radius: 6px;
    display: block;
    width: 30%;
    height: 50px;
}
```
## 結果

![btn_sample01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/683909/64f74db4-0cee-a600-934f-d4f5b762e494.jpeg)
【備忘録】【Laravel8】controllerからbladeに変数を渡して表示させる

Controllerのファンクションで定義した変数を、bladeに渡して表示させる方法を
自分用に残しておきます。

# Controller

```php:
public function index () 
{
    $test1 = "テスト";
    $sample = "サンプル";

    return view('index', [
        'test_blade' => $test,
        'sample_blade' => $sample,
    ]);
}
```

return viewでbladeに変数を渡します。
第二引数でbladeに渡す変数を指定しています（左辺と右辺がある）。

### 第二引数の左辺

bladeに渡す変数の部分です。
上記の例ではtest_bladeとsample_bladeが当てはまります。

### 第二引数の右辺

関数で定義した変数です。上記の例では$testと$sampleが当てはまります。

# Blade

{{ $変数名 }}と記述します。
この変数名の部分に、controllerで渡した左辺の変数名を指定します。

$マークを忘れないようにしましょう！

```php:
<p>{{ $test_blade }}</p>
<p>{{ $sample_blade}}</p>
```

これでブラウザで確認すると表示されているはずです！


▼参考にさせていただいた記事
https://bonoponz.hatenablog.com/entry/2020/08/15/%E3%80%90laravel%E3%80%91controller%E3%81%8B%E3%82%89blade%E3%81%AB%E5%A4%89%E6%95%B0%E3%82%92%E6%B8%A1%E3%81%97%E3%81%A6%E8%A1%A8%E7%A4%BA
文字コードってなんだ（基本編）

文字コードってなんかややこしいですよね。
なので、いつでも思い出せるようにメモを残しておこうと思います。

基本編と応用編に分けて書いていく予定です。力尽きなければ。

#文字コードの概要
コンピュータ君はとっても不器用なので、**基本的には1か0かしか判別ができません**。
それは、コンピュータが**トランジスタという「電流を流す(1)か流さない(0)か」しかできないものの組み合わせで構成されている**ので、仕方ないことなのです。

コンピュータは1か0かしか判別できないので、コンピュータ上で何かを処理するときは**二進数**というものを使います。
※そのため、メモリやHDD/SSD等のは2のべき乗数単位(8GB,128GB,256GBなど)で構成されることが多いです

そうなると、**コンピュータは日本語や英語なんてものは原理的に絶対にわからない**のです。だって1か0かしか（以下略）
しかしながら、今日のパソコンやスマホはwebページやアプリ上では日本語の文字を表示できていますよね？　コンピュータは1か0かしか（以下略）なのに。

実はそれは**文字コード**という仕組みを用いて実現しているのです。

##文字コードとは？
文字コードは**文字を二進数(1と0の羅列)で表したもの**です。
ちなみに、文字に限らずに**「ある情報を二進数に変換すること」をエンコード（encode）**と言い、**その逆に二進数の情報を文字などの情報に復元することをデコード（decode）**といいます。

簡単な例になりますが、「a」という文字をエンコードすると・・・

**a → 1100001**

となります。**わけわからん数字😡**
通常、二進数は長くなってしまうので以下のように十六進数でさらに省略して表記します。

**a → 1100001 →　0x61**

上記のようにほぼ全ての文字や記号は二進数（ないしは十六進数）の数字で表現されます。
その結果、**『文字』と『文字コード』の対応表**が必要になってきます。
**この対応表には複数の種類があり、用いる対応表を間違えると文字化けが発生します。**

##文字化けの仕組み
先ほど少し触れた通り、**文字コードと文字の対応表がずれると意図しない文字が表示される『文字化け』という現象が発生**します。
たとえば以下の文字列が文字化けすると・・・

**文字化けのテスト**
↓
**譁?ｭ怜喧縺代?繝?せ繝**

急にこんな文字列出てくるとドキッとしますよね。急いでいるときはイラッ😡としますね。
これは、**「文字化けのテスト」という文字列中の各文字の対応番号が、前者と後者で用いている対応表では全く違う文字を指しているため発生します**。

上記の例は、『**UTF-8**』という対応表でエンコードした文字列を、『**Shift-JIS**』という異なる対応表でデコードした時の化け方になります。結構このパターンは多いです。

| 文字コード（十六進数） | UTF-8でのデコード | Shift-JISでのデコード|
| :--:| :--: | :--:|
| e6 96 87 e5 ad 97 e5 8c 96 e3 81 91  |  文字化け| 譁?ｭ怜喧縺|


めちゃくちゃどうでもいい話ですが、四角(□)に文字化けすパターンは日本で「豆腐」と呼ばれるようになりそれが世界に広がり、「**tofu**」というワードが世界中でも使われるようになったらしいです。（ほんとかな？）
Googleが提供している 「**Noto**」というフォントは、豆腐をなくすという意味から「**no** more **to**fu」の文字を取ったらしいです。

https://fonts.google.com/noto

#文字コードの種類
ということで、ざっくりですが文字コードで代表的なものを挙げていきます。
##JIS
JISという言葉は聞いたことがある方が多いかなと思います。
JISコードは**インターネットやEメールで日本語を表記する際に標準的に使用されている文字コード**です。
##Shift-JIS
Shift-JIS（シフトジス）は**Microsoft社が日本でコンピュータを普及させる際に策定した文字コード**です。
JISからShiftするという意味があるとかないとか。SJISと略したりもします。
外国語を表示するのが苦手とか色々弱点があるそうで、Microsoftも後述するUnicodeにShiftしているみたいです。

##ASCII
ASCIIコードは『American Standard Code for Information Interchange』の略です。いや、長。
歴史も長く、**多くの文字コードはASCIIを基にしていたりします**。

##Unicode
Unicodeはユニコード・コンソーシアムにより制定され、アルファベットや漢字、アラビア文字など世界中の文字を表現しようという目的のもと作られた文字コードです。
構成によって『**UTF-8**』とか『**UTF-16**』とかがあります。
世界中の文字コードを統一しようとしているということもあるので、基本的には**UTF-8あたりでエンコードしておけば大丈夫です**。

ただし、**JIS / Shift-JISとは互換性がないので（文字コードと文字の対応表がズレている）ので、文字化けを起こします**。

😡

※ここで紹介したもの以外にもEUCとかEBCDICとかもあります。

#次回予告
文字化けパターンから、「これはSJISからutf-8に変わったな」的なことを判別する内容を書きます。
あくまで代表的なパターンから推測する方法ですけどね。
【SAP-C01試験対策】IPv4からIPv6への移行

# はじめに
VPCとサブネットでIPv6の使用を有効にするためのステップについて、以下のドキュメントを参考に学習したので内容をまとめます。

https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/vpc-migrate-ipv6.html

# 背景
本記事はAWSソリューションアーキテクトプロフェッショナルに合格するために、[Udemyの模擬試験](https://www.udemy.com/course/aws-53225)を解いて分からなかった部分を勉強してまとめるものです。

試験対策用のため、分からない知識を補足したり試験で問われなさそうなところを省略したりしながらまとめています。
なるべくわかりやすい記載を心がけますが、最終目的は自己学習用であるということをご容赦ください。


#手順概要
1. IPv6 CIDRブロックをVPCおよびサブネットに紐づける
1. IPv6トラフィックがルーティングされるようにルートテーブルを更新する
1. セキュリティグループのルールを更新する。カスタムNACLを利用している場合はNACLも更新する。
1. インスタンスタイプをIPv6対応のものに変更する。
1. サブネットのIPv6アドレスの範囲からインスタンスに割り当てる。
1. 5.で自動的にIPアドレスが設定されていない場合は、IPv6アドレスを認識させる。

# 補足
## 2.ルートテーブルの更新について
- パブリックサブネットの場合、サブネットからインターネットゲートウェイにIPv6トラフィックを全てルーティングするルートを作成する。
- プライベートサブネットの場合、サブネットから[Egress-onlyインターネットゲートウェイ](#Egress-onlyインターネットゲートウェイ)にインターネット経由のトラフィックを全てルーティングするルートを含める。

## [Egress-onlyインターネットゲートウェイ](https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/egress-only-internet-gateway.html)

- プライベートサブネットからIPv6 経由での VPC からインターネットへの送信を可能とする。
- IPv6トラフィックのみで使用。IPv4の場合はNATゲートウェイを使う。
CSSを書いていいてなぜかエラーが出る時の原因

![スクリーンショット 2021-11-21 21.06.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2284920/16f57e1d-912e-1c25-3439-2b919af74904.png)
さっきまで普通にposition使えてたのに急にエラー。
ハマったので備忘録として・・・

![スクリーンショット 2021-11-21 21.06.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2284920/24489da5-d1ec-361d-5cc1-cce5368bb981.png)
５pxの後に;が無かっただけでした。
しかし気づけなかった笑
【Ruby のまずいコード】次の整数

# お題

整数に 1 足した整数を得るコードを書いてください
元の整数は変数 `n` に代入されているとしましょう。

# コード

## コード 1

```rb
n + 1
```

## コード 2

```rb
n.next
```

# 改善

コード 1 もコード 2 もまずくありません。ほとんどの場合，これで問題ありません。
記事タイトルに「Ruby のまずいコード」と入っているのは，このアドベントカレンダーの共通のスタイルなだけです。

コード 1 と 2 のどちらがよいかは，好みでいいと思います。
ただ，変数の値に 1 を足すのではなく，メソッドチェーンの途中で 1 を足すという場合，`next` を使うほうが書きやすいと思います。
つまり，

```rb
foo.bar.next.hoge.fuga
```

のほうが

```rb
(foo.bar + 1).hoge.fuga
```

とか

```rb
foo.bar.then{ |n| n + 1 }.hoge.fuga
```

よりもいいだろう，ということです。

## 速度を極限まで求めるなら

この「整数に 1 を足す」演算が多数回ループの中に書かれていて，しかも極限まで速度を追求したいような場合，`next` より（エイリアスの関係にある）`succ` を使って

```rb
n.succ
```

としたほうがよいかもしれません。2 倍くらい速いのです。
参考：[Ruby のエイリアスメソッドはどれを使っても同じ？ - Qiita](https://qiita.com/scivola/items/6c513cde43d46c41d38b)
【エクセルVBA】吹き出し：折れ線の終端を矢印にして追加する

#エクセルのVBAで吹き出し(折れ線)の終端を矢印にして追加するマクロです。

##その他に以下について設定しています。
　・塗りつぶしの色
　・枠線の色・太さ・種類
　・矢印の色・太さ・種類
　・テキスト(フォント・大きさ・文字色)

~~~VBScript
Sub 吹き出し追加()
    Dim tshape As Shape
    
    Set tshape = ActiveSheet.Shapes.AddShape(msoShapeLineCallout3, 50, 50, 200, 30)
    
    With tshape
        ' 塗りつぶしの色
        tshape.Fill.ForeColor.RGB = RGB(255, 229, 214)
        ' 枠線の色
        tshape.Line.ForeColor.RGB = RGB(255, 0, 0)
        ' 枠線の太さ
        tshape.Line.Weight = 3
        ' 枠線の種類
        tshape.Line.Style = msoLineSingle '一重線
'        tshape.Line.Style = msoLineThinThin '細い二重線
'        tshape.Line.Style = msoLineThinThick '細い線と太い線の二重線。上が細い線で下が太い線
'        tshape.Line.Style = msoLineThickThin '太い線と細い線の二重線。上が太い線で下が細い線
'        tshape.Line.Style = msoLineThickBetweenThin '両側を細い線ではさまれた太い線
        ' 枠線の種類
        tshape.Line.DashStyle = msoLineSolid        '実線
'        tshape.Line.DashStyle = msoLineSquareDot    '点線 (角)
'        tshape.Line.DashStyle = msoLineRoundDot     '点線 (丸)
'        tshape.Line.DashStyle = msoLineDash         '破線
'        tshape.Line.DashStyle = msoLineDashDot      '一点鎖線
'        tshape.Line.DashStyle = msoLineDashDotDot   '二点鎖線
'        tshape.Line.DashStyle = msoLineLongDash     '長破線
'        tshape.Line.DashStyle = msoLineLongDashDot  '長鎖線
        ' 線の種類
'        tshape.Line.EndArrowheadStyle  = msoArrowheadNone  '矢印なし
        tshape.Line.EndArrowheadStyle = msoArrowheadTriangle   '三角矢印
'        tshape.Line.EndArrowheadStyle = msoArrowheadOpen   '開いた矢印
'        tshape.Line.EndArrowheadStyle = msoArrowheadStealth   '鋭い矢印
'        tshape.Line.EndArrowheadStyle = msoArrowheadDiamond   'ひし型
'        tshape.Line.EndArrowheadStyle = msoArrowheadOval   '円形矢印
        ' 矢印の長さ
'        tshape.Line.EndArrowheadLength   = msoArrowheadShort  '短い
'        tshape.Line.EndArrowheadLength   = msoArrowheadLengthMedium  '普通
        tshape.Line.EndArrowheadLength = msoArrowheadLong    '長い
        ' 矢印の幅
'        tshape.Line.EndArrowheadWidth    = msoArrowheadNarrow  '狭い
'        tshape.Line.EndArrowheadWidth    = msoArrowheadWidthMedium  '普通
        tshape.Line.EndArrowheadWidth = msoArrowheadWide     '広い
        ' テキスト
        tshape.TextFrame.Characters.Font.Size = 11    'サイズ11
        tshape.TextFrame.Characters.Font.Bold = True  '太字
        tshape.TextFrame.Characters.Font.Color = RGB(0, 0, 0)   '文字色：黒
        tshape.TextFrame2.TextRange.Font.NameFarEast = "BIZ UDゴシック" 'フォント
    End With
    Set tshape = Nothing
End Sub
~~~
vscodeのHTML雛形で"en"を"ja"に変える方法

![スクリーンショット 2021-11-21 22.11.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2284920/efb31275-b9b7-19b5-5ce8-e1350ce878e8.png)
このlang="en"をjaにしたい。
まず、vsコード画面左下の歯車マークから設定を開く。
検索テキストにsettingと入れるとsettings.jsonを編集が出るのでクリック。
![スクリーンショット 2021-11-17 21.55.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2284920/e9e82834-6862-2851-a28a-e9002dd8bfca.png)
おそらく、"afterdelay"の後に,がないのでカンマを入れる。
これを入れないとエラーになる。（写真のはカンマが入っていないのでえレーになっている）そしてその後ろに、
"emmet.variables": {
     "lang": "ja"
   },
}
を追加。
![スクリーンショット 2021-11-21 22.21.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2284920/fd0bbea6-105a-a6bf-0e74-9d36b0887b4d.png)
jaになった。
vscodeでopen with live serverの規定ブラウザ変更法

まずvsコード左下の歯車マークから設定を開く
検索テキストにliveserverと入力。
![スクリーンショット 2021-11-21 20.44.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2284920/ee065494-efd6-4ef4-5b2d-2720d563a010.png)
そこで出たlive server settings をchrome debugging attachmentにする。

またはcustombrouserと検索テキストに入力してchromeを選択する。
![スクリーンショット 2021-11-21 20.45.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2284920/68e73f27-400b-296f-6f76-745d844ad3c9.png)
Arduinoの勉強　第6弾：デジタル通信方式 (2) - SPI通信方式

# #SPI通信方式
##はじめに
ハードウェアの勉強のためにArduinoを復習も兼ねて参考教材に沿って，勉強する．細かな部分の理解までして，自在に扱えるようになることが目的である．その第6弾として，「SPI通信方式」を扱う．

## SPIとは
![slide1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/951300/7538d044-03bc-9290-e589-2d1577b393ef.png)
![slide4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/951300/8fa755b0-b666-41be-f31e-25531651288d.png)

## 用語
![slide2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/951300/15e3b4b6-1199-2332-6c2b-c3bb43701d61.png)


## データの通信方法
![slide3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/951300/022cdaac-8247-ed14-7073-f88deb10b8bc.png)
![slide5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/951300/301076a0-d8ee-a67f-7936-b1a5a79d173f.png)

## 感想
前回のI$^2$C通信の仕組みと比べて，送受信の通路が分離されていることからも高速でデータのやり取りができることが直感的に理解しやすい．また，制御したいデバイス指定も明示的にプログラム側からSS端子をLOWにすることで可能ということで，ここも分かりやすいと思う．まだ通信方法について2つしか学んでいないため，一概には言えないが，用途に合わせて通信方法についても考慮しておかないと，うまくいかないことも予想されると思っている．次回も別の通信方式について学ぶということで，楽しみである．

## 参考文献
- 電子部品ごとの制御を学べる！Arduino電子工作実践講座 改訂第2版 福田和宏 著 ソーテック社
Unity で Prefab にアタッチされたコンポーネントが Find できないんですが？

と思ってましたが、以下の記事のコードをコピペすると、ちゃんと動きます。
色々書いてありますが、個人的に必要なのは１行だけでした。

https://www.zuluonezero.net/2020/02/04/unity-script-find-all-assets-and-prefabs-with-a-given-component-by-type/

---

自分は今まで、以下のようなコードを書いていました。

```csharp
MyOriginalComponent[] nodes = FindObjectsOfType<MyOriginalComponent>();
```

cf. https://docs.unity3d.com/2021.3/Documentation/ScriptReference/Object.FindObjectsOfType.html

これは、冒頭の記事の方法を採用すると以下のように書けます。

```diff
- MyOriginalComponent[] nodes = FindObjectsOfType<MyOriginalComponent>();
+ MyOriginalComponent[] nodes = FindObjectsOfType(typeof(MyOriginalComponent)) as MyOriginalComponent[];
```

オブジェクトであれば検索に引っかかるらしく、それを変換して代入するわけですね。
その発想はなかった。

ちなみに、`FindObjectsOfType()` の説明に、
> This does not return assets (such as meshes, textures or prefabs), or objects with HideFlags.DontSave set. Objects attached to inactive GameObjects are only included if inactiveObjects is set to true. Use Resources.FindObjectsOfTypeAll to avoid these limitations.

Google 翻訳：
これは、アセット (メッシュ、テクスチャ、プレハブなど) や HideFlags.DontSave が設定されたオブジェクトを返しません。非アクティブなゲームオブジェクトにアタッチされたオブジェクトは、inactiveObjects が true に設定されている場合にのみ含まれます。これらの制限を回避するには、Resources.FindObjectsOfTypeAll を使用します。

とあります。

つまり非アクティブなオブジェクトも探す場合は、以下の書き方になります。

```diff
- MyOriginalComponent[] nodes = FindObjectsOfType(typeof(MyOriginalComponent)) as MyOriginalComponent[];
+ MyOriginalComponent[] nodes = Resources.FindObjectsOfTypeAll(typeof(MyOriginalComponent)) as MyOriginalComponent[]
```

cf. https://docs.unity3d.com/2021.3/Documentation/ScriptReference/Resources.FindObjectsOfTypeAll.html

# 追記（2024-11-14）

> inactiveObjects が true に設定されている場合にのみ含まれます。

はオプションで指定できるって意味かも。

自分の場合はエディタ拡張を書くときに調べてたので、static な関数の上で書くために Resources...を使ったのかも。

あとで要調査
FlutterでTextFieldの上下が見切れる問題の修正

# 現象

WindowsアプリのTextFieldで、長い文字列を入力した場合に上下が見切れる問題が起きました。
（添付画像の左側のTextFieldは正常に表示されていますが、右側のTextFieldで問題が起きています。）
<img width="300" alt="bug" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2055383/ed227a47-f75d-f3c1-3f59-6434000b0436.png">

# デバッグ

不具合の起きるコードは、以下のシンプルな実装です。

```
SizedBox(
  height: 22,
  child: TextField(
  ),
),
```

Flutter Dev ToolでWidgetのサイズを確認すると、上下に padding のようなものがあることがわかります。
<img width="300" alt="dev" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2055383/f441319b-e567-a8fc-05b2-e424c40c69d1.png">

# 修正方法

padding と isDense を設定することで問題が解決しました。

```
SizedBox(
  height: 22,
  child: TextField(
    decoration: const InputDecoration(
      contentPadding: EdgeInsets.symmetric(vertical: 5, horizontal: 2),
      isDense: true,
    ),
  ),
),
```

<img width="300" alt="fix" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2055383/951c53e2-682c-e17a-9633-a3276f353064.png">
dat.guiはlil-guiに移行中です

## 先に結論だけ

[three.js r135](https://threejs.org/)のexamplesにて、[dat.gui](https://github.com/dataarts/dat.gui)が[lil-gui](https://lil-gui.georgealways.com/#)へ移行しました。dat.guiのメンテナンスは今後続かないと思われます。import文を書き換えるだけでほぼ移行が完了するので、dat.guiを利用中の皆さんはlil-guiに移行しましょう。

## はじめに

この記事は、dat.guiのメンテナンス状況と、移行先となるlil-guiの紹介をするための記事です。

### 想定する読者

- dat.guiを使っている
- dat.guiのメンテナンスが途絶えており困っている

### 想定する環境

- three.js r135
- dat.gui 0.7.7
- lil-gui 0.13.0

## dat.guiとは

https://github.com/dataarts/dat.gui

>A lightweight graphical user interface for changing variables in JavaScript.
>JavaScriptで変数を変更するための軽量なグラフィカルユーザーインターフェースです。

dat.guiは軽量な、動的に値を変更できるGUIコントローラーです。動作中のパラメーターを変更できるため、three.jsなどの描画系JSライブラリのサンプルページに利用されてきました。

しかし、近年更新が途絶えたままとなっています。

## lil-guiとは

https://lil-gui.georgealways.com/#

>lil-gui
>Makes a floating panel for controllers on the web. Works as a drop-in replacement for dat.gui.
>ウェブ上のコントローラ用にフローティングパネルを作成します。dat.gui.の代替品として動作します。

lil-guiは更新の途絶えたdat.guiの代替品として開発されました。

### three.jsでの採用

https://github.com/mrdoob/three.js/pull/22765

https://github.com/mrdoob/three.js/wiki/Migration-Guide#134--135

lil-guiはthree.js r135でdat.guiの代わりに採用されました。この状況を鑑みると、dat.guiのメンテナンスはもう続かないと思われます。

## マイグレーションガイド

[Migrating - lil-gui](https://lil-gui.georgealways.com/#Migrating)

>For most projects, moving from dat.gui to lil-gui should be as simple as changing the import URL. 
>ほとんどのプロジェクトでは、dat.guiからlil-guiへの移行は、インポートURLを変更するだけで簡単にできます。

マイグレーションガイドの通り、lil-guiはほとんどの場合dat.guiと互換性を保っています。そのため、ライブラリのimport URLを書き換えるだけでそのまま動作します。主な変更箇所はカラーコントローラーにありますので、カラーコントローラーを利用している方はマイグレーションガイドを確認してください。

以上、ありがとうございました。
'AmplifySignOut' is not exported from '@aws-amplify/ui-react'.を解消する

##はじめに
この記事は、AWS Amplifyハンズオンである「[AWS で React アプリケーションを構築する](https://aws.amazon.com/jp/getting-started/hands-on/build-react-app-amplify-graphql/)」を行っていた際に詰まった箇所のメモになります。

###つまづきポイント
「[モジュール 3 - AWS で React アプリケーションを構築する](https://aws.amazon.com/jp/getting-started/hands-on/build-react-app-amplify-graphql/module-three/)」の後半、
「アプリをローカルで実行する」のところで```npm start```してもうまく動かなかった。
具体的には以下のエラーが出て進めなくなってしまう。

```
./src/App.js
Attempted import error: 'AmplifySignOut' is not exported from '@aws-amplify/ui-react'.
```

###動作環境の確認
必要情報はNodeとAmplifyCLIくらいですかね？
ちなみに今見たらAmplify CLI 7.4.4が出てますね。

* Node v17.0.1
* Amplify CLI 7.4.2

## こうして解決した
試しに、node_modulesを消してインストールしなおしても同様の事象だったので@aws-amplifyかui-reactをダウングレードすることにした。
まずはパッケージのバージョン確認。

```
% npm list --depth=0
amplifyreact@0.1.0 /Users/hogehoge/workspace/Handson/amplifyreact
├── @aws-amplify/ui-react@2.0.0
├── @testing-library/jest-dom@5.15.0
├── @testing-library/react@11.2.7
├── @testing-library/user-event@12.8.3
├── aws-amplify@4.3.8
├── react-dom@17.0.2
├── react-scripts@4.0.3
├── react@17.0.2
└── web-vitals@1.1.2
```

@aws-amplify/ui-react@2.0.0
多分悪いのはこいつだ。

[@aws-amplify/ui-react  -  npm](https://www.npmjs.com/package/@aws-amplify/ui-react)でv2.0.0の前の安定版を探すとおそらくv1.2.25が良さそう。

```
% npm remove @aws-amplify/ui-react
% npm install @aws-amplify/ui-react@1.2.25
```
そして、```npm start```すると
![スクリーンショット 2021-11-21 21.26.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/894678/d1e56a55-d57d-74cd-7383-b3f9631994a6.png)
解決しましたね！


##参考
以下でも質問が出てました。
[reactjs - 'AmplifySignOut' is not exported from '@aws-amplify/ui-react' - Stack Overflow](https://stackoverflow.com/questions/70036160/amplifysignout-is-not-exported-from-aws-amplify-ui-react)
「v1.2.5にダウングレードしろ」って回答だけどどうやってversion判断してるんですかね。
npmjs.comの見方、勉強しないとな。

##追記
この時は気づかなかったのですが、よく見たら Node.js がLTS版じゃないですね。
【Android】Y乗換アプリをURLスキームから起動する

ショートカット作成アプリで遊んでいたときに困ったので備忘録です。
apk内のAndroidManifest.xmlを解析しました。

以下のURLを開くことでYahoo乗換アプリを起動することができます。
` https://transit.yahoo.co.jp/transit_app/androidToBrowser.php `

また、パラメータとして from , to を用いることで既存のショートカットと同様に、よく使う駅の情報を一発で開けます。
` https://transit.yahoo.co.jp/transit_app/androidToBrowser.php?from=東京&to=仙台`