OmniAICreator/Qiita-1.07M huggingface dataset:
マルチスレッドでHTTPリクエストしてみる




Rubyで複数のAPIリクエストをシングルスレッドで行った時とマルチスレッドで行った時でどのくらい速度に差が出るか見てみたかった。
[JSONPlaceholder](https://jsonplaceholder.typicode.com/)のサンプルエンドポイントで試してみる。
`https://jsonplaceholder.typicode.com/todos/{number}`にアクセスするとtodoが帰ってくる。

## シングルスレッドの場合

50件のtodoをループで取得してみる。

```slow.ruby
require 'uri'
require 'net/http'
require "json"

todos = []
start_time = Time.now    

(1..50).each do |n|
  uri = URI("https://jsonplaceholder.typicode.com/todos/#{n}")
  res = Net::HTTP.get_response(uri)
  todos << JSON.parse(res.body)
end

end_time = Time.now

puts JSON.pretty_generate({
  responses: todos,
  time: end_time.to_f - start_time.to_f
})
```

結果は`5.683950901031494`秒だった。


## マルチスレッドの場合

つぎにリクエストの数だけスレッドを立てて並行でリクエストしてみる。スレッドの生成は[Thread](https://docs.ruby-lang.org/ja/latest/class/Thread.html)クラスがある。レスポンスを追加する配列`todos`は、複数のスレッドから並行アクセスされる変数であるため[Mutex](https://docs.ruby-lang.org/ja/2.0.0/class/Mutex.html)で競合回避している。

```fast.ruby
require 'uri'
require 'net/http'
require "json"
mutex = Mutex.new

threads = []
todos = []
start_time = Time.now    

(1..50).each do |n|
  threads << Thread.new do
    uri = URI("https://jsonplaceholder.typicode.com/todos/#{n}")
    res = Net::HTTP.get_response(uri)
    todo = JSON.parse(res.body)

    mutex.synchronize { todos << todo }
  end
end

threads.each(&:join)

end_time = Time.now

puts JSON.pretty_generate({
  responses: todos,
  time: end_time.to_f - start_time.to_f
})
```

結果は`0.6077589988708496`秒！
rails Bootsnapを無効化する

# 起きている問題
rails sすると
bootsnapでエラーが出る
`gems/bootsnap-1.3.2/lib/bootsnap/load_path_cache/core_ext/kernel_require`

# エラー原因のBootsnapを無効化する

以下の二つの行を無効化
```ruby:Gemfile
# gem 'bootsnap', '>= 1.4.4', require: false
```

```ruby:boot.rb
# require "bootsnap/setup" # Speed up boot time by caching expensive operations.
```

その後

```
$ bundle install
```
を実行

以上で解決
```
$ rails s
```
【SQL】COUNT関数を利用するときはNULLに気をつけよう!

# はじめに
SQLを利用するときには極力NULLを使わないようにしようと言われることが多いです。
SQLではNULLのデータが入っていることで奇妙な挙動をしてしまうことがあります。
その中の一つでCOUNT関数が存在します。

COUNT関数はその名の通りで条件に合致したデータ数を取得するための関数です。
例えば、条件に合致するデータが3件ある場合は3 と返却を行います。
簡単ですね。

ただ、データ内にNULLが含まれていると、`COUNT`関数の対象によって、返される値が異なる場合があります。

具体的には以下の通りです。

- `COUNT(*)`
    - NULLのカラム**を数える**
- `COUNT(col_name)`
    - NULLのカラム**を数えない**

なかなかとややこしいですね。。。

実際に例を見てみましょう。

## 例

以下のようなテーブルを考えます。


|  col_name  | 
| ---- | 
|  NULL  |  
|  NULL  |
|  NULL  |


```sql: テーブル作成手順
CREATE TABLE COUNT_TEST (col_name INTEGER);

INSERT INTO COUNT_TEST VALUES (NULL);
INSERT INTO COUNT_TEST VALUES (NULL);
INSERT INTO COUNT_TEST VALUES (NULL);
```

### `COUNT(*)`, `COUNT(col` 実行比較

実際に両者の挙動を見てみましょう。

```sql
SELECT COUNT(*), COUNT(col_name) FROM COUNT_TEST;

+----------+-----------------+
| COUNT(*) | COUNT(col_name) |
+----------+-----------------+
|        3 |               0 |
+----------+-----------------+
1 row in set (0.00 sec)
```
実際に `COUNT(*)` では NULLのカラム**を数える**のに対して、
`COUNT(col_name)` ではNULLのカラム**を数えていない**ことがわかります。

## 活用例
COUNT関数の挙動は少しややこしいですが、この挙動を利用するとすこし便利な集計が可能になります。

会社の目標設定シートの提出日を記録している以下のようなテーブルを考えます。

```sql
CREATE TABLE employees
(employee_id   INTEGER PRIMARY KEY,
 department    VARCHAR(16) NOT NULL,
 submission_date     DATE);

INSERT INTO employees VALUES(100,  '営業部',   '2018-10-10');
INSERT INTO employees VALUES(101,  '営業部',   '2018-09-22');
INSERT INTO employees VALUES(102,  '開発部',   NULL);
INSERT INTO employees VALUES(103,  '開発部',   '2018-09-10');
INSERT INTO employees VALUES(200,  '開発部',   '2018-09-22');
INSERT INTO employees VALUES(201,  '経理部',   NULL);
INSERT INTO employees VALUES(202,  '総務部', '2018-09-25');
```

### すべて目標設定シートを提出している部署を取得する
上記のテーブルからすべて目標設定シートを提出している部署を取得する 場合を考えましょう。

employeesｍのデータですが、
提出のない社員の`submission_date`のデータはNULLとなります。

ここで、COUNT関数の挙動が役に立ちます。

すべて目標設定シートを提出している = `submission_date`カラムにデータが入っている

ということになるので、以下のようなSQLを実行することで、目的のデータを取得することができます。

```sql
SELECT 
  department
FROM
  employees 
GROUP BY
  department
HAVING 
  COUNT(*) = COUNT(submission_date);


+------------+
| department |
+------------+
| 営業部     |
| 総務部     |
+------------+
2 rows in set (0.01 sec)
```


## まとめ

- `COUNT(*)`
    - NULLのカラム**を数える**
- `COUNT(col_name)`
    - NULLのカラム**を数えない**
macで重複したファイルを整理


ローカルで大量のファイルを管理しつつ、一部をDropboxで共有、iPadでもiCloudで関連ファイルを触る、みたいなプロジェクトが一段落したのでファイル整理。
ローカルをマスターにしておけばよかったものの、杜撰な管理によりDropboxやiCloudにしかないファイルやバージョン差分が乱立。
楽してファイルを整理したい、、、。
自分でスクリプト書いてもいいかな〜とか思ったけどせっかくなら先人の知恵を、、、の備忘録。

### というわけで
`fdupes`でファイルの重複を確認します。
### インストール
`brew`で簡単インストール。
```
$ brew install fdupes
````

### 実行
単純に重複を確認。
```
$ fdupes -rnA <directory_pathA> <directory_pathB> <directory_pathC>...
/Users/user/A/220401/xxx.wav
/Users/user/dropbox/B/220401/xxx.wav
/Users/user/dropbox/B/20402/xxx_220402.wav

/Users/user/A/220403/xxx.pdf
/Users/user/Library/Mobile\ Documents/com\~apple\~CloudDocs/C/xxx.pdf
...
```
`-r`は再帰、`-n`は0バイトファイルの無視。
Macだと`.DS_Store`が大量に出てきて非常に邪魔なので`-A`で隠しファイルを無視。
ディレクトリは1個以上の指定が可能。今回だとAはローカル、BはDropbox、CはiCloud、みたいな感じ。

元は対象ディレクトリにはlogic楽曲制作ファイルも格納していたが、中の音声データにまで反応しちゃって邪魔。
よく調べもしてないが例外処理は出来なさそうなので一旦別ディレクトリに移した。

### 感想
`-d`で自動削除までやってくれるのだけど、全部残すべきな場合があったり、消すにしてもどれを残すかは個別に選びたい。
ので、結果のテキストを編集して`rm`で消した後にフォルダ整理をしていきました。スマートじゃない、、、。
各ファイルでどれ残すか選べるようにできたらなあ、てかGUIの方が楽だなあ、そういうソフトあるんだろうなあ、、。
普通にshellスクリプト書けばファイルごとに聞くように作れるだろうし、そっちのほうがいいかも。
Mac M1でビルドしたDockerイメージがEC2で起動できなかった

EC2でイメージからコンテナを起動しようとしたらできなかったので、自分用にメモ。

- 何やら警告が

>WARNING: The requested image's platform (linux/arm64/v8) does not match the detected host platform (linux/amd64)

- イメージ確認

```
docker images

REPOSITORY                                                      TAG       IMAGE ID       CREATED        SIZE
xxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/kinoko-test   tag3.0    7740c0369ffc   29 hours ago   157MB
```

- コンテナ起動（失敗）

```
docker run --name nginx-tutorial -d -p 8080:80 xxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/kinoko-test:tag3.0

WARNING: The requested image's platform (linux/arm64/v8) does not match the detected host platform (linux/amd64) and no specific platform was requested
4550cc5b7f4ba00f0fffe27a9525bce85e2c61fc5cda2f5448735d56c6c4aaa6
```

- コンテナステータスが`Exited`に

```
docker ps -a

CONTAINER ID   IMAGE                                                                  COMMAND                  CREATED         STATUS                     PORTS     NAMES
4550cc5b7f4b   xxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/kinoko-test:tag3.0   "nginx -g 'daemon of…"   2 seconds ago   Exited (1) 2 seconds ago             nginx-tutorial
```

- docker logs でログを確認

```
docker logs 4550cc5b7f4b

standard_init_linux.go:228: exec user process caused: exec format error
```

このエラーは、Docerfileをビルドした M1 Macとコンテナを実行するPCのCPUアーキテクチャが異なるために発生する模様

#### 対策

- イメージビルド時にプラットフォームを指定

```
docker build --platform amd64 -t kinoko-nginx:tag3.0 .
```

- ECRへプッシュ

```
docker push xxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/kinoko-test:3.0
```

- ダッシュボードはこんな感じ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119864/69bbe362-cdc3-9790-4351-684df98233b1.png)



# EC2側操作

- dockerインストール

```
sudo yum update -y
sudo yum -y install docker
```

- docker起動

```
sudo service docker start
```

- EC2ユーザーをグループに追加

```
sudo usermod -a -G docker ec2-user
```

- IAMロール

`AmazonEC2ContainerRegistryFullAccess`を付与

- セキュリティグループ

8080を許可

- ECRログイン

```
aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin xxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/kinoko-test
```

- イメージ取得

```
docker pull xxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/kinoko-test:3.0
```


# ローカルPCからアクセス

http://[EC2インスタンスIP]:8080/ で無事にアクセスできました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119864/88c5d39f-33ef-3382-6cff-8e27feb192da.png)
Windows10のPCにヘッドセットを差したら「このアプリを開けません」と言われた

# 事の発端
Windows10搭載のパソコンにヘッドセットのプラグを差し込んだらこんな表示が出た。

![このアプリを開けません](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67311/3467e319-47e9-1ab5-fa6c-7bb5292232d8.png)

> このアプリを開けません
> Realtek Audio Console について詳しくは、Windows ストアで調べてください。

スピーカーからだけ音が出て、ヘッドセットからまったく音が出なくなってしまった。

下記を入れ直しても効果なし。
[Realtek Audio Control \- Microsoft Store アプリ](https://apps.microsoft.com/store/detail/realtek-audio-control/9P2B8MCSVPLN?hl=ja-jp&gl=JP)

# 解決方法
Windowsアイコンを右クリック→デバイスマネージャーを選択する。

![デバイスマネージャー](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67311/3e7e842a-5312-26bc-3712-b75fca3f1417.png)

「サウンド、ビデオ、およびゲームコントローラー」から「Realtek(R) Audio」を選択して右クリック→プロパティを開く。
「ドライバー」タブから「デバイスを無効にする」を選択する。
その後、再度「デバイスを有効にする」を選択する。
これでヘッドセットから音が出るようになる。

まれにヘッドセットの左右の音量バランスがおかしい場合がある。
その場合はWindowsアイコン→設定→システム→サウンド→「出力」内の「デバイスのプロパティ」で調整できる。
SQL：データベース作成とアクセス権を持つ新規ユーザ作成

Cake-PHPや、Laravelなどの環境のために、
新規のデータベースを作成、アクセス権を持つ新規のユーザを作成する
コマンドのメモ
　newdbname : のところは、データベース名を
　newusername : のところは、ユーザ名を
　password : のところは、パスワードを入れます。

````
MariaDB [(none)]> create database newdbname;

MariaDB [(none)]> create user 'newusername'@localhost identified by 'password';

MariaDB [(none)]> grant all on newdbname.* to 'newusername'@localhost;

MariaDB [(none)]> flush privileges;
````
v6プラスで利用中のASUSルーターに外部からOpenVPNで接続してWindowsPCに接続する方法

忘備録です。

1. ルーターのVPNポート設定を変更する（ルーターのHelpに従って6112など。）
1. クライアントのOpenVPN設定を行う。
1. Windowsファイアウォールの設定をする。
+ ポート設定
    + 新しい規則
    + ポート
    + 1で設定したポートを入力
+ IP設定
    + 新しい規則
    + カスタムルール
    + これらのIPアドレス
    + このIPアドレス範囲
    + 10.8.0.1から10.8.0.254
Geo Spatialを使ってみたWith AR道場

beeです。今回Googleが出したGeo Spatialについて紹介していこうと思います！

GeoSpatialについて参考にした記事は以下の二つです。

https://www.docswell.com/s/Tks_Yoshinaga/Z86Q2K-geospatial-api

https://zenn.dev/tkada/articles/04b44474149130

# Geo Spatialとは

現在地の緯度・経度・高度を提供し、特徴点のデータを現地でスキャンすることなく、ARコンテンツを制作できるAPIです。

# 初期設定

1. GeoSpatialを触る前に[Google Cloud Platform](https://console.cloud.google.com/projectcreate?hl=ja)の登録 
2. Google ARCore Extensions for AR Foundationのインストール
3. ARCore Extensionsを選択しGeospatialのSampleがインポート

# Unityの設定
1.[この記事](https://qiita.com/shun-shun123/items/1aa646049474d0e244be)と同じように、AFfoundationを使えるようにします。
2.AR Anchor Managerのセットアップを行います。
これは、緯度・経度を設定した場所にオブジェクトを置くためです。
3.AR Earth Managerのセットアップを行います。
これは、Geo Spatial APIによる位置・姿勢推定の結果をSceneで使用できるようにします。
4.位置情報へのアクセス許可を行います。

# Geo Spatialでオブジェクトを任意の場所に置いてみた

オブジェクト生成するコードです。

```instantiate.cs

status = "Tracking";
if (displayObject == null)
{


ARGeospatialAnchor anchor
= AnchorManager.AddAnchor(Latitude, Longitude, Altitude, quaternion);

}


if (anchor != null)
{
displayObject = Instantiate(ContentPrefab, anchor.transform);
}

```

トラッキングを表示するコードです。

``` Info.cs
void ShowTrackingInfo(string status, GeospatialPose pose)
{
OutputText.text = string.Format(
"Latitude/Longitude: {0}°, {1}°¥n" +
"Horizontal Accuracy: {2}m¥n" +

"Altitude: {3}m¥n" +

"Vertical Accuracy: {4}m¥n" +

"Heading: {5}°¥n" +

"Heading Accuracy: {6} °¥n" +

"{7} ¥n"
,
pose.Latitude.ToString("F6"),
pose.Longitude.ToString("F6"),
pose.HorizontalAccuracy.ToString("F6"), 
pose.Altitude.ToString("F2"), //{3}
pose.VerticalAccuracy.ToString("F2"),
pose.Heading.ToString("F1"), //{5}
pose.HeadingAccuracy.ToString("F1"), 
03.txt
status
);
}

```

![3EAF8CD2-9ABE-4B4B-84B7-9C0B9977C03F_1_105_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1340659/39514b15-a77c-23e3-5e1c-70c8c5b8269c.jpeg)



# 今後行うこと
ひとまず、Geo Spatialを使ってみることができました。
緯度経度を取りObjectを置くことができるので、向き・距離を取得することができるので、GoogleのARオブジェクトでの地図ナビゲーションを自分でも作ってみようかなと思います。
ngrokを使用して複数ポートをhttps化する

# はじめに
WebAPIのエンドポイントを同時に2つ設定したかったので、
ngrokでトンネルを設定して複数ポートをhttpsで立ててみました。

# 事前準備
* ngrokのアカウント登録
* 設定ファイルに認証情報を追加

# 目次
[1.環境](#1-環境)
[2.トンネルの設定](#2-トンネルの設定)
[3.トンネルの起動](#3-トンネルの起動)
[4.最後に](#4-最後に)
[5.参考](#5-参考)

# 1. 環境
* macOS Monterey：12.3

# 2. トンネルの設定
設定ファイルの場所はOSによって異なり、それぞれ以下になります。
* Linux: "~/.config/ngrok/ngrok.yml"
* MacOS (Darwin): "~/Library/Application Support/ngrok/ngrok.yml"
* Windows: "%HOMEPATH%\AppData\Local\ngrok\ngrok.yml"

https://ngrok.com/docs/ngrok-agent/config#config-ngrok-location

設定を書き換える
```
version: "2"
authtoken: XXXXXXXXX

// 以下を追加
tunnels:
  httpbin:
    proto: http
    addr: 8080
  demo:
    proto: http
    addr: 9090
```
上記では「httpbin」と「demo」というトンネル名で設定しています。
トンネル名は任意のもので構いません。
# 3 トンネルの起動
トンネル名を指定して起動
```
ngrok start httpbin demo
```
全てのトンネルを起動
```
ngrok start --all
```
これで複数ポートがhttps化されます。


# 4 最後に
ngrokの読み方は「エングロック」だそうです...

# 5 参考
https://qiita.com/reona396/items/d7a7958b68d738f7c56e

https://itsec-arekore.blogspot.com/2021/02/ngrok.html

https://ngrok.com/docs/ngrok-agent/config#config-ngrok-location

https://ngrok.com/docs/ngrok-agent/config#config-ngrok-tunnel-definitions:~:text=the%20web%20UI-,Tunnel%20definitions,-The%20most%20common
FRP（Fast Reverse Proxy）

## はじめに
HPサーバの公開には、簡便にはレンタルサーバを使うのが早いが、ここではVPSサーバーを使い、ローカルサーバをリバースプロキシサーバー方式として実現しています。この方式は、FRB（Fast Reverse Proxy）方式と呼ばれますが、分かりやすくはピギーバック方式と呼んでおきます。

![FRP (1).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/210593/07a48727-cd98-bd1e-5596-7e1a3852573b.jpeg)
会議スケジュールと議事録をまとめて管理！Notionを使って速攻で作ってみた

 皆さんこんにちは！食品会社のシステム部門で働くAzarashiです。
 皆さんの会社では会議の議事録の管理はうまくいっていますか？「バラバラのフォルダに分かれてどこに行ったか分からない」「作る人によってフォーマットがバラバラ」「どの会議のかわかりづらい」等々常に見るものではないためついついおろそかになってしまう方も多いのではないでしょうか。
 今回はそんな会議の議事録を会議スケジュールとともに管理し、ついでに他のカレンダーとの連携や関係者へのメール通知なども含めた仕組みを考えました。

## 実装したい機能
* 会議のスケジュール管理
* 議事録
* 他のカレンダーサービスとの連携
* 関係者へのメール通知

## 使用ツール
* Notion：メモ作成、プロジェクト管理、タスク管理等多数の機能を備えたサービスです。Webブラウザから利用可能で、複数人に共有したり共同で編集することが可能です。

https://www.notion.so/ja-jp


* Make：様々なサービスをノーコードで連携し利用することができるサービスです。
連携できるサービスはLINE、Googleカレンダー等を含め多種多様です。

https://eu1.make.com


## 作ってみよう！
### その①：Notionで会議スケジュールと議事録管理
Notionにはこの画像にあるように多数の機能があり、用途に合わせて自分ので好きに作ることが可能です。また、あらかじめテンプレートもカテゴリごとに用意されており、それらをもとに作成することも可能です。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2668023/d50f86db-3aa3-2c59-e247-90f0e7be6b41.png" width=300>
今回は**製品化管理**カテゴリの中にある**議事録**のテンプレートをもとに目的に合った内容に変更していきます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2668023/6275364f-cc65-26e7-64a2-bcd7449dc1c6.png" width=500>
議事録のテンプレートを見てみると左下にある**新規**をクリックすると右のような画面が表示され、下方に会議種別ごとにテンプレートが用意されていることが分かります。ここで各テンプレートの右にある **・・・マーク** をクリックすることで編集が可能です。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2668023/fb56378f-010d-2ab9-287c-2e718ee2e583.png" width=500>
今回は**開催日**と**ファイルのアップロード**を追加し、スケジュール管理に加え、会議資料と議事録が同じ場所で管理されるようにしました。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2668023/d8a10bad-481a-1e9a-6420-c1cfc92585d2.png" width=300>
### その②：Makeを使って、Googleカレンダーと連携＋メール通知の実装
Makeではこのようにシナリオを作成しました。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2668023/b01fdbdd-b71f-8686-c52e-6bd33280fa19.png" width=500>
各モジュールの設定はこんな感じです。
#### Notion（Watcg Database Items）
このモジュールで入力する**Database ID**はNotionの該当ページのURLの一部（下記画像参照）になります。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2668023/abe06982-5738-5d3f-9ee4-d2171f0c4fea.png" width=500>
#### Google Carender（Create an Event）
ここでは**Event Name**、**Start Date**、**End Date**にNotionモジュールで取得した情報が入るように設定します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2668023/ed3de9cb-9c4f-2bf5-42ec-70fbfeac449e.png" width=300>
#### Microsoft 365 Email（Create and Send a Message）
ここでは**Subject**、**Body Content**、**Email Address**を入力するように設定しています。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2668023/df9a7e1e-aab1-5368-c2a7-3bff879d485b.png" width=300>

## 実際に動かしてみると。。。
![ezgif-1-b2cac0583c.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2668023/b7a6781a-73fc-c783-c087-1bb9e44d1151.gif)
 このように、Notionで作成したスケジュールがGoogleカレンダーに反映され、メールも送信することができました。

## 最後に
　今回初めてNotionを使ってみましたが、チーム内での情報共有・タスク管理等において非常に強力なツールだと感じました。今回作成した議事録以外にも各案件の進捗管理等、まだまだ多くの面で活用できそうなのでさらに検討していきたいです。
　Makeでの連携はまだまだ改善点はありますが、一通り形にすることができました。ただしGoogle Carenderモジュールの設定をする際、入力されるデータの選択によってはエラーが発生していたのでこの辺りは要研究といったところだと思いました。
　NotionもMakeも使っていて非常に楽しいツールでしたので皆さんも是非使ってみてください！
【React / Chakra-UI】CheckboxGroupでisChecked={true}をしてもチェックされていない

個人的備忘録です。

# やりたいこと
- fetchしてきた配列データを、CheckboxGroupとして、Checkboxをmapで回して、checkedに一致したデータがあれば表示時にチェック状態にしたい
- チェック済みかの情報は、query として渡す

# 環境
- React: 17.0.2
- Next: 11.1.3
- @chakra-ui/react: ^1.8.5

# 調査
- https://chakra-ui.com/docs/components/form/checkbox#checkboxgroup-props
- CheckboxGroup には isChecked props がない！
- https://github.com/chakra-ui/chakra-ui/issues/283
- CheckboxGroupの時は、Groupレベルへチェック済みの配列を渡さないといけない
```tsx
<CheckboxGroup value={checkedValueList}>
	<Checkbox value={item.value}>
</CheckboxGroup>
```
- このやり方にすると、クリックしてもチェックが外れない

# 原因
- そもそも、isChecked が props になかった

# 解決方法
- useForm の reset を使って CheckboxGroup に設定されている変数へセットする

reset について

https://qiita.com/tak001/items/3d9ecc2432c751e35726

# サンプルコード
```tsx
import { ~~~ } from '@chakra-ui/react';
import { useEffect, useState } from 'react';
import { Controller, useForm } from 'react-hook-form';
import { Foo, FormInput } from './types';

interface Props = {
  isOpen;
  onClose;
  // query
  searchedFoo?: string[];
};

export const Modal = ({ isOpen, onClose, searchedFoo }: Props) => {
  // 省略

  const [foo, setFoo] = useState<Foo[]>();

  const { handleSubmit, control, reset } = useForm<FormInputData>();

  useEffect(() => {
    reset({
      foo: searchedFoo,
    });
  }, [reset, searchedFoo]);

  const onSubmit = (data: FormInputData) => {
    // 処理
  };

  return (
    <Modal isOpen={isOpen} onClose={onClose}>
      <ModalOverlay />
      <form onSubmit={handleSubmit(onSubmit)} noValidate>
        <ModalContent>
          <ModalHeader>
            <Text>Title</Text>
          </ModalHeader>
          <ModalCloseButton />
          <ModalBody className={styles.modal__search_body}>
            // 省略
            <FormControl>
                <FormLabel>
                  Foo
                </FormLabel>
                <Controller
                  name="foo"
                  control={control}
                  render={({ field }) => (
                    <CheckboxGroup {...field}>
                      <Box>
                        {foo &&
                          foo.map((item) => (
                            <Checkbox
                              value={item.code}
                              key={item.code}
                            >
                              {item.name}
                            </Checkbox>
                          ))}
                      </Box>
                    </CheckboxGroup>
                  )}
                />
              </FormControl>
          </ModalBody>

          <ModalFooter>
            <Box>
              <MwButton type={'submit'}>Submit</MwButton>
            </Box>
          </ModalFooter>
        </ModalContent>
      </form>
    </Modal>
  );
};
```
git pullとgit fetchの差異

git pullとgit fetchの差異

pullとfetchが似た機能をするコマンドのようだが違いは以下の通りである。

なるべくfetch後、pullをしながら2つを適切に使用することが良いという。


1. git fetch

ローカルファイルには触れず、襟の変更内訳だけを確認する場合、使用

ローカルディレクトリに変更された内訳を持ってこない

​
2. git pull

ローカルファイル+羽根変更内訳の確認

ローカルディレクトリに変更された内訳を取得(変更された内容を併合)

変更された内訳と同じファイルに触れた場合、衝突発生
ARCore Geospatial APIを実装してみる


### はじめに

使用端末： Xpedia SOG01 （Android11）

### 行き詰っていること

https://zenn.dev/tkada/articles/04b44474149130

手始めに、上記の記事を参考に手を付けた際、以下のようなエラーが出てビルドできない問題が発生。
Unity 2020.3.0f1

![1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228399/7b40fd52-5b50-87e0-60f8-3c58384d110c.png)

以下のようにモジュールを加えたところ
![2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228399/4521c223-5db6-510e-88bc-ea11c3ac42e7.png)

以下のようなエラーが発生。
![3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228399/4f2ba5b3-6c69-b508-9581-fdf096085647.png)


なので、以下の記事を試してみる。

### 最終的に参考にさせて頂いた記事

https://www.docswell.com/s/Tks_Yoshinaga/Z86Q2K-geospatial-api#p1

Unity 2020.3.33f1

記事内の155 / 208まで行い、ビルドに成功したものの動作せず

![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228399/021ce9f5-8a45-7834-f1bc-5aacf2b6c7bb.png)


Xpedia SOG01 （Android11）側の問題かと考え、iphon SE2（ios）での検証を引き続き行う。
Rubyの問題を解いて知識を深める。④

# はじめに
毎日Rubyの問題を復習として5問ずつ解いています。
知識を更に深堀りするためにアウトプットします。

# Q16 検索問題
任意の文字列に"code"が、左から何文字目に出てくるかを返し、その数を出力するメソッドを作る。
出力例
count_code("codexxcode") → 1
count_code("aaacodebbb") → 4
count_code("cozexxcode") → 7
解答
```
def count_code(str)
  puts str.index("code", 0) + 1
end
```
ポイントとしてはindexメソッドになります。文字列や配列の中に指定した文字列が含まれていた場合、その文字列の開始位置を整数の値で返します。
```
str.index(検索したい文字列, [検索を開始する位置])
```
解答に+ 1を使用している理由は先頭を0から数えた数字を返すため使用。

# Q17　if,else問題 
以下の要件を満たすparrot_troubleメソッドを実装。
最近、あなたはオウムを飼いはじめました。しかし、近隣から「夜にオウムの鳴き声がうるさい」と苦情がくるようになりました。あなたはこれをシステムで解決しようと考え、次のようなプログラムの要件を考えました。

- 第一引数にオウムが鳴く場合はtrueを指定し、鳴かないfalseを指定する
- 第二引数には時間を指定する（ただし、「分」は考えないものとする）
- 20時から翌朝7時までの間にオウムが鳴いた場合は「NG」と出力する（20時と7時は含まれない）
- 上記以外の場合は「OK」と出力する

雛形
```
def parrot_trouble(talking, hour)
  # ここに条件式を実装する
end

# 呼び出し例
parrot_trouble(true, 6)
```
出力例
parrot_trouble(true, 6) → NG
parrot_trouble(true, 7) → OK
parrot_trouble(false, 6) → OK
parrot_trouble(false, 7) → OK
解答
```
def parrot_trouble(talking, hour)
  if talking && (hour < 7 || hour > 20)
    puts "NG"
  else
    puts "OK"
  end
end

# 呼び出し例
parrot_trouble(true, 6)
```

# Q18　偶数値の取得
配列にある値の中から偶数の数をカウントして出力するメソッドを作る
出力例
count_evens([2, 1, 2, 3, 4]) → 3
count_evens([2, 2, 0]) → 3
count_evens([1, 3, 5]) → 0
```
def count_evens(nums)
  count = 0
  nums.each do |num|
    if num.even? #数が偶数かどうか判断
      count += 1
    end     
  end
  puts count
end
```
ポイントはevenメソッド
Rubyがもともと用意している対象の値が偶数かどうかを判断するメソッド
```
10.even?
#=> true

5.even?
#=> false
```

# Q19 特定の数字を検知するプログラムの実装
以下の要件を満たすarray123メソッドを実装
- 配列内に1,2,3が全て入っている場合は、「True」と出力すること
- 配列内に1,2,3の全てが入っていない場合は、「False」と出力すること
出力例
array123([1, 1, 2, 3, 1]) → True
array123([1, 2, 4, ]) → False
array123([1, 1, 2, 1, 4, 3]) → True
解答
```
def array123(nums)
  if nums.include?(1) && nums.include?(2) && nums.include?(3)
    puts "True"
  else
    puts "False"
  end
end

# 呼び出し例
array123([1, 1, 2, 3, 1])
```
ポイントはinclude?メソッド
include?メソッドは指定した値が、配列中に含まれているかを判定するメソッド。
```
array = ["foo", "bar"]
puts array.include?("bar")
#=> true
puts array.include?("hoge")
#=> false
```
# Q20 if,else問題
指定された2つの真偽値によって処理が異なるプログラムを実装。
Aさんは普段土日が休みの仕事に就いており、休みの日は遅くまで寝ていたいと考えています。
そこで、Aさんのために「その日が遅くまで寝ていられるかどうか」を判断する、sleep_inメソッドを実装しましょう。
第一引数の値では「平日かどうか」、第二引数の値では「休暇かどうか」をtrueまたはfalseを用いて以下のように表します。
- 第一引数がtrue（平日である）または、第二引数がtrue（休暇である）の場合はtrueと出力する
- 第一引数がfalse（平日でない）または、第二引数がtrue（休暇である）の場合はtrueと出力する
- 第一引数がtrue（平日である）または、第二引数がfalse（休暇でない）の場合はfalseと出力する
- 第一引数がfalse（平日でない）または、第二引数がfalse（休暇でない）の場合はtrueと出力する
出力例
sleep_in(false, false) → true
sleep_in(true, false) → false
sleep_in(false, true) → true
解答
```
def sleep_in(is_weekday, is_vacation)
  if (is_weekday != true) || (is_vacation == true)
    puts true
  else
    puts false
  end
end

# 呼び出し例
sleep_in(false, false)
```

# 終わりに
まだまだ問題演習は続く。
Git flowについて

배달의 민족(우아한 형제들) 開発ブログの内容を参考に作成しました。

1.定義

プロジェクトを進めるにあたって、ブランチ管理を有効にするブランチ別の役割を区分しておいた概念を適用させたものである。

2．図式化の画像(ネット検索）
![git-flow_overall_graph.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2662676/e2246b01-1a76-195b-3e66-21eb475b540d.png)


３．BRANCHの役割

１）develop

developブランチは、名前からも分かるように開発に対するブランチである。 開発の進行はdevelopブランチで行われ、全般的なすべての開発がここで行われる。

２）feature

フィーチャーブランチはdevelopブランチから派生するブランチである。 フィーチャーブランチは、developの小単位開発だと考えればいいが、特定機能/関数などで大きさはユーザによって異なる特定機能を開発するためのブランチだと考えればよい。

すなわち、基本開発はフィーチャーブランチで進められるが、該当機能を統合してボトルネック現象の解決をするところがdevelopブランチだと考えればよい。

各機能別開発のためのフィーチャーブランチを取って機能を開発し、該当機能開発が完了すれば、developブランチに併合して他のフィーチャーとのボトルネック現象やバグなどを解決することをdevelopブランチで進めることである。

３）release

releaseブランチは、プロジェクトの開発が完了し、配布を進める過程のブランチである。 当該ブランチでは大きくリリースノートの作成、documentationの作成等と配布のための配布版の準備等を進める。

４）master/main

masterあるいはmainブランチは、配布版に対する内容が保存されるブランチである。 該当ブランチにはtagというものを付けて配布(リリース)バージョンを表示し、該当バージョンのトラッキングをすぐに進めることができるブランチだ。

５）hotfix

hotfixブランチは、masterまたはmainブランチに配布を進めたが、予期せぬバグが発生した場合、mainブランチからhotfixブランチを派生する。

hotfixという部分は、通常、セキュリティ上の深刻な脆弱性が発見されたり、ビジネスロジック的に多くの損害が発生しうるバグが発生した時、つまり今すぐ直さなければならないバグが発生した時に使用するブランチである。

（このようなバグはdevelopブランチで先に確認し、なくさなければならず、遅くともreleaseブランチで配布前にもう一度最終点検を通じてバグが発生しないようにしなければならない。)

しかし、このようなバグが絶対に発生できないと仮定できないため、もし発生した場合、hotfixブランチを通じて迅速に解決しなければならない。

６）bugfix

上記の図にはないが、gitflowシステムで存在するブランチが一つ存在する。 まさにbugfixというブランチだが、内容はhotfixとほぼ似ている。 ただしmaster/mainブランチではなくdevelopブランチから派生するという点がhotfixと異なる。

すなわち、developブランチでフィーチャーを併合して開発を進めたが、併合で誤ったコードが一緒に合わされたり、色々なフィーチャーを合わせて発生しうるバグをこのbugfixブランチを通じて解決することだ。

直ちに配布が行われたのではなく、開発過程の中で発生したバグであるため、hotfixよりは優先度が低いブランチだ。


3．使用方法

１）git flow init
gitflow管理形式で適用するというコマンドである。 最も基本設定として適用するには、-dオプションを与えればよい。
（当然、最も基本的な設定が使いやすく、branchの名前も直観的だ。 -dオプションを付けなければ、本人が直接各役割別branchの名前を付けなければならない。

git flow init-d
gitflowinitをすると、基本的にdevelopブランチにcheckoutされているだろう。 目に見えるブランチはmaster/mainとdevelop branchが存在する。

２）feature branch
各機能別開発のためにフィーチャーbranchを始めてみよう。

# #feature branchスタート
git flow feature start <name>
# #feature branchdevelopブランチに併合·削除
git flow feature finish <name>
# #feature branch遠隔リポジトリに同期化
git flow feature publish <name>

使い方の上と同じである。 name>部分に自分の好きなbranchの名前を付ければいい。 通常は当該フィーチャーで開発を進める機能についての簡単なキーワードとして名前をつける。

publishキーワードはブランチを遠隔貯蔵所にpushするのと同じ過程を進めるコマンドである。 ただし、publishを進める際には、必ず現在のプロジェクトに修正事項が残っていてはならない。

3) release branch

各機能ごとの開発が終わって配布を進めるrelease branchを作ってみよう。
# #release branch スタート
git flow release start <name(version)>
# #release branch 終了
git flow release finish <name(version)>
フィーチャーbranchと同じようにstart、フィインishで使用すればよい。 
この時、nameには通常配布を進行するリリースバージョンが明示される。

4) hotfix branch

# #hotfix branchスタート
git flow hotfix start <name(version)>
# #hotfix branch 終了
git flow hotfix finish <name(version)>
hotfixはrelease branch と同様にname部分にバージョンが明示される。 配布後に素早くバグを修正して再配布するので、新しいバージョンが生成されるのだ。

5) bugfix branch 

# #hotfix branch スタート
git flow hotfix start <name>
# #hotfix branch 終了
git flow hotfix finish <name>
bugfixは配布されたプロジェクトで発生したバグではないため、<name>の部分には希望する名前を入れればいい。 通常はフィーチャーbranchと同様に、どのようなbugを修正するかがわかるキーワードとして明示する。
【React / Next】postした後に、SWRでfetchして表示している部分を更新させたい

個人的な備忘録です。

# やりたいこと
- モーダルなどで記事をpostした後に、後ろで表示されている一覧を更新させたい

# 環境
- React: 17.0.2
- Next: 11.1.3
- @chakra-ui/react: ^1.8.5

# 解決方法
- submit ボタンを押した時に post して、そのpost後に submit メソッド内で SWR の mutate を呼ぶ
- もし props で渡す場合、 `refresh={() => mutate()}` などとして渡す

# サンプルコード
```tsx:親
const { data, error, mutate } = useSWR(~~~);

<Modal
  refresh={() => mutate()}
/>
```

```tsx:子
interface Props {
  refresh: () => Promise<HogeResponse | undefined>
}

export const Modal = ({ refresh }) => {
  const submitHandler = async () {
    // 省略 await
    refresh();
    onClose();
  }
}
```

# 参考
https://swr.vercel.app/ja/docs/mutation
【React / Next】同じ画像を選択してもonChangeが走るようにしたい

個人的な備忘録です。

# やりたいこと
- input type="file" で画像を選択した時に、特定のメソッドを走らせたい
- 画像選択時に、同じ画像を選択すると onChange が走らない
- 同じ画像を選択しても、特定のメソッドを走らせたい

# 環境
- React: 17.0.2
- Next: 11.1.3

# onClickパターン
```tsx
// 省略

const handleChangeFile = async (e: React.ChangeEvent<HTMLInputElement>) => {
  if (e.target.files && e.target.files.length > 0) {
    const file = e.target.files[0];
    setSelectedImageType(file.type);
    const resizedImage = await resizeFile(file, file.type);
    setSelectedImage(resizedImage);
    onOpen();
  }
};

<label>
	<Input
	  type="file"
	  accept={'image/jpeg, image/png, image/gif'}
	  onChange={(e) => handleChangeFile(e)}
	  onClick={(e) => {
	    (e.target as HTMLInputElement).value = '';
	  }}
	/>
</label>
```

# refパターン
```tsx
import { useRef, RefObject } from 'react';

export const Component = () => {
	inputRef: RefObject<HTMLInputElement>;
}

const handleChangeFile = (e: React.ChangeEvent<HTMLInputElement>) => {
  if (e.target.files && e.target.files.length > 0) {
    const reader = new FileReader();
    reader.onload = (e) => {
      if (!e.target || !e.target.result) {
        setSelectedImage('');
        return;
      }
      setSelectedImage(e.target.result.toString());
    };
    reader.readAsDataURL(e.target.files[0]);
	inputRef.current.value = '';
    onOpen();
  }
};

return (
  <label>
    <Input
	  ref={inputRef}
	  type="file"
	  accept={'image/jpeg, image/png, image/gif'}
	  onChange={(e) => handleChangeFile(e)}
	/>
  </label>
)
```
【React / Next】引数ありのComponent自体をpropsで渡して、子Component側で引数を渡したい

個人的な備忘録です。

# やりたいこと
- 親から Component を渡す時には、引数なしで子へ渡す
- 子Component側に props で渡ってきた component へ引数を渡す

# 環境
- React: 17.0.2
- Next: 11.1.3

# サンプルコード
## 親Component
```tsx
import { Item } from './components/item';

export const ParentComponent = () => {
  return (
    <>
      {/* Componentを（）をつけずに渡す。引数なしの場合は（）でもOK */}
      <ChildContainer component={item} />
    </>
  );
};
```

## 子Component
```tsx
interface Props {
  component: (hoge: Hoge) => ReactNode;
  // 引数をオブジェクトにしている場合
  // component: (_props: {data: Data, Foo: string}) => ReactNode;
}

export const ChildContainer = ({ component }: Props) => {
  // 省略

  return (
	<Box>
      {data && data.map((item) => component(item))}
    </Box>
  )
}
```

## Propsで渡されるComponent
```tsx
export const Item = (hoge: Hoge) => {
  // 省略

  return (
    <div>
      <p>{date.title}</p>
    </div>
  );
};
```
ローコード開発プラットフォーム(Oracle APEX)を使って家計簿?アプリを作る(その5 最終回)

本記事は「ローコード開発プラットフォーム(Oracle APEX)を使って家計簿?アプリを作る(その1)〜(その4)」(以降「その1」「その2」等と表記します)の続きで最終回です。
(想定所要時間:15分)

https://qiita.com/icywhite/items/730db15fc200b8af9483

https://qiita.com/icywhite/items/3ebbbc7fac40681f6309

https://qiita.com/icywhite/items/01dc28913139fa02d88a

https://qiita.com/icywhite/items/05f4e55c00a32485244e

# 1. チャートとファセット検索を連動させる

その1〜その4 まで進めてこられた皆様の チャートページの棒グラフは下のような状態かと思います。
![棒グラフ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409337/0fa1f1ba-436c-516d-6701-62cf76a1ce33.png)
この棒グラフの、例えば22年1月(2201)の交際費(上のグラフの赤い部分)って一体何に使ったんだっけ?と思った場合のために、そこをクリックすると 下図のように「ファセット検索」画面に遷移して 22年1月の交際費内訳が表示されるようにします。
![ファセット検索.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409337/9e47019f-1c52-7169-52df-081a3803de70.png)
棒グラフの下の円グラフでも同様に、クリックするとファセット検索に遷移して明細が表示されるようにします。
## 1-1. 棒グラフとファセット検索の連動
棒グラフとファセット検索の連動から行います。
まず「ページ2: チャート」の編集画面を開き、棒グラフ「月別支出合計」をクリックします。
その状態で右側の「シリーズ」ペインをスクロールすると「リンク」という項目が出てきますので、そこの「タイプ」をクリックし、「このアプリケーションのページにリダイレクト」を選択します。
![棒グラフ_リンク1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409337/fd1c3113-6809-b55b-cf41-fd39e6d86dba.png)
すると「ターゲット」欄に「リンクが定義されていません」と表示されますので、そこをクリックし、下図の通り
「ページ」ー> 3 (ファセット検索 右のLOVアイコンをクリックして選択できると思います)
「アイテムの設定」には (同様に右のLOVアイコンをクリックして)
    「名前」ー> P3_項目、「値」ー> 項目
    「名前」ー> P3_年月、「値」ー> 年月
「クリア/リセット」には (やはり同様に右のLOVアイコンをクリックして)
    「キャシュのクリア」ー> 3
を設定します。
![リンク・ビルダー・ターゲット.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409337/a27ba03d-a0f8-0f93-53e4-bedce8797484.png)
保存/実行してみて下さい。チャートページの棒グラフをクリックすると、ファセット検索画面に遷移すると思います。
## 1-2. 円グラフとファセット検索の連動
棒グラフと同様、
・チャートの編集ページで円グラフ(「項目別支出割合」)をクリック
・「リンク」の「タイプ」ー>「このアプリケーションのページにリダイレクト」を選択
![円グラフ_リンク1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409337/df4d9880-f654-69d3-c387-236d859f1d44.png)
下図の通り「ターゲット」の
「ページ」ー> 3
「アイテムの設定」には
「名前」ー> P3_項目、「値」ー> 項目
「クリア/リセット」の
「キャシュのクリア」ー> 3
をそれぞれ設定します。
![リンク・ビルダー・ターゲット2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409337/0b785a81-ca41-33ac-f92f-c521e1048242.png)
以上ですべて完了です。
アプリケーションとしては改善すべき点があると思いますので、色々カスタマイズいただければと思います。よろしくお願いします。
SQLでレコードをDELETEしてからINSERTする場合に気をつけること

## 軽く自己紹介
初めまして！
Webのバックエンドエンジニアを志望して勉強している佐藤をいいます！
初記事なので、良くないところがいくつかあるかもです。
その時は指摘していただけると助かります！
## 実行環境
MacBook Air (M1, 2020)
macOS Monterey 12.4
PostgreSQL 13.7

## 発生した問題
SELECT * FROM　テーブル名;でテーブルを表示する時に、idでソートされているわけではなく、削除したカラムの位置に新しいデータが挿入されることがある。
### 発生例
```SQL
-- humanテーブル
-- SELECT * FROM human;
 id |  name  | age | created_at
----+--------+-----+----------------------------------
  1 |  sato  |  17 | 2022-06-18 12:00:00.000000
  2 | tanaka |  20 | 2022-06-18 12:00:00.000000
  3 | suzuki |  19 | 2022-06-18 12:00:00.000000
  4 |  ito   |  22 | 2022-06-18 12:00:00.000000
```
id 1のレコードを削除
```SQL
-- DELETE FROM human WHERE id = 1;
 id |  name  | age | created_at
----+--------+-----+----------------------------------
  2 | tanaka |  20 | 2022-06-18 12:00:00.000000　　　　-- id 1のレコードが削除された！
  3 | suzuki |  19 | 2022-06-18 12:00:00.000000
  4 |  ito   |  22 | 2022-06-18 12:00:00.000000
```
id 5, name sakuma, age 25の新しいデータを挿入する
```SQL
-- INSERT INTO human (id, name, age) VALUES (5, sakuma, 25);
 id |  name  | age | created_at
----+--------+-----+----------------------------------
  5 | sakuma |  25 | 2022-06-19 15:00:00.000000　　　　-- 削除された一番上のカラムに挿入されている
  2 | tanaka |  20 | 2022-06-18 12:00:00.000000
  3 | suzuki |  19 | 2022-06-18 12:00:00.000000
  4 |  ito   |  22 | 2022-06-18 12:00:00.000000
```

これは、SQLの仕様で、データの保存を効率よく行うために、書き込みの順序という概念がないとのこと。
僕は勝手にデータの保存は一番下のカラムにされるものなんだなって勘違いしてた...

## 解決策
### ソートする時はORDER BYを使う
```SQL
-- SELECT * FROM human ORDER BY id
 id |  name  | age | created_at
----+--------+-----+----------------------------------
  2 | tanaka |  20 | 2022-06-18 12:00:00.000000
  3 | suzuki |  19 | 2022-06-18 12:00:00.000000
  4 |  ito   |  22 | 2022-06-18 12:00:00.000000
  5 | sakuma |  25 | 2022-06-19 15:00:00.000000
```

おお！綺麗にならんだ！
### 降順の場合は、ORDER BY カラム名 DESCを使う
```SQL
-- SELECT * FROM human ORDER BY id DESC
 id |  name  | age | created_at
----+--------+-----+----------------------------------
  5 | sakuma |  25 | 2022-06-19 15:00:00.000000
  4 |  ito   |  22 | 2022-06-18 12:00:00.000000
  3 | suzuki |  19 | 2022-06-18 12:00:00.000000
  2 | tanaka |  20 | 2022-06-18 12:00:00.000000
```
逆になった！

## まとめ
- SELECT * FROM　テーブル名;は昇順で表示されるわけではない
- データの保存に順番という概念はない
- 昇順にソートしたい時はORDER BYを使う
- 逆に降順にソートしたい時はORDER BY カラム名 DESCを使う

## 参考にしたサイト
https://oshiete.goo.ne.jp/qa/1666055.html
2005年とだいぶ古い質問なのですが、調べてもこれくらいしか見つかりませんでした...
もし他に参考になるものなどあったら教えてください！
docker/build-push-actionでcache-toにGoogle Container Registryを指定すると400 Bad Requestになるとき

こういうGithub Actionがあるとする
```yaml
name: Deploy
on: push
jobs:
  test:
    name: test
    runs-on: Ubuntu-20.04
    steps:
      - name: Checkout
        uses: actions/checkout@v3
      - uses: google-github-actions/auth@v0
        with:
          project_id: your-own-project
          credentials_json: ${{ secrets.GCP_SA_KEY }}
      - run: gcloud auth configure-docker
      - uses: docker/setup-buildx-action@v2
      - uses: docker/build-push-action@v3
        with:
          tags: your-own-project
          cache-from: type=registry,ref=asia.gcr.io/your-own-project/your-own-project-cache
          cache-to: type=registry,ref=asia.gcr.io/your-own-project/your-own-project-cache,mode=max
```

このActionを実行するとこういうエラーが出る
```
buildx failed with: error: failed to solve: error writing manifest blob: failed commit on ref "sha256:b436d0ae59aa712572ed25eabccb2fbda5c32b6f74ba03358732229cbefa0647": unexpected status: 400 Bad Request
```
## 解決策
Container RegistryではなくArtifact Registryを使え

https://github.com/docker/buildx/issues/271#issuecomment-1067766457
【React / Next】親Componentから共通Componentをchildrenで渡して、子Component側で引数を追加したい

親から渡ってきた children に props を追加したかったので、その個人的な備忘録です。

# やりたいこと
- 親Componentから 共通Component を children として 子Componentへ渡す
- 子Component側で持つべきメソッドを、子に渡ってきた時に追加したい

# 環境
- React: 17.0.2
- Next: 11.1.3
- @chakra-ui/react: ^1.8.5

# サンプルコード
## 親Component
```tsx
import { CommonForm } from 'components/commonForm';

interface Props {
  email: string;
}

export const ParentComponent = ({ email }: Props) => {
  return (
    // 省略
	{/* Container へ渡す children は 共通Component */}
    <HogeContainer email={email}>
	  {/* この時のpropsは1つだけ */}
      <CommonForm email={email} />
    </HogeContainer>
  );
};
```

## 子Component
```tsx
import { Container } from '@chakra-ui/react';
import { cloneElement, ReactElement } from 'react';

interface Props {
  email: string;
  children: ReactNode;
}

export const Container = ({ email, children }: Props) => {
  // 省略

  const changeTitle = () => {
    // 処理
  }

  // children(共通Component) へ追加したい props を定義
  const additionalProps = { onCompleted: changeTitle };

  // cloneElement で children へ props を追加する
  const clonedForm = cloneElement(children as ReactElement, {
    ...additionalProps,
  });

  return (
    <Container>
      {/* props が追加された children(共通Component) */}
      <>{clonedForm}</>
    </Container>
  );
};
```

## 共通Component（children）
```tsx
import { Box } from '@chakra-ui/react';
import { useState } from 'react';
import { Controller, useForm } from 'react-hook-form';
import { FormInputData } from './types';

interface Props {
  email: string;
  onCompleted?: () => void;
}

export const CommonForm = ({ email, onCompleted}: Props) => {
  const [isLoading, setIsLoading] = useState(false);
  const [message, setMessage] = useState('');
  const { registrationHandler } = useRegistration(role, token);

  const onSubmit = async (data: FormInputData) => {
    setIsLoading(true);
    const response = await someHandler(data).finally(() => {
      setIsLoading(false);
    });
    // 省略
    onCompleted!();
  };

  const {
    handleSubmit,
    control,
    formState: { errors },
  } = useForm<FormInputData>({
    // 省略
  });

  return (
    <form onSubmit={handleSubmit(onSubmit)} noValidate>
      // 省略
      <Box>
        <Button type={'submit'} isLoading={isLoading}>
          登録
        </Button>
      </Box>
    </form>
  );
};
```

# 参考文献
https://reactjs.org/docs/react-api.html#cloneelement

https://stackoverflow.com/questions/32370994/how-to-pass-props-to-this-props-children

https://qiita.com/NeGI1009/items/e6ad87320391c836bcf9
さくらのクラウド

## 雑感
色々不具合があるが、サポートの方にはけっこう突き放される感じ。
「詳しい××についてはご案内しておりません」みたいな。


## 東京第1ゾーン(tk1a)はルータとスイッチ合わせて1台しか作れない
「東京第1ゾーンでは新規ご利用のお客様のスイッチ作成数上限が1台に制限されています。」
スイッチは「ルーター＋スイッチ」も入るので、「ルーター＋スイッチ」を作ってしまうと、ローカルスイッチが作れない。注意。

「東京第1ゾーン」で「ルーター＋スイッチ」を作ったらスイッチを作れず、3,500円くらい損した。金返せ。

## バイナリログの容量

アプライアンスDBは外からSQLでしか手だしができない。
ゆえにSQLでバイナリログの容量も知る必要がある。

```
> SHOW BINARY LOGS;

| Log_name                   | File_size  |
+----------------------------+------------+
| db-113401185017-bin.000001 |    8590989 |
| db-113401185017-bin.000002 |        375 |
| db-113401185017-bin.000003 |        409 |
| db-113401185017-bin.000004 | 1073853934 |
(略)
| db-113401185017-bin.000036 | 1074452566 |
| db-113401185017-bin.000037 |  135178482 |
| db-113401185017-bin.000038 |        462 |
| db-113401185017-bin.000039 |        462 |
| db-113401185017-bin.000040 |        462 |
| db-113401185017-bin.000041 |        462 |
| db-113401185017-bin.000042 |        462 |
| db-113401185017-bin.000043 |        462 |
| db-113401185017-bin.000044 |        462 |
| db-113401185017-bin.000045 |        405 |
+----------------------------+------------+
```

ざっと1GBが33本(36-4+1)あるので、約33GB。

## データ容量

[こちら](https://www.wakuwakubank.com/posts/323-mysql-capacity/)を参考に。

```
MariaDB [hoge]> SELECT table_schema,
    ->        floor(SUM(data_length + index_length) / 1024 / 1024) AS ALL_MB,
    ->        floor(SUM((data_length) / 1024 / 1024)) AS DATA_MB,
    ->        floor(SUM((index_length) / 1024 / 1024)) AS INDEX_MB
    -> FROM information_schema.tables
    -> GROUP BY table_schema
    -> ORDER BY sum(data_length + index_length) DESC;
+--------------------+--------+---------+----------+
| table_schema       | ALL_MB | DATA_MB | INDEX_MB |
+--------------------+--------+---------+----------+
| hoge               |  21815 |   20951 |      863 |
| mysql              |      9 |       7 |        2 |
| information_schema |      0 |       0 |        0 |
| performance_schema |      0 |       0 |        0 |
+--------------------+--------+---------+----------+
```

約22GB。

## アプライアンスDBのバックアップ

アプライアンスNFSにバックアップが作れる。
ファイルパスは
`/mnt/sacloud-appliance/db-1134011XXXXX/backup/locked/dump-YYYYMMDD-HHIISS.sql.gz`
`1134011XXXXX` は DBのリソースID
DTOについて

1.定義
DataTransferObject、データ転送オブジェクト)はプロセス間でデータを伝達するオブジェクト

2．なぜ使用しなければならないのか？

1)DTOを使わないと、通信の回数が増加するだけでなく、ロジックが非効率的になるからだ。

2)通信を通じて値がサーバーに伝達されるとしよう。
送信された値をサーバで使用する値に変えるために、我々は直列化(serialization)を経なければならない。
ところが、原始値の場合、直列化ロジックを内部に持ちにくいので、
通信を担当するコントローラレイヤーで直列化に対するコードを持たなければならない。
このコードはコントローラごとに必要なので管理することも難しく、
また、修正しようとする時、正確にどこを修正しなければならないのか知ることも難しい。
しかし、オブジェクトに整理されたDTOの場合、直列化ロジックを内部にカプセル化して持っていることができる。
この場合、責任も明確でコードを修正することも楽だろう。

3)EntityではなくDTOを伝達することで、各レイヤー間の役割を分離することができるため
RapidAPIを利用して世界中のAPIを探してみる

# こんな人におすすめ
+ APIを利用して開発をしてみたい
+ APIが見つからない、調べても同じようなAPIばかり検索でヒットする
+ 海外のAPIを利用してみたい
+ 無料のAPIを探している

# RapidAPIとは
世界最大のAPIマーケットプレイスです。
世界中の10,000以上APIを扱っているため、自分に合ったAPIを探すことが可能です。

## APIの検索方法

以下のサイトから新規登録を行うことができます。登録は無料です。
https://api.rakuten.co.jp/ja/

登録が完了したら以下のページから早速APIを探してみます。
https://rapidapi.com/hub

今回は無料のAPIを探してみます。　
なお、RapidAPIは以下の3つの料金体系があります。

:::note info
無料API:クレジットカードやプランの登録をせずに利用可能。
フリーミアムAPI:一定量無料で利用可能なAPI。クレジットカードの登録が必要。
有料API:有料のサブスクリプションが必要なAPI。クレジットカードの登録が必要。
:::

フリーミアムは一定量無料ではあるものの、超過をすると登録したクレジットカードから引き落としが発生してしまいますのでお気を付けください。
また無料APIとフリーミアムAPIの見分けが少しわかりづらいため、例を以下に記載します。

■無料APIの場合：APIの説明ページに「FREE」と記載
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2680827/f585f469-65a8-0d02-a9c1-e08d42bbcae6.png)

■フリーミアムAPIの場合：APIの説明ページに「FREEMIUM」と記載
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2680827/330125a3-4eec-8b96-c591-d1aa1ab6b692.png)


試しに無料API・フリーミアムAPIをコレクションから検索してみます。
https://rapidapi.com/collection/list-of-free-apis
面白そうなAPIがたくさんヒットしました。(わかりやすいように日本語翻訳をしています)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2680827/7fab96f1-4a5d-439b-14c9-5376ed18ea59.png)

他にもニュース、スポーツ、株・証券、天気、翻訳、暗号通貨に関するAPIなど、
カテゴリごとにAPIが整理されているため、自分にあったAPIは見つけやすいと思います。

## APIを利用してみる

無料APIとして公開されていた、数字の雑学を教えてくれるAPIを試してみます。
https://rapidapi.com/divad12/api/numbers-1/
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2680827/c65e6270-48b4-3606-bd15-a7cf2e7ffee5.png)

今回は「Get trivia fact」を選択して、「42」という数字で検索をしてみます。
「Test Ecdpoint」を実行すると、右側のResultに「"text":"the number of kilometers in a marathon"」と表示されました。確かにマラソンの距離ですね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2680827/8ab07550-4bad-5386-61f0-c957ccd19d97.png)


ちなみにフリーミアム以上は事前にクレジットカードの登録をしないとテスト実行ができません。


# さいごに
WEBブラウザでAPIを検索をしても有名なAPIしかヒットしなかったので困っていたのですが、
RapidAPIを利用することで開発の幅が広がりそうです。
特に無料のAPIも多いので皆さまもよければお試しください。
iOSネイティブでGeospatial APIを動かす手順

Google I/O 2022にて発表されたGeospatial APIをiOSネイティブで動作させる手順です。
macOC Monterey。Unityは使いません。

公式ドキュメントはこちら。
https://developers.google.com/ar/develop/ios/geospatial/quickstart

![output.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63205/9628cb15-6280-06d4-f6ba-2f48593243e6.gif)

以下が注意ポイントです。
1. Google Cloud Platformでプロジェクト作成、API有効化、APIキー作成が必要
1. M1 MacではCocoapods実行でTerminalにRosseta設定が必要


# iOS 向け地理空間クイックスタートをなぞる

基本的に公式ドキュメントのクイックスタートを進めるだけで動きます。

## ダウンロード
https://github.com/google-ar/arcore-ios-sdk/releases

GitHubのARCore iOS SDKリポジトリから `arcore-ios-sdk-1.31.0.zip` をダウンロード。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63205/cd9952c5-8cc7-b886-2453-037ecfc8ef26.png)

## Google Cloud プロジェクト設定

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63205/1e4aec6f-f3b4-03b0-5732-88bc9bb6f13f.png)

私は仮に「GeoSpatial Sample」というプロジェクトを作成。

## 認可設定

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63205/df252de8-98b5-8bae-6b3b-3180be943bfa.png)

APIキー管理画面にて、同意画面を作成していない場合`必ず、アプリケーションに関する情報を使用して OAuth 同意画面を構成してください。` と警告が表示されます。
手元での動作確認は同意画面未作成で進行できますが、対外的に公開する場合は必ず作成してください。

## ライブラリ追加

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63205/1c62b63e-0043-71c8-6f15-8f26eb26b66e.png)

<img width="375" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63205/eb0c09d4-e9c5-2086-0474-78c5c2fa1341.png">

arcore-ios-sdk-1.31.0/Examples/GeospatialExample

のフォルダをTerminalで開き `pod install`
M1 MacではCocoapods実行の際にTerminalをRosseta対応で開く必要がありました。

`GeospatialExample.xcworkspace` を開く。

## 実行

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63205/9860eca0-e10c-892c-1ea1-1efb7e3d2048.png)

iPhone実機を接続し実行します。

周りを見渡して`ACCURACY`が5°以下位になると安定すると思います。
ADD ANCHORをタップすると円盤型のマーカーが配置されます。
精度が低い状態では配置できないので注意。
屋外で実行しないと精度出ないですね。景色の良いビル内から頑張ってみましたが無理でした。

<img width="375" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63205/cc5af522-1fe4-359d-6a17-f5abfa4fc84b.png">

<img width="375" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63205/cea91e94-a37b-0427-ea8b-678b7dce456c.png">
tigervncをUbuntu20にインストールする

Ubuntu 20 デスクトップをインストール

#tigervnc-serverのインストール
sudo apt install tigervnc-standalone-server -y
sudo apt-get install -y tigervnc-xorg-extension
sudo apt-get install -y tigervnc-common

#vncのログインパスワード設定
vncpasswd

#.Xsuthorityのモードを変更する
chmod 666 <HOME Dir>/.Xauthority 

#xstartupnを作る
vi HOMEDir/.vnc/xstartup
###########################################################
demo@intel-S2600WFT:~/.vnc$ cat xstartup 
#!/bin/sh

[ -x /etc/vnc/xstartup ] && exec /etc/vnc/xstartup
[ -r $HOME/.Xresources ] && xrdb $HOME/.Xresources
vncconfig -iconic &
dbus-launch --exit-with-session gnome-session &
###########################################################

#VNCサーバーの起動
vncserver -localhost no -geometry 1152x864 -depth 24
or
vncserver -localhost no
or
tigervncserver -xstartup /usr/bin/mate-session -geometry 1920x1080 -localhost no


#動いているVNCインスタンス確認
vncserver -list

#VNCのKill
vncserver -kill :*

#ログ確認
less Hostname\:1.log 

#ネットワーク確認
sudo apt install net-tools
netstat

#ファイヤーウォールの確認
systemctl status ufw
sudo ufw status
単一責任の原則でカレー作り

### こんにちは、Javaおじさんのシキムです。


40才目前で、プログラム工学に興味を持ったので本や記事で読んだ難しい話を
咀嚼して簡単な言葉で語りたいと思います。

-----

今回は、**単一責任の原則（Single Responsibility Principle**というものについてです。

ざっくりと、、、

１つのクラスとかメソッドにいろいろなことをさせるといろいろ大変だから、
１つのクラスとかメソッドにひとつのことをさせると楽ですということ。

詳しくは偉い人の話を読んでください。

ここでは、この原則をカレー作成装置に見立てて解説したいと思います。

では、さっそくカレー作成装置を作りましょう。
-----

**カレー作成装置**
　入れるもの：
　　　人参、ジャガイモ、玉ねぎ、肉

　作業：
　　　①人参の皮を剥く
　　　②ジャガイモの皮を剥く
　　　③玉ねぎの皮を剥く
　　　④人参を切る
　　　⑤ジャガイモを切る
　　　⑦玉ねぎを切る
　　　⑧肉を切る
　　　⑨具材を鍋に入れて煮込む
　　　⑩カレールーを入れる
　　　⑪ご飯にかける

　出てくるもの：
　　　カレー

やりましたね、カレー装置完成です。　
-----


しかし、試しに起動したところカレーは出てきませんした。

こうなると、この装置でいろいろな作業している(責任を持っている)ので修理するのは
どこが壊れているか特定する必要がありめっちゃ大変です。


では、単一責任の原則を意識して装置を新たに作りましょう。
-----

**人参下ごしらえ装置**
　入れるもの：
　　　人参

　作業：
　　　①人参の皮を剥く
　　　②人参を切る

　出てくるもの：
　　　下ごしらえ人参

**ジャガイモ下ごしらえ装置**
　入れるもの：
　　　ジャガイモ

　作業：
　　　①ジャガイモの皮を剥く
　　　②ジャガイモのを切る

　出てくるもの：
　　　下ごしらえジャガイモ

**玉ねぎ下ごしらえ装置**
　入れるもの：
　　　玉ねぎ

　作業：
　　　①玉ねぎの皮を剥く
　　　②玉ねぎを切る

　出てくるもの：
　　　下ごしらえ玉ねぎ

**肉下ごしらえ装置**
　入れるもの：
　　　肉

　作業：
　　　①肉を切る

　出てくるもの：
　　　下ごしらえ肉

**カレー作成装置**
　入れるもの：
　　　人参、ジャガイモ、玉ねぎ、肉

　作業：
　　　①人参下ごしらえ装置に、人参を入れて下ごしらえする。
　　　②ジャガイモ下ごしらえ装置に、ジャガイモを入れて下ごしらえする。
　　　③玉ねぎ下ごしらえ装置に、玉ねぎを入れて下ごしらえする。
　　　④肉下ごしらえ装置に、肉を入れて下ごしらえする。
　　　⑤具材を鍋に入れて煮込む
　　　⑥カレールーを入れる
　　　⑦ご飯にかける

　出てくるもの：
　　　カレー

真カレー装置完成です。
-----

どうでしょうか？
下ごしらえ装置を別にすることでカレーが出てこない場合にも、どれか下ごしらえに問題があるのか
煮込みに問題があるのか確認が容易になったと思います。

そしてお気づきだろうか、

***下ごしらえ装置をそのままに肉じゃが装置もシチュー装置も作れることを！！！***

そう、気付いたら使いまわしも簡単になってます。



以上が、おじさんなりの単一責任の原則の理解です。

が、話はここでは終わらない。
というかこの先が話の本題だったり。
-----

ここまでの話を聞くと装置がバラバラなるほどいいような気がしませんか？
少し本気を出して。装置を分けてみましょう

・人参の皮に刃をあてる装置
・人参の皮にあてた刃を動かす装置
・人参をまな板の上に移動する装置
・まな板の上の人参を刃をあてる装置
・まな板の上の人参の上の刃を動かしてきる装置
↑の装置のジャガイモ版も作らないと
↑の装置の玉ねぎ版もつくらないと
↑煮込みも細かい工程いろいろあるよね。。。。。
↑まて、人参の位置を特定する装置も必要じゃないのか？

***いや、いくつ装置を作る気なんだ。。。。***

装置をバラバラにすることにこだわりすぎてしまうと、このような事態となってしまいます。
こんなことになると、逆にどこが問題になったのか調べるのも大変になってきます。
それでは本末転倒ですよね？

バラバラにすることが目的なんじゃない。
----

システムごとに最適な大きさの責任をクラスやメソッドに持たせていくことが
大事なんじゃないかなと思います。
　
　
　
　
　
**カレー作りシリーズ**

https://qiita.com/sikimuOji/items/a99fdc2de406a0f42fac

   


　　

　　
番外編：ここにコードを載せなかった理由についての記事を書きましたのでよかったら合わせてどうぞ。

https://qiita.com/sikimuOji/items/2dd12ca69eb8c4451179