OmniAICreator/Qiita-1.07M huggingface dataset:
Debian Bullseye(11)での固定IP設定をsystemdでする

# はじめに
　当方、IPv4およびIPv6の両方の到達性がある状況を作りたいために、備忘録を兼ねて書いております。誤りがありましたら、コメントなどでお教えいただけると幸いです。

# Debian Bullseye初期状態
　OSインストール中にネットワーク設定をしていない状態であれば、IPv4, IPv4問わずDHCP/RAなどでアドレスが自動で設定されます。
その設定ファイルは以下のとおりです。
```
$ cat /etc/network/interfaces
# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).

source /etc/network/interfaces.d/*

# The loopback network interface
auto lo
iface lo inet loopback

# The primary network interface
allow-hotplug eth0
iface eth0 inet dhcp
```
 このファイルをいじればいいのだと思いますが、IPv6アドレスの固定方法が自分では調べられず、期待していることができそうな情報を見つけた次第です。

# systemd-networkdによるネットワーク設定
　少し前までは毛嫌いしていたsystemdですが、少しずつ慣れてきたところで、systemdでネットワーク設定ができるとのことで、それを試してみました。

## デフォルトからsystemd-networkdへの移管方法
Debian公式に情報があります。

https://wiki.debian.org/SystemdNetworkd

1. 一旦、``/etc/network/interfaces``を``/etc/network/interfaces.save``として退避させておきます。
1. systemd-networkdの有効化のため、
``# systemctl enable systemd-networkd``
をします。
1. とりあえず、DHCPでアドレスを取得できる状態の設定ファイルを作ります
```
# vi /etc/systemd/network/eth0.network
[Match]
Name=eth0

[Network]
DHCP=ipv4
```
内容は、
- [Match]セクションのNameについて、``/etc/network/interfaces``の``iface``と同じ名前を指定します。
- [Network]セクションは、IPv4アドレスをDHCPで取得するように書いています。
    - ``DHCP=yes``でIPv4/v6ともに自動取得
    - ``DHCP=ipv6``でIPv6のみ自動取得
    - ``DHCP=no``で自動設定無効

ファイルの編集が終わったら、再起動します。

## systemd-networkd管理下にあるか確認
以下のコマンドで設定が反映されているか確認できます。
```
# networkctl
IDX LINK TYPE     OPERATIONAL SETUP
  1 lo   loopback carrier     unmanaged
  2 eth0 ether    routable    configured

2 links listed.
```
eth0のみ今回は設定しているので、
- ``SETUP``が``configured``
- ``OPERATIONAL``が``routable``

になっていればsystemd-networkd管理下になりました。

## IPv4, IPv6アドレスの固定化
先ほど作成した、``eth0.network``ファイルを編集します。
```
$ cat /etc/systemd/network/eth0.network
[Match]
Name=eth0

[Network]
DHCP=ipv4
IPv6Token=::dead:beef:4:252
IPv6AcceptRA=true
```
各所、解説します。
- ``IPv6Token``
    - IPv6アドレスをRAから生成する際、eui-64の自動生成ではなく、指定するインターフェースIDとしたいときに設定します。
    - RAの情報が「ABCD:EF01:2345:6789」だった場合、IPv6アドレスは「ABCD:EF01:2345:6789:dead:beef:4:252」になります。
- ``IPv6AcceptRA``
    - RAを受け取るかどうかのbooleanです。falseの場合は、DHCPv6から取得される？不明です。

IPv4についてはルータでの固定割当にしているので、ここでは設定を変更していませんが、``Address``と``Gateway``、``DNS``を設定すると良いと思います。

# 終わりに
　systemd.networkのmanがとても充実していて、その情報を一部抜粋しました。色々な設定が可能ですので、一読すると大抵のことができると思いますので、見てみると良いと思います。
リーダブルコードを読んで

* if else文はif return を使った書き方に書き換えをする事で分かりやすくなる事もある
* 複雑な処理やコードを書く事に詰まったら、一度実装したい処理を言葉で説明したり、書き出してみる
* コードは書かないに越したことはない。
① 便利なライブラリが有れば利用する。
その為に、言語の表情ライブラリを定期的に15分みる習慣をつくる。
* 忘れても後で見たら簡単に分かるコードを書く。
AWS Cognito でLINEログインのボットリンク機能を使う

# 背景

AWS Amplify で作成するアプリに**LINEログイン**を組み込み、ボットリンク機能（LINEログイン時に公式アカウントを友だちに追加する機能）を有効にしようと思ったのですがすんなりと行きませんでした。

[ウェブアプリにLINEログインを組み込む | LINE Developers](https://developers.line.biz/ja/docs/line-login/integrate-line-login/)
[LINEログインしたときにLINE公式アカウントを友だち追加する（ボットリンク） | LINE Developers](https://developers.line.biz/ja/docs/line-login/link-a-bot/)

調査したところ、Cognito側でLINEの認可URLにパラメータを追加することができないようでした。詳しくは下記の記事を御覧ください。

[Amazon CognitoではLINEログインのボットリンク機能は…使えません！](https://zenn.dev/kecy/articles/7e8648dd2bdc3e)

この記事は、API Gateway と Lambda を利用して上記を解決する方法を記載します。

# 解決方法

さっそく解決方法についてです。方法としては、

1. Cognito の認可URLにAPI Gateway を設定
2. API Gateway からLambda を呼び出し
3. Lambda から `bot_prompt=aggressive` のクエリパラメータをつけて、LINEの認可URLにリクエスト
3. LINEの認可URLからのレスポンスをそのまま返す

となります。1, 2 については他の記事でも説明があるのでここでは省かせていただきます。

3, 4 について、今回はGolang を使用して下記のように実装しました。注意点としては、LINEの認可URLからは 302のリダイレクトが返ってくるので、それを処理せずにクライアント側に返送するようにします。また、基本的にヘッダやボディはコピーして利用するのですが、`Host`のみ宛先によって変える必要があるので、そこだけは書き換えるようにします。

```go
package main

import (
    "log"
    "net/http"
    "strings"
    "net/url"
    "github.com/aws/aws-lambda-go/events"
    "github.com/aws/aws-lambda-go/lambda"
    "io/ioutil"
)



func handler(request events.APIGatewayV2HTTPRequest) (events.APIGatewayV2HTTPResponse, error) {
    url := url.URL{
        Scheme: "https",
        Host: "access.line.me",
        Path: "oauth2/v2.1/authorize",
        // Query Paramter に bot_prompt を追加
        RawQuery: request.RawQueryString + "&bot_prompt=aggressive",
    }

    client := &http.Client{}
    // default でリダイレクトしてしまうので、無効化
    client.CheckRedirect = func(req *http.Request, via []*http.Request) error {
        return http.ErrUseLastResponse
    }

    req, err := http.NewRequest(request.RequestContext.HTTP.Method, url.String(), nil)
    if err != nil {
        log.Fatal(err.Error())
    }

    // ヘッダをコピー(Host のみ書き換える)
    for k, v := range request.Headers {
        req.Header.Add(k, v)
    }
    req.Header.Set("Host", url.Host)

    resp, err := client.Do(req)
    if err != nil {
        log.Fatal(err.Error())
    }
    defer resp.Body.Close()
    byteArray, _ := ioutil.ReadAll(resp.Body)

    // ヘッダとボディをコピーして返送
    header := map[string]string{}
    for k, v := range resp.Header {
        if k!= "Host" {
            header[k] = strings.Join(v, ",")
        }
    }
    return events.APIGatewayV2HTTPResponse{
        StatusCode: resp.StatusCode,
        Headers: header,
        Body: string(byteArray),
    }, nil
}

func main() {
    lambda.Start(handler)
}

```

# ボツ案

APIGateway の機能で他のURLにパラメータを追加/変更/削除した上でリクエストを送信する機能があったのですが、こちらはうまく動作しませんでした(設定は下記の画像参照)。Cognitoから認可URLへのリクエストにはトークンなどの複雑なパラメータが含まれているので、それが原因かと考えています。トークンを含まないようなURLであれば、きちんと追加されていたので...残念...。

![AWS APIGateway のIntegration](https://i.gyazo.com/119569f712b7e4e14d8352e00dd98eed.png)
![AWS APIGateway のParameter Mapping](https://i.gyazo.com/9ee6f3d425039cb69c90cad150f40813.png)
Salesforce Chatterグループのメール受信設定

<h2>ChatterGroupでメンションされたらメールを受信したい</h2>

<h3>実現したいこと</p3>

Chatterメンションを受けた際のメール受信設定はデフォルトでオフになっています。
この部分の設定方法について記載しています。
手動での設定も可能ですが、今回はデータローダーを使用して大人数を一括で設定します。


<h3>設定方法</p3>

１.グループメンバー情報をエクスポート
　　データローダーを使用して、グループメンバー情報をエクスポートします。
　　 ※（CollaboratinonGroupMember)を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1520342/92e8046a-e2f8-00e5-7edc-754511ab0b48.png)

２.アップデート用ファイルを作成
エクスポートしたファイルを編集し、アップデート用のファイルを作成します。
NOTIFICATIONFREQUENCYの項目がデフォルトでは「N」（受信しない）になっているので、
今回は「P」（投稿ごと)に変更します。
【変更前】
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1520342/53461fec-331c-6e7a-c4e4-580c00993b1f.png)
【変更後】
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1520342/011764a5-7719-e818-ac85-033df1f9ee4d.png)

３.作成したファイルで設定をアップロード
アップロードファイルの列は「ID」、「NOTIFICATIONFREQUENCY」のみでアップデートします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1520342/56ec96a5-9e2a-823e-cd4f-20d815a8318e.png)

設定は以上となります。

【確認】
自分が所属するグループ宛にチャターが届くと下記のようなメールを受信することができました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1520342/a9ad6aaa-726f-718b-2af7-609d2a8a3f6c.png)
Aurora Serverless v2を30分くらい触ってみた

Aurora Serverless v2がついにGAになったので早速触ってみました。
ホントにただ触ってみた感想なので役には立たないかも。

- v1からv2へのマイグレーションみたいなことができたら嬉しかったけどそんなものはなかった（しょぼり
- 非Serverlessと同じようにWriterインスタンスとReaderインスタンスが立ち上がる
    - このインスタンスがリニアにスケールしまくるんだろうな
- Aurora Serverlessのv2というよりはAuroraのインスタンスにServerlessのスケールを組み合わせた感じという印象
    - 普通にWriter←→Reader入れ換えのフェイルオーバーとかある。
- でもこれだとReaderインスタンスはさておき、Writerインスタンスは特定のAZに縛られちゃう気がする
- まぁ、既存のServerlessも内部的には1つのAZだけど、スケール時に別AZに移動するから各AZを満遍なく使うことになるのに対してv2だとフェイルオーバーしないと書き込み可能インスタンスがAZを移動しないことになるんじゃないかな
- ACU0.5～128っていう設定はDBクラスターに対して指定するので、Writerは0.5で固定、Readerは0.5～3.0、みたいな別指定はできなさそうに見える
- 現在何ACUなのかが分からないような？
nginx ssl, proxy setup

```/etc/nginx/sites-enabled/default.conf
server {
	listen 80;
	listen [::]:80;

	root /var/www/html;

	index index.html index.htm index.nginx-debian.html;
    server_name domain.com; # managed by Certbot

	location / {
		proxy_pass http://127.0.0.1:8080;
		proxy_set_header X-Real-IP $remote_addr;
		proxy_set_header Host $host;
		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
	}

    listen [::]:443 ssl ipv6only=on; # managed by Certbot
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/domain.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/domain.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
```

```
nginx -t
service nginx restart
nginx -t
service nginx restart
sudo apt install certbot python3-certbot-nginx
sudo ufw allow 'Nginx Full'
sudo ufw delete allow 'Nginx HTTP'
```

```
sudo certbot --nginx -d domain.com
```
or
```
sudo certbot --nginx -d domain.com -d www.domain.com
```

```
crobtab -e
0 12 * * * /usr/bin/certbot renew --quiet
```
https://github.com/aizwellenstan/nginx-conf
https://ibkr.com/referral/zhenwei375
MediaLive の Maintenance Window について

# はじめに
MediaLive Channel に Maintenance Window が導入されていたので、
情報を整理して共有します。


詳細はAWSドキュメントをご覧ください。

https://docs.aws.amazon.com/medialive/latest/ug/maintenance.html

大事なポイントとしては、
メンテナンス対象のChannelは、期日までに**再起動が必要**という点です。
# 確認方法
## 1. AWSコンソール
AWSコンソールのMediaLive Channelページにて、UIが変更されています。
（変更されていない場合は、順次AWSアカウントに適用されていくと思われます）

- Maintenance status
- Maintenance window

最右列に、これらの項目列が追加されています。
![Qiita_pic1_edited.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277934/9c409863-d331-fea5-0321-6929a1a4e743.png)
### Maintenance status 
・**Not required**：メンテナンス予定がない状態 もしくは メンテナンスが完了した状態。
・**Required by date** : メンテナンスが必要な状態。実際は具体的な日付が表示されると思われます。

### Maintenance window
Channelに現在設定されている Maintenance window の時間帯が表示されます。
既存のChannelには、AWSが自動で設定したメンテナンス曜日と時間帯が表示されていました。

※AWSコンソールから新規にChannelを作成してみましたが、Maintenance windowを設定する箇所は見当たらなかったので、
現状だとChannel作成後に、Maintenance windowの時間帯を変更するしかないようです。
### Maintenance windowの変更
Maintenance windowの時間帯は、手動で変更が可能です。

まず Channelを選択し、Channnel Actions から **Edit channel maintenance window** をクリックします。
すると、下記のような画面が表示されますので、曜日と開始時間を選択します。

![Qiita_pic2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277934/5b6900d8-4514-e633-00ce-495ac824f30f.png)

## 2. Channel JSON

各Channelのメンテナンス状況は Channel一覧のページだけではなく、
ChannelのJSON もしくは AWSコンソールのAdvanced detailsから確認することも可能です。

例：

```
  "maintenanceWindow": "SATURDAY_1900",
  "maintenanceStatus": "",
  "maintenance": {
    "maintenanceDay": "SATURDAY",
    "maintenanceStartTime": "19:00"
```

・ChannelのJSONを取得するには、
Channelを選択し、Channnel Actions から **Download custom template** をクリックします。

・Advanced detailsを確認するには、
MediaLive Channelの [Details]タブを選択して、最下部の **Advanced details** をクリックします。

![Qiita_pic3_edited.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277934/32baedb5-a546-14ba-7c27-7c7295377e11.png)

## 3. AWS Health Dashboard
AWS Health Dashboard からも メンテナンスが必要なChannelを確認できます。

1. AWSコンソールから AWS Health Dashboardを開きます。
1. [Other notifications]タブを選択します。
1. 「MediaLive maintenance event affecting AWS account XXXXXXXXXXXX」 というタイトルの通知を確認します（この通知に、メンテナンスが必要なChannelおよび日付が記載されるようです）。

https://docs.aws.amazon.com/medialive/latest/ug/viewing-maintenance.html
## 4. AWS CLI
現状では、AWS CLIの describe-channel および list-channels では
MaintenanceStatus や MaintenanceWindowの項目は表示されませんでした。

# おわりに

本番のライブ配信でMediaLiveを利用される際は、事前にメンテナンス有無を確認しておきましょう。
また、前もってメンテナンス時間帯をライブが行われない時間帯に変更しておくこともお勧めです。

まだ実際にメンテナンスが必要な状態を目撃していないので、今後も注視しておきたいと思います。

# 参考

https://docs.aws.amazon.com/medialive/latest/ug/maintenance.html

https://docs.aws.amazon.com/medialive/latest/ug/viewing-maintenance.html

https://docs.aws.amazon.com/medialive/latest/ug/setting-maintenance.html
[VirtualBox] Cannot register the hard disk because a hard disk already exists

仮想HDDの場所を移したときエラーになったので対処法の備忘録

## 環境
ホストOS: Windows10
VirtualBox: 6.1

## エラーメッセージ例
Cannot register the hard disk 'folder1\folder2\diskimage.vmdk' {c9050cf2-e1f1-41cd-9f0c-a60ab6e325e8} because a hard disk 'folder1\diskimage.vmdk' with UUID {c9050cf2-e1f1-41cd-9f0c-a60ab6e325e8} already exists.

終了コード : E_INVALIDARG (0x80070057)
コンポーネント: VirtualBoxWrap
インターフェース: IVirtualBox {d0a0163f-e254-4e5b-a1f2-011cf991c38d}
呼び出し先 RC: VBOX_E_OBJECT_NOT_FOUND (0x80BB0001)

## VBoxManage
* まずコマンドプロンプトでVBoxManageコマンドが使えるようにPathを通す
システムのプロパティ > 詳細設定タブ > 環境変数
変数Pathに C:\Program Files\Oracle\VirtualBox を追加

* 移動先の仮想HDDに以下のコマンドを実行すると、UUIDが再設定され利用可能になる
  ```
  vboxmanage internalcommands sethduuid <path>
  ```

* 古い仮想HDDの残骸が以下のような状態でリストに存在する場合、
  ```
  vboxmanage list hdds あるいは vboxmanage showmediuminfo <uuid>
  
  UUID:           c9050cf2-e1f1-41cd-9f0c-a60ab6e325e8
  State:          inaccessible
  ```

  以下のコマンドで消去する
  ```
  vboxmanage closemedium disk <uuid> --delete
  ```
【shell】ずっと見てられる？古(いにしえ)のジェネラティブなワンライナー(mac)

```shell
yes 'c=(╱ ╲);printf ${c[RANDOM%2]}' | bash
```

仕事に疲れたら、ターミナルに入力してみよう。

## 参考
https://10print.org/
JavaScriptで配列の要素を入れ替える方法

## はじめに
表題の件ですが、分割代入を使うと簡単です。

>分割代入 (Destructuring assignment) 構文は、配列から値を取り出して、あるいはオブジェクトからプロパティを取り出して別個の変数に代入することを可能にする JavaScript の式です。

## 処理

```javascript
let hoge = [1, 2, 3, 4];
console.log(hoge);

[hoge[0], hoge[1]] = [hoge[1], hoge[0]];
console.log(hoge);
```

実行結果

```
[1, 2, 3, 4]
[2, 1, 3, 4]
```

ちなみに文字列でも問題なく可能です。

```javascript
let hoge = ["a", "b", "c", "d"];
console.log(hoge);

[hoge[0], hoge[1]] = [hoge[1], hoge[0]];
console.log(hoge);
```

実行結果

```
['a', 'b', 'c', 'd']
['b', 'a', 'c', 'd']
```

## 参考
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment
【shell】開いているポート一覧の確認の仕方(mac)

開発をしているとすでにポートが開いていてポートが重複をしているとエラーが出るときがあります。そんなときの対処方法を紹介します。

## ポート一覧の確認方法
```shell
lsof -i :3000 # ←確認したいポート番号
```

`-i` オプションのあとに、確認したいポート番号を入力します。あとは消したいジョブの `PID` を削除すれば解決します。

```shell
kill -QUIT [PID] # [PID]の部分に消したいジョブのPIDを入力
```

## まとめ
ほぼほぼ自分用の備忘録です。ほかにも確認方法はあると思います。
PostgreSQLでCTE内の関数呼び出しが、思った回数の数倍呼ばれる場合

# はじめに

PostgreSQLのユーザー関数をCTE内で実行するクエリを書いていて、予期しないパフォーマンスの低下を発見したので説明します。
（厳密にはパフォーマンスが低下したわけではなく、データ量の増大によりSlow Queryレポートの閾値を超えてしまって報告されたということです）

# PostgreSQLのユーザー関数の揮発性

PostgreSQLのユーザー関数の揮発性にはIMMUTABLE, STABLE, VOLATILEがあり、「なんでもVOLATILE」よりは「できるならSTABLE、IMMUTABLEにすべし」と思っていました。

https://www.postgresql.jp/document/13/html/xfunc-volatility.html

# CTE(共通テーブル式)内で関数を呼び出す

あるユーザー関数の戻り値をクエリ内で複数回参照したい場合、CTE内で関数を実行して後から参照するというクエリを書くことがあると思います。

```sql
WITH cte AS (
    SELECT foo(user_id) AS user_id
      FROM users
)
SELECT user_id,
       user_id || 'def' as user_id_2
  FROM cte
;
```

# foo()が思った回数の二倍実行されている！

usersの行数が440行だった場合、foo()が実行されるのは何回でしょうか？
440回？
まず最初にCTE内のクエリが実行されメモリ上に展開された後、後続のクエリで参照されるから440回だろうと思っていましたが、ここで880回実行されるという現象に遭遇しました。

これは、PostgreSQL 12の新機能「CTEの高速化」によるもので、少なくともPostgreSQL 13はこの挙動のままでした。（14でどうなるかは未確認）。

https://www.sraoss.co.jp/tech-blog/pgsql/pg12-cte/

今回の原因は、foo()の揮発性がSTABLEだったことで、VOLATILEだと発生しません。

# 回避策

関数の揮発性をVOLATILEにするか（これは本質的ではない気がする）、CTEを使うときにMATERIALIZEするように指示します。

```sql
WITH cte AS MATERIALIZED (
    SELECT foo(user_id) AS user_id
      FROM users
)
SELECT user_id,
       user_id || 'def' as user_id_2
  FROM cte
;
```

# 実行計画

参考までに、PostgreSQL 13.6における実行計画を載せておきます。

## MATERIALIZEしない場合

```
Index Only Scan using users_index on public.users  (cost=0.27..233.47 rows=440 width=64) (actual time=0.059..1.381 rows=440 loops=1)
  Output: foo((users.user_id)::text), (foo((users.user_id)::text) || 'def'::text)
  Heap Fetches: 0
  Buffers: shared hit=5
Planning Time: 0.172 ms
Execution Time: 1.460 ms
```

## MATERIALIZEする場合

```
CTE Scan on cte  (cost=122.37..132.27 rows=440 width=64) (actual time=0.067..1.565 rows=440 loops=1)
  Output: cte.user_id, (cte.user_id || 'def'::text)
  Buffers: shared hit=5
  CTE cte
    ->  Index Only Scan using users_index on public.users  (cost=0.27..122.37 rows=440 width=32) (actual time=0.060..1.236 rows=440 loops=1)
          Output: foo((users.user_id)::text)
          Heap Fetches: 0
          Buffers: shared hit=5
Planning Time: 0.146 ms
Execution Time: 1.674 ms
```

# ユーザー関数のコスト指定は無力（かも）

PostgreSQLが実行計画を作成するにあたり、関数のCOSTも参照すると思いますが、今回のケースではCOST 1000000にしても揮発性がSTABLEだと自動的にはMATERIALIZEしてくれませんでした。

## COST 1000000にしたときの実行計画

```
Index Only Scan using users_index on public.users  (cost=0.27..2200013.47 rows=440 width=64) (actual time=0.071..1.775 rows=440 loops=1)
  Output: foo((users.user_id)::text), (foo((users.user_id)::text) || 'def'::text)
  Heap Fetches: 0
  Buffers: shared hit=5
Planning Time: 0.151 ms
Execution Time: 1.869 ms
```

# おまけ

ユーザー関数が何回呼ばれているかは、以下のクエリで確認できます。
※ postgresql.confでtrack_functionsにplかallを指定する必要があります。

```sql
SELECT * FROM pg_stat_user_functions;
```

以上です。
iOS ReactNativeでOpenUrlを使って設定アプリの好きな画面へ遷移させる方法

# 結論：rootが必要ない

OpenUrlで色んなアプリを呼び出せる。
```
line://
fb://
```
など

iOSの設定アプリを呼び出す方法でハマったのでメモとして残します。

ReactNativeのLinkingで呼び出す場合
```　
export const openSetting = () => {
  Linking.openURL('App-Prefs:APPLE_ACCOUNT&path=PASSWORD_AND_SECURITY').catch(
    err => Alert.alert('URLを開けませんでした。', err),
  );
};
openSetting（）
```

一度AppleSignInしたらFullNameが取れなくなるのでユーザーに解除してもう一度やって貰いたかったから調べました。

参考URL：
https://blog.thetheorier.com/entry/ios15-settings-urlscheme
https://github.com/FifiTheBulldog/ios-settings-urls/blob/master/settings-urls.md
上記はすべて　`App-Prefs:root=` となっているが `App-Prefs:`　で良い！みたい。ま、OSが上がるたびにかわりそうですはあります。えぇ
Laravel MVCの仕組みとWEB3層構造

## MVCとは
* アプリケーションを実装するためのデザインパターン
* アプリケーションの役割を分ける

### Model(データ処理)
データベースへのアクセス(登録・更新・削除・検索の実行)やデータの加工等々、
データにまつわる処理全般を請け負う。

### View(ブラウザに表示される画面を作る)
Controllerから取得したデータをテンプレートを使ってブラウザに出力する。

### Controller
画面からの入力値をModel層の処理機能へデータとして引き渡したり、
データベースから取得したデータを画面へ表示するためにView層へ渡したりと
ViewとModelの間を取り持つ。


## WEB3層構造
* ブラウザ(クライアント)
* プレゼンテーション層(WEBサーバ)
* アプリケーション層(APサーバ)
* データベース層(DBサーバ)

クライアントからの処理をするサーバがプレゼンテーション層・アプリケーション層・データベース層の3層から構成されているため、WEB3層構造という。

#### クライアント
利用者からの入力を受け付け、結果を出力する。

#### プレゼンテーション層(WEBサーバ)
クライアントとシステムをやりとりをコントロールする。
例)
・Apache
・Nginx

#### アプリケーション層(APサーバ)
システムの中核を担う処理を実行する。
例)
・Puma
・Unicorn

#### データベース層(DBサーバ)
データベースとの連携
例)
・MySQL
・PostgreSQL
DobotLab ティーチング＆プレイバックの使い方

# 準備
1. DobotLabへアクセスする
    https://dobotlab.dobot.cc/#/
1. 「Teaching and Playback Lab」を選択する
    ![01_edit.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145092/14148784-854c-0ce5-f9a2-66a2bdfbcd7e.jpeg)
1. 「Download DobotLink」を選択して、セットアップファイルをダウンロードする
    ![02_edit.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145092/bf533781-0d88-40bf-5a0a-adf33ebe9a19.jpeg)
1. ダウンロードしたexeファイルを実行し、「DobotLink」をインストールする

# 接続
1. DOBOT Magicianの電源を入れ、PCとUSBケーブルで接続する
1. 画面右上の「connect」をクリックし、DOBOTと接続する
    ![09_edit.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145092/f6fb11d7-6b81-95fa-5587-0dae18b93390.jpeg)

# 使い方
![10.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145092/d076290d-cabb-3a4a-2077-ebb4861ed4e9.jpeg)

画面右側にある「Command panel」から動作を追加します。
または、DOBOTのフォアアームにあるボタンを押しながら動かしたい座標へ移動させると自動的に追加されます。
CSSのみでモーダルウィンドウを作成


参考記事
https://ecmemo.net/modal-window

ビューページ
```
<a href="#modal-01">
        <div class="site-header">
            <div class="side-bar box-center">
                <img src="/img/side_registration.svg">
            </div>
        </div>
    </a>
    <div class="modal-wrapper-01" id="modal-01">
        <a href="#!" class="modal-overlay-01"></a>
        <div class="modal-window-01">
            <div class="modal-content-01">
                <img src="https://picsum.photos/id/1080/600" width="100%">
            </div>
            <a href="#!" class="modal-close-01">×</a>
        </div>
    </div>
```
css
```
/* Modal */

.site-header{
    position: fixed;
    top: 0;
    right:0px;
    z-index:20;
  }

.side-bar {
    position: relative;
    width: 100%;
    min-height: 100vh;
    background-color: #F7F6F1;
    padding-left: 1rem;
    padding-right: 1rem;
  }
  
.modal-wrapper-01 {
    z-index: 999;
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    padding: 60px 10px;
    text-align: center
  }
  
  .modal-wrapper-01:not(:target) {
    opacity: 0;
    visibility: hidden;
    transition: opacity .3s, visibility .3s;
  }
  
  .modal-wrapper-01:target {
    opacity: 1;
    visibility: visible;
    transition: opacity .4s, visibility .4s;
  }
  
  .modal-wrapper-01::after {
    display: inline-block;
    height: 100%;
    margin-left: -.05em;
    vertical-align: middle;
    content: ""
  }
  
  .modal-wrapper-01 .modal-window-01 {
    box-sizing: border-box;
    display: inline-block;
    z-index: 20;
    position: relative;
    width: 70%;
    max-width: 700px;
    padding: 3rem 3rem 3rem;
    border-radius: 2px;
    background: #fff;
    vertical-align: middle
  }
  
  .modal-wrapper-01 .modal-window-01 .modal-content-01 {
    max-height: 80vh;
    overflow-y: auto;
  }
  
  .modal-overlay-01 {
    z-index: 10;
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    background: rgba(0, 0, 0, .8)
  }
  
  .modal-wrapper-01 .modal-close-01 {
    z-index: 20;
    position: absolute;
    top: 0;
    right: 0;
    width: 35px;
    color: #95979c !important;
    text-align: center;
    text-decoration: none;
    text-indent: 0
  }
  
  .modal-wrapper-01 .modal-close-01:hover {
    color: #2b2e38 !important
  }
```
地獄のフィボナッチ数列@Python

誰か助けてください．

# できごと

とあるプログラミング勉強用の問題を出すサイトにて（サイト名は言うと問題のネタバレになりかねないので秘密だよ）フィボナッチ数列の実装を求められたよ

# 序章

ぼく「これ簡単やな！＾＾」

```Python:fib1
def fib(seq):
    if seq == 0:
        return 0
    if seq == 1:
        return 1
    return fib(seq-1) + fib(seq-2) 
```

エラー発生
ぼく「どこがおかしいんだ？」

テスト内容
`
fib(1000) fib(-36)
`
ぼく「??????????????????????????????」

# ちょっと調べた

ワイ「[負数への拡張](https://ja.wikipedia.org/wiki/%E3%83%95%E3%82%A3%E3%83%9C%E3%83%8A%E3%83%83%E3%83%81%E6%95%B0#%E8%B2%A0%E6%95%B0%E7%95%AA%E3%81%B8%E3%81%AE%E6%8B%A1%E5%BC%B5)はこうやるのか，[LRUキャッシュ](https://zenn.dev/imaimai/articles/c7df51d75706d0321d21)か，これ使えばいけそうやな」

```Python:fib2
from functools import lru_cache

@lru_cache(maxsize=10000000)
def fib(seq):
    if seq == 0:
        return 0
    if seq == 1:
        return 1
    tmp = (fib(abs(seq)-1) + fib(abs(seq)-2)) 
    
    if seq < -1:
        tmp *= (-1)**(abs(seq)+1)
    return tmp
```
エラー発生：`RecursionError: maximum recursion depth exceeded`
ぼく「ん，何これ？」
問題文を確認したら，
問題文「nが2000000まで扱えるようなアルゴリズムを書きなさい。」

ぼく「…馬鹿じゃねえの？」

# 迷走

`import sys` からの`sys.setrecursionlimit()`を調整したら`segmentation fault`を起こしたのでこれではダメそう
```python:korehadame
from functools import lru_cache
import sys

sys.setrecursionlimit(50000)


@lru_cache(maxsize=10000000)
def fib(seq):
    if seq == 0:
        return 0
    if seq == 1:
        return 1
    tmp = fib(abs(seq) - 1) + fib(abs(seq) - 2)

    if seq < -1:
        tmp *= (-1) ** (abs(seq) + 1)
    return tmp


fib(80000)
```
手元での出力結果
```
Segmentation fault 
```

# 光明
再帰的処理には[無理があろうと思われます](https://www.kunaicho.go.jp/page/okotoba/detail/12)と感じたので，ループ処理の実装例に切り替える

```python:Kwangmyong
from functools import lru_cache


@lru_cache(maxsize=10000000)
def fib(seq):
    a, b = 0, 1
    if seq == 0:
        return a
    elif abs(seq) == 1:
        result = b
    else:
        for j in range(abs(seq) - 1):
            a, b = b, a + b
        result = b

    if seq > 0:
        return result
    else:
        return result * (-1) ** (abs(seq) + 1)
```
手元では動作
ぼく「お，これいけるんとちゃうか？」
提出結果:`Execution Timed Out (12000 ms)`
ぼく「」

# 解決
O(n)のアルゴリズムでは無理そうなのでO(logn)のアルゴリズムを~~考えたがぼくの低レベルな脳みそでは考えつかなかったので~~調べる．

するとこのような法則があるらしい．（[参考サイト](https://www.geeksforgeeks.org/program-for-nth-fibonacci-number/)）


>Method 6 (O(Log n) Time)
もう一つ、フィボナッチ数nをO(Log n)時間で求めることができる面白い漸化式を紹介します。 
nが偶数の場合，`k = n/2`として，`Fib(n) = [2*Fib(k-1) + Fib(k)]*Fib(k)`
nが奇数の場合，`k = (n + 1)/2`として，`F(n) = F(k)*F(k) + F(k-1)*F(k-1)`

これを実装してみる

```Python:Final
from functools import lru_cache


@lru_cache(maxsize=10000000)
def fib(seq):
    a, b = 0, 1
    if seq == 0:
        return a
    elif abs(seq) == 1:
        result = b
    else:
        if abs(seq) % 2 == 0:
            k = abs(seq) / 2
            result = ((2 * fib(k - 1)) + fib(k)) * fib(k)
        else:
            k = (abs(seq) + 1) / 2
            result = fib(k) * fib(k) + fib(k - 1) * fib(k - 1)

    if seq > 0:
        return result
    else:
        return result * (-1) ** (abs(seq) + 1)
```

無事にテスト突破！やったぜ！

# 〆
アルゴリズムのオーダーって大事，ほんとに痛感した…
テキストエディタの違い（シンタックスハイライト）

テキストエディタでコーディングしていて、気になったことがあります。

# シンタックスハイライト
コードを書くときにどこまでシンタックスハイライトがつくかエディタによって違いがあるようです。
例１
```php_sample1.php
<?php
class Sampleclass{
}
```
上のコードでSampleclassが緑色にハイライトされていますが、エディタによってはSampleclassがハイライトされないものもあります。
VScodeやgithub・AWSはハイライトされますが、paiza ioはハイライトされません。

例2
```php_sample2.php
<?php
public function(){
}
```
上のコードは共通してハイライトされます。

# 違いが何なのか
その違いはなんなのかわかりませんが、コードは動くので問題はありませんが。

みなさんは気になったことはありませんか？
Laravel で定数を呼び出しました


const.php を置きました。

# const.php を置く
定数を書き込むファイルを用意します。
```
laravel/config/const.php 
```

# 定数定義
定数を定義します。

```php:const.php
return [
    'HOGE' => [
        'APP_ID' => 'xxxxpiyopiyo',
    ],
];

```

# 呼び出し

```php
config('const.HOGE.APP_ID');
```

# まとめ
Laravel で定数を呼び出しました。
ただもっといいやり方もあるとかでだれか教えて下さい(☝ ՞ਊ ՞)
Windows11 に Docker を簡単に導入する

# はじめに

Windows に Docker を入れるには過去色々試行錯誤がありました。[Windows10 でDocker Engineを動かす方法](https://qiita.com/ryosukeImai/items/be2b777af94c43c8604e)
Windows 11 では簡略化され、いくつかのツールを利用すれば、コマンドひとつで導入できます。

## 導入のながれ

1. Windows 用パッケージ管理ツール　[Windows Package Manager](https://docs.microsoft.com/ja-jp/windows/package-manager/)　(以降. winget)のインストール　※1
1. winget を利用してDocker Desktop をインストール

※1. 現在の Windows11 では[バンドル](https://docs.microsoft.com/ja-jp/windows/package-manager/winget/)されているみたいです。過去バージョンの方は windows Update か手動で入れてみてください。

## 環境

- windows 11 21H2

## winget のインストール

Microsoftストアにて 「app installer」を検索して、インストールしてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207696/465bd903-a564-8bf8-5142-fb54654c1e5a.png)

インストールが完了したら、Windows ターミナルを管理者で起動し、以下コマンドでインストールの確認してください。

```bach
winget -v
```
以下のようにバージョンが表示されれば OK です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207696/e160621d-4087-9c29-9321-36ec164c1065.png)



## Docker Desktop のインストール

以下コマンドでインストールができます。これで終わりです。
```bash
winget install Docker.DockerDesktop
```
※winget インストールするものを調べるためには、以下コマンドで検索することができます。

```bash
winget search docker
```
IDがインストールコマンドの名称となります。


## インストール確認

以下バージョンでインストール確認を行います。

```bash
docker -v
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207696/94e47eb6-2c01-91b2-9446-08e981ab301c.png)

これで終わりです。
JavaScript不要！CSSだけでハンバーガーメニューを実装する方法

参考記事
https://www.asobou.co.jp/blog/web/css-menu

ビューページ
```
<header class="phone_area">
  <div class="header_phone">
    <div class="hamburger-menu">
      <input type="checkbox" id="menu-btn-check">
      <label for="menu-btn-check" class="btn menu-btn"><span></span></label>
      <!--ここからメニュー-->
      <div class="menu-content">
        <ul>
          <li>
            <a href="#">ログイン</a>
          </li>
          <li>
            <a href="#">会員登録</a>
          </li>
        </ul>
      </div>
      <!--ここまでメニュー-->
    </div>
  </div>
</header>
```

css
```
/* ヘッダーphoneバージョン */
input:checked + label {
    color: #9A7B4E;
    border-color: #9A7B4E;
    background-image:url("/img/x.svg");
    background-repeat: no-repeat;
    background-position: center;
    box-shadow: none;
  }

.menu-btn {
    /* position: fixed; */
    /* top: .75rem;
    right: 1rem; */
    display: flex;
    height: 45px;
    width: 45px;
    justify-content: center;
    align-items: center;
    z-index: 90;
    background-image:url("/img/MENU.svg");
    background-repeat: no-repeat;
    background-position: center;
    color: #9A7B4E;
    border-color: #9A7B4E;
}
.menu-content {
    width: 100%;
    height: 100%;
    position: fixed;
    top: 0;
    left: 0;
    z-index: 80;
    background-color: #F7F6F1;
}
.menu-content ul {
    padding: 5rem 1rem;
}
.menu-content ul li {
    border-bottom: solid 2px #fff;
    list-style: none;
}
.menu-content ul li a {
    display: block;
    width: 100%;
    font-size: 15px;
    box-sizing: border-box;
    color:#222;
    text-decoration: none;
    padding: 15px 15px 15px 0;
    position: relative;
}
.menu-content ul li a::before {
    content: "";
    width: 7px;
    height: 7px;
    border-top: solid 1px #222;
    border-right: solid 1px #222;
    transform: rotate(45deg);
    position: absolute;
    right: 11px;
    top: 25px;
}
#menu-btn-check {
    display: none;
}

/* ボタンを押したらメニューが出てくるように */
.menu-content {
    width: 100%;
    height: 100%;
    position: fixed;
    top: 0;
    left: 100%;/*leftの値を変更してメニューを画面外へ*/
    z-index: 80;
    background-color: #F7F6F1;
    transition: all 0.5s;/*アニメーション設定*/
}

#menu-btn-check:checked ~ .menu-content {
    left: 0;/*メニューを画面内へ*/
}

.header_phone
{
    position: relative;

    display: flex;

    padding: .75rem 1rem; 

    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
}
```
cscの作法 その133

# 概要
cscの作法、調べてみた。
ntdll.dll使ってみた。

# 参考にしたページ

https://qiita.com/Yusuke_Pipipi/items/28cbfdcc06f378a26860

# サンプルコード


```
using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace StealthThreadPrj
{
	public partial class Form1 : Form {
		enum NTSTATUS {
			STATUS_SUCCESS = 0,
			STATUS_INFO_LENGTH_MISMATCH = 4,
		}
		enum THREADINFOCLASS {
			ThreadHideFromDebugger = 0x11,
		}
		[DllImport("ntdll.dll")]
		public static extern ulong NtSetInformationThread(IntPtr ThreadHandle, int ThreadInformationClass, IntPtr ThreadInformation, ulong ThreadInformationLength);
		[DllImport("kernel32.dll")]
		public static extern IntPtr GetCurrentThread();
		public Form1() {
			ulong status;
			IntPtr curThread = GetCurrentThread();
			status = NtSetInformationThread(curThread, (int) THREADINFOCLASS.ThreadHideFromDebugger, IntPtr.Zero, 0);
			if (status == (int) NTSTATUS.STATUS_SUCCESS)
			{
				Console.WriteLine("Stealth Thread Success : 0x{0:x}", status);
			}
			else
			{
				Console.WriteLine("Stealth Thread Fail : 0x{0:x}", status);
			}
			for (int i = 0; i < 3; i++)
			{
				Console.WriteLine(i);
			}
			Timer timer1 = new Timer();
			timer1.Interval = 1000;
			timer1.Tick += new EventHandler(timer1_Tick);
			timer1.Start();
		}
		private void timer1_Tick(object sender, EventArgs e) {
			Console.WriteLine("Hello");
		}
		[STAThread]
		public static void Main() {
			Application.Run(new Form1());
		}
	}
}





```

以上。
cscの作法 その132

# 概要
cscの作法、調べてみた。
WtsApi32.dll使ってみた。

# 参考にしたページ

https://qiita.com/Yusuke_Pipipi/items/5c561b81e861e286e0c5

# 

```
using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace LockDetect
{
	public partial class Form1 : Form {
		[DllImport("WtsApi32.dll")]
		private static extern bool WTSRegisterSessionNotification(IntPtr hWnd, [MarshalAs(UnmanagedType.U4)] int dwFlags);
		[DllImport("WtsApi32.dll")]
		private static extern bool WTSUnRegisterSessionNotification(IntPtr hWnd);
		const int NOTIFY_FOR_THIS_SESSION = 0;
		const int WM_WTSSESSION_CHANGE = 0x2b1;
		const int WTS_SESSION_LOCK = 0x7;
		const int WTS_SESSION_UNLOCK = 0x8;
		const int WTS_SESSION_REMOTE_CONTROL = 0x9;
		public Form1() {
			WTSRegisterSessionNotification(this.Handle, NOTIFY_FOR_THIS_SESSION);
		}
		protected override void WndProc(ref Message m) {
			if (m.Msg == WM_WTSSESSION_CHANGE)
			{
				int value = m.WParam.ToInt32();
				switch (value)
				{
				case WTS_SESSION_LOCK:
					Console.WriteLine("PCがロックされました");
				break;
				case WTS_SESSION_UNLOCK:
					Console.WriteLine("PCのロックが解除されました");
				break;
				case WTS_SESSION_REMOTE_CONTROL:
					Console.WriteLine("PCがRDP制御されました");
				break;
				default:
				break;
				}
			}
			base.WndProc(ref m);
		}
		[STAThread]
		public static void Main() {
			Application.Run(new Form1());
		}
	}
}





```

以上。
[Swiftの教科書]UIDatePicker

# [Swiftの教科書]UIDatePicker

## はじめに
こんにちは、夢見がちです。
いよいよオリジナルアプリの開発を開始してから１ヶ月半でここまで来ました。

開発者支援用アプリ[Swiftの教科書]の申請まで徐々に形になってきてワクワクしてます

さて、今回は、UIDatePickerについての紹介をしていこうと思います

## UIDatePicker

> Apple Developer Documentation

https://developer.apple.com/documentation/uikit/UIDatePicker

## ソースコードサンプル

viewDidLoad()などで書いてください
~~~ViewController.swift
    var datePicker:UIDatePicker? = nil

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        self.datePicker = UIDatePicker.init(frame: CGRect.zero)
        if let datePicker = datePicker {
            datePicker.frame = CGRect(x: 0, y: 0, width: self.view.frame.width, height: 100)
            datePicker.center = self.view.center
            self.view.addSubview(datePicker)
        }
    }
~~~

シンプルに書くと、こんな感じになります。
今の仕様だと、左に寄った感じになっちゃうので、widthのサイズをもう少し短くしてもいいかもですね。

## まとめ
UIDatePickerは、日付や時間を選択したい時に使用します。使用頻度としては、そこまでないかもしれないですが、ふとStoryboardで書き忘れた時や、途中で呼び出したい時などは、こちらのコードを思い出して書いてみてください。

## あとがき
[Swiftの教科書]を作ることでもっとよりSwiftを使える人が増えることを願ってます。
いろんな形であれ、一緒に開発できるメンバーも探しているので、一緒にオンラインで開発していきましょう。
GETRECORDIDS


+ [GETRECORDIDS](https://help.salesforce.com/s/articleView?id=sf.customize_functions_getrecordsids.htm&type=5)

リストビューまたは関連リストなどのリスト内で選択したレコードのレコード ID の形式で、配列された文字列を返します。

**使用方法**
{!GETRECORDIDS(object_type)}。object_type に、取り出したいレコードのカスタムオブジェクトまたは標準オブジェクトへの参照を指定します。

**ヒント**
Sコントロール、カスタム項目、およびリンクの特殊な差し込み項目にアクセスするには、グローバル変数を使用します。
活動は、特殊なオブジェクトです。ToDo リストボタンを作成する場合は、{!GETRECORDIDS($ObjectType.Task)} を使用します。行動リストボタンを作成する場合は、{!GETRECORDIDS($ObjectType.Event)} を使用します。
この関数はカスタムボタン、リンク、および Sコントロールでのみ使用できます。

**カスタムボタンの例**

```
{!REQUIRESCRIPT ("/soap/ajax/13.0/connection.js")} var records =
                  {!GETRECORDIDS($ObjectType.Sample)}; var newRecords = []; if (records[0] == null) { alert("Please select at least one row") } else {
                  for (var n=0; n<records.length; n++) { var c = new sforce.SObject("Case"); c.id = records[n]; c.Status = "New";
                  newRecords.push(c); } result = sforce.connection.update(newRecords); window.location.reload(); }
```

この例では、すべての選択されたケースのレコードの [状況] を「新規」として更新します。組織で設定するには、次の属性を持つケースのカスタムリストボタンを作成します。

+ [表示の種類] は「リストボタン」です。
+ [動作] は「JavaScript を実行」です。
+ [コンテンツソース] は「OnClick JavaScript」です。

上記のサンプルコードをカスタムボタンのコンテンツに張り付けます。最後にリストボタンを、取引先や商談などの [ケース] 関連リストを含むページレイアウトに追加します。ユーザは、関連リストで任意の数のケースを選択し、リストボタンをクリックすることで選択した複数のケースの状態を一度に変更できます。ユーザがリストから何も選択しなかった場合にメッセージを表示する records[0] == null の設定を確認してください。

# 外部システムへのレコード ID の受け渡しの例

[外部システムへのレコード ID の受け渡しの例](https://help.salesforce.com/s/articleView?id=sf.links_useful_custom_buttons_passing_record_ids.htm&type=5)

外部システムと統合するための固有 ID として Salesforce レコード ID を使用できます。次の例では、Visualforce ページをコールして、選択されたレコードのレコード ID を判別し、それらを URL クエリパラメータで「www.yourwebsitehere.com」という外部 Web ページに渡すボタンを作成します。

1. GETRECORDIDS 関数を使用する Visualforce ページを作成して、選択されたレコードのリストを取得します。

```
<script type="text/javascript">

idArray = {!GETRECORDIDS($ObjectType.Account)};

window.location.href="http://www.yourwebsitehere.com?array="+idArray;

</script>
```

2\. 次の属性を使用して、取引先のボタンを定義します。

表示の種類 : リストボタン
[チェックボックスの表示 (複数レコード選択用)] を選択すると、ユーザはボタンをクリックする前に、リストで複数のレコードを選択できます。
動作 : 現在のウィンドウにサイドバー付きで表示します。
内容のソース : Visualforce ページ。

3\. 最初の手順で作成した Visualforce ページを選択します。
4\. 該当するページレイアウトまたはリストビューレイアウトにボタンを追加します。
AWSでVPCを構築する

本日はAWSでVPCを構築します。

その前に、そもそもVPCとは何か？を簡単にまとめたいと思います。

#<VPCとは？>

Amazon VPC(Virtual Private Cloud)は、AWS上でネットワークを提供する仮想ネットワークです。
AWSアカウントごとに論理的に区分けされた仮想ネットワーク空間を構築することができ、AWSで取り扱うさまざまなリソースが動く土台となります。

→簡単に言うと、AWSアカウントごとに仮想空間を設定できるサービスがVPC！

#<VPC内には何があるのか？＞

VPCを作成する際、基本的には5つの要素について設定を行う必要があります。

1. サブネット　：VPCを細かく分割したもの。EC2インスタンスを起動する際には、どのサブネットに起動するかを選択する

2. アベイラビリティーゾーン　: EC2などのインスタンスが置かれる場所。

3. インターネットゲートウェイ　：　インターネット通信の出入り口

4. ACL(Access Control List) ：　IPアドレスの通信を許可/拒否するために、サブネットごとに設定するもの 

5. セキュリティグループ ：　通信を許可するIPアドレスやプロトコルを、リストにしたもの。



#<VPCの作成>

前置きが長くなりましたが、ここからは本題のVPC作成に移ります。
以下に作成手順を記載します。

<1>AWSマネジメントコンソールでVPCを開く

<2>リージョンを設定する
VPCの操作対象となるリージョンを、右上から選択します。

<3>VPC領域を作成する

VPCメニューから、VPCの作成をクリックします。
「名前タグ」には作成するVPC領域につける名前を、
「IPv4 CIDRブロック」には使用するIPアドレス範囲（今回は「10.0.0.0/16」とします）を入力します。
上記を入力後、「作成」を押すとVPCが作成されます。

<4>VPCをサブネットに分割する

今回のケースでは、先ほど作成したVPCを次の2つのサブネットに分割します。
①パブリックサブネット（インターネット上からアクセスすることを目的としたサブネット）

(1)「サブネット」メニューをクリックし、「サブネットの作成」を選択します。

(2)CIDRブロック入力画面が表示されるので、「名前タグ」の部分にはサブネットの名前を入力します。
また「IPv4 CIDRブロック」には、割り当てるCIDRブロックを入力します。
今回は「10.0.1.0/24」とします。
「作成」をクリックすると、パブリックサブネットが出来上がります。


(1)(2)でパブリックサブネットが作成されました。
次に、作成したパブリックサブネットをインターネットに接続します。

<手順>
(1)インターネットゲートウェイを作成する
「インターネットゲートウェイ」メニューを開き、「インターネットゲートウェイの作成」をクリックします。

(2)作成したIGWにチェックを付けてから「アクション」をクリックし、「VPCにアタッチ」を選択します。
すると、当該VPCにIGWがアタッチされます。
Githubが使いずらすぎる（知識が足りない）件について

## Pythonでプログラミングしてみた感想
　Pythonでプログラミングを始め、c言語よりも文字列操作が簡単でコードがめちゃめちゃ少なくすんでいるのですが、文字式への対応という課題が追加されたことによる設計の見直しをして、入力処理のプログラムを作りました。c言語では１００行くらいが２０行くらいで収まりました。この調子で進めていきたいです。
## Githubにプッシュできない問題発生
　Githubの使い方を見直そうとレポジトリをいじくった結果、、、、、プログラムをプッシュできない問題発生。ネットで調べながらレポジトリをGithubから複製してそこに変更後のプログラムをコピーしてみてもダメ、VScodeをGithubアカウントでサインインしてもダメ、最終的にプッシュする権限を持っていないと表示されひとまずヘルプを求めることに、、、。![giterror_LI.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2504276/0761d57b-6387-f6f1-3cc1-701a79e9df85.jpeg)


まあでも詰まっても自主的にやれて来れているのでこの調子で頑張っていけそうな気もしました。
In-App Guidance


[まとめページに戻る](https://qiita.com/Keiji_otsubo/items/60afc2a8d211b6f7d89f)
[まとめA～M](https://qiita.com/Keiji_otsubo/items/f3ddedee6793bf1576f8)

+ [ガイダンスのまとめ](https://qiita.com/Keiji_otsubo/items/f9bbbed3111bfd03fa95)

---------------

使ったことはないのですが、ワーニングの代わりに使うこともできようです。

[Is it possible for a validation rule have a warning and allow a save?](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000Ggyrs)

+ [Can you use Flow to show in-app guidance when a specific field is updated?](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007bLGH3)

:::note
you might be able to use popups or flow launcher  to do it but inapp guidance wouldn't work.

https://appexchange.salesforce.com/appxListingDetail?listingId=a0N3A00000FYDyHUAX

https://unofficialsf.com/launch-screen-flows-automatically-when-a-record-changes-with-detect-and-launch-page-component/
:::

# できない？

+ [ユーザー向けにアプリ内ガイダンスプロンプトを作成しました。これは、最後のログインから24時間ごとに表示されるはずです。開始日は2024年8月20日で、終了日は設定していません。](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007er902)


24 時間に 1 回必要なプロンプトを表示するには、アプリ内ガイダンス設定の「アプリ内ガイダンス間の遅延」をデフォルトからカスタムに変更する必要があるとのことでしたが、これらの設定でも繰り返し表示されませんでした。

:::note
「表示する回数」フィールドに 30 を設定するようにします 
:::

# エラー

+ [【未解決】「アプリ内ガイダンス用のCSP信頼済みサイトに画像URLを追加する際に問題が発生しました – 画像が正しく表示されません」](https://trailhead.salesforce.com/trailblazer-community/feed/0D5KX00000Ti85A0AR)
Java備忘録

- [Javaファイルのコンパイル](https://qiita.com/makoto__05/private/d4ed76737d462c1a89b1)

- [Eclipseの基本](https://qiita.com/makoto__05/private/dfeee26e265b3cb0c8a8)

- [Javaのデータ型と算術子](https://qiita.com/makoto__05/private/42a6ab97501fee32547d)　
- [配列とコレクション](https://qiita.com/makoto__05/private/4f24ee53e41822e94de2)
- [制御文](https://qiita.com/makoto__05/private/436de93c91ae6bba8ba6)
- [クラスの基本](https://qiita.com/makoto__05/private/846f188f143b2d2ddf33)
- [クラスの継承](https://qiita.com/makoto__05/private/b283715716ff95b5fd51)
- [インターフェイス](https://qiita.com/makoto__05/private/2690469688fdcfe6354a)
- [オブジェクト指向の基本](https://qiita.com/makoto__05/private/d59ea71db9f63f10eb06)
Uncaught ReferenceError: $ is not defined　Rails６

Rails６で非同期処理がうまくいかなかったので備忘録。

:::note alert
Uncaught ReferenceError: $ is not defined
:::

##### 原因としては
・jQueryがうまく読み込めていなかった。
・Rails6でのjQuery導入ができていなかった



:writing_hand:参考にした記事

https://www.botreetechnologies.com/blog/introducing-jquery-in-rails-6-using-webpacker/


#### 導入方法



```
$ yarn add jquery
````

config/webpack/environment.js
javascript/packs/application.js
に下記を追加

```environment.js
const { environment } = require('@rails/webpacker')

//追加部分 
const webpack = require('webpack')
environment.plugins.prepend('Provide',
  new webpack.ProvidePlugin({
    $: 'jquery/src/jquery',
    jQuery: 'jquery/src/jquery'
  })
)

module.exports = environment

```

```application.js 
require("jquery")
```
MyISAMエンジンの採番テーブルをInnoDBに移行する

# 背景
**(1)オンプレミスのMySQLサーバをAmazon Auroraに移行したい**

 - **このとき、全てのテーブルをInnoDBエンジンに移行する必要がある**
 - MyISAMエンジンを利用できないため（Amazon Auroraの制約）

**(2)一方、MyISAMエンジンを使ってユニークなidを発行するテーブル（採番テーブル）が存在する**

 - MySQLのデザインパターンの一つ。採番テーブル・シーケンステーブルと呼ばれる。詳細は https://dev.mysql.com/doc/refman/8.0/ja/information-functions.html#function_last-insert-id の「シーケンスカウンタ」や https://qiita.com/Nyokki/items/c68dddff2368c557c4bf の「方法3」を参照
 - **これをそのままInnoDBに移行すると、問題が発生する場合がある**

この記事では、(1)(2)を踏まえて、採番テーブルをInnoDBに移行する際の問題と対策について説明する。

# 採番テーブルをInnoDBに移行する際の問題点

 - 問題が発生する必要条件は、採番処理がトランザクションの中で実行されている場合である。トランザクションの外で実行されている場合は、問題は発生しない。
 - また、本記事は、トランザクション分離レベルが `REPEATABLE READ` の場合を前提としている。それ以外の場合は、挙動が大きく変わってくるのでスコープ外となる。

## 問題1. トランザクションがロールバックすると採番テーブルの値が戻ってしまう

 - 採番テーブルをInnoDBにすると、トランザクションが有効になる。すると、トランザクションがロールバックされた時に、採番テーブルの値もロールバックされてしまう。それにより、次のトランザクションで同じidが発行されてしまう。
 - それが問題になるかは要件次第である。ロールバックされたトランザクションに対しても一意なidを発行してトレースしたい場合などは、この挙動は問題になる。

## 問題2. 採番処理後、トランザクションが開放されるまで採番テーブルにロックが掛かってしまう

 - InnoDBのトランザクションの仕様で、 `UPDATE` 文は行ロックを掛ける。
 - 採番処理をするとidを格納している行に `UPDATE` が実行されるので、ロックが掛かり、他のトランザクションは採番ができずに、待ち状態となってしまう。
 - ロックはトランザクションがコミットされるまで開放されないので、トランザクション中に時間の掛かる処理が含まれていると、パフォーマンスの悪影響が発生する可能性がある。

# 採番テーブルをInnoDBに移行する方法

以下の2通りの対策があり、どちらかを採用することで問題を解消できる。

## 対策A. 採番処理をトランザクションの外で実行するようにする

今回の問題は採番処理をトランザクションの中で行うことにあるので、トランザクション外で実行するようにアプリケーションを改修することで解決できる。

## 対策B. 採番テーブルをリプレイスする

以下のようなテーブルを作成し、採番ルールも変更して移行する。
 - `AUTO_INCREMENT` で採番する。 `AUTO_INCREMENT` はロールバックされない性質を利用する。
 - 下記のSQLであれば、ロックされることもない。
 - よって、トランザクション中で実行しても問題がない。

```sql:DDL
CREATE TABLE sequence (
    id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY
) engine = InnoDB;
```

```sql:DML
INSERT INTO sequence VALUES();
SELECT LAST_INSERT_ID();
```

このとき、シーケンステーブルにはデータが溜まっていく点に注意。トランザクション中で古いデータを削除する方法もある([ref1](https://qiita.com/Nyokki/items/c68dddff2368c557c4bf), [ref2](https://qiita.com/NAKANO_Akihito/items/44db44375a464c72606a))が、`DELETE` 文を実行すると行ロックが掛かってしまい、「問題2」の問題が発生してしまう。

## 対策AとBの比較

### 対策Aの採用理由

 - アプリケーションの改修だけで完結するので、作業負担やインパクトが小さい

### 対策Bの採用理由

 - 対策Aの採用が難しい場合。
   - 採番処理がトランザクション内の前の処理に依存していたり、トランザクションの例外処理の都合など。
 - 対策Aは、アプリケーションレベルの対策である。開発者はアプリケーション追加改修時、採番処理をトランザクションの中にうっかり記述しないように気をつけ続けなければならない。一方対策Bは、テーブルレベルでの対策となるため、アプリケーション開発者はテーブルの利用方法を気にする必要がなくなり、より安全であるとの見方もできる。
VUEJSのtransition,transition-groupについてメモ

## 概要
アニメーションを作るために便利な`transition`と`transition-group`についてメモ。

## 

公式からの画像。
![公式から](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182163/5cd01164-c28a-d7fb-e3de-492187ce0118.png)

>vue3では `v-enter・v-leave`が`v-enter-from・v-leave-from`になっている。


v-enterでの状態についてだと、各名前は以下の状態に対応する。

- v-enter : 要素がレンダリングされる前
- v-enter-active : 要素がレンダリングされている途中
- v-enter-to : 要素がレンダリングされる後

`v-enter-to`とか`v-leave`は要素がレンダリングされてる状態のままでいいことが多いから、
指定されないことが多い。

```css
/* vue-jsの公式ドキュメントのcss事例 */
/* `v-enter-to`とか`v-leave`は指定されてない。 */
.slide-fade-enter-active {
  transition: all .3s ease;
}
.slide-fade-leave-active {
  transition: all .8s cubic-bezier(1.0, 0.5, 0.8, 1.0);
}
.slide-fade-enter, .slide-fade-leave-to
/* .slide-fade-leave-active below version 2.1.8 */ {
  transform: translateX(10px);
  opacity: 0;
}
```


## 気をつけるべきこと

### tranisionとtransition-gruopの違い

`transition`は`v-if`とか`v-show`に対して作用するもの。
`transition-group`は連想配列の加減に対して作用するもの。
`transition-group`で`v-if`とかを囲んでも全く意味ないので注意。


### v-bindのkey

`v-bind:key`の指定を`index`にするとダメらしい。


### `transition-group`の上に`v-if``v-show`をつける

下記のコードのように、あるテンプレート内で`transition-group`の上位に`v-show`をつけると、`transition-group`がうまく効かない可能性あり。別テンプレートに記載したらいけた。

```vue
<template>
  <div v-if:"isShow"> <!-- ここでv-ifとかつけるとtransition-groupが効かなくなる -->
    <transition-group name="todo">
      <div v-for="(todo, index) in todos" v-bind:key="(todo.id)">
        <Todo :todo="todo">
    </transition-group>
  </div>
</template>
```

## 参考記事

https://jp.vuejs.org/v2/guide/transitions.html

https://tech-broccoli.life/articles/engineer/vue-created-animation-with-transition-group/

 https://devsakaso.com/vue-js-transition-group/
<script setup>で動的コンポーネントを使う方法

公式サイトみたいにやろうとしたら失敗した。
```App.vue
<template>
  <label>
    <input type="radio" value="1" v-model="index">
    Sample1
  </label>
  <label>
    <input type="radio" value="2" v-model="index">
    Sample2
  </label>
  <label>
    <input type="radio" value="3" v-model="index">
    Sample3
  </label>
  <component :is="currentComponent"/>
</template>

<script setup>
import Sample1 from './Sample1.vue'
import Sample2 from './Sample2.vue'
import Sample3 from './Sample3.vue'

import { computed, ref } from 'vue'

const index = ref("1")
const currentComponent = computed(() => "sample" + index.value)
</script>
```

対処法を調べていると、以下の記事が見つかった。
https://stackoverflow.com/questions/69237991/vue-script-setup-how-to-deal-with-multiple-dynamic-components

どうやら＜script setup＞ではコンポーネントを名前で登録するのではなく、直接importしているため、上記のようにis属性に名前を渡してもどのコンポーネントか判断できないみたい。

以下のようにすると動いた。

```App.vue
<template>
  <label>
    <input type="radio" value="1" v-model="index">
    Sample1
  </label>
  <label>
    <input type="radio" value="2" v-model="index">
    Sample2
  </label>
  <label>
    <input type="radio" value="3" v-model="index">
    Sample3
  </label>
  <component :is="SampleComponents[`sample${index}`]"/>
</template>

<script setup>
import Sample1 from './Sample1.vue'
import Sample2 from './Sample2.vue'
import Sample3 from './Sample3.vue'

import { computed, ref, shallowReactive } from 'vue'

const index = ref("1")
const SampleComponents = shallowReactive({
  sample1: Sample1,
  sample2: Sample2,
  sample3: Sample3
})
</script>
```

＜script setup＞だと自由度が高く柔軟な設計がしやすいので便利。
100日後くらいに個人開発するぞ！day004

# 今日はヘッダーを作ってみた！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2632394/cc0a5602-1420-55ae-cb33-19fef3408fc3.png)

```
 - ヘッダーの構造
    - （HTML）ヘッダーの枠組みをロゴの<div>要素とリストの<div>要素で作成
        - 例
            -  <div class="header">
                -  <div class="header-logo">Progate</div>
                -  <div class="header-list"> </div>
            -  </div>
    - （CSS）リスト要素はlist-styleプロパティを用いてnoneを指定することで先頭のマークを消す
        - 例 li{list-style: none;}
 - ヘッダーの要素を横並びにする
    - 要素を横並びにする場合はfloatプロパティを用いる
        - 例：リストを左から順に横並びにする場合
            - li{float:left;}
        - 例：ヘッダーのロゴとリストを横並びにする場合
            - .header-logo{float:left;}
 - ヘッダーの余白
    - 要素に余白を入れる場合はpaddingプロパティを用いる
        - 上下左右の全ての方向に同じ幅の余白を入れる場合
            - 全方向に20pxの余白：{padding:20px;}
        - 上下左右のそれぞれの方向に異なる幅の余白を入れる場合
            - 上だけ20px：{padding-top:20px;}
            - 下だけ20px：{padding-bottom:20px;}
            - 左だけ20px：{padding-left:20px;}
            - 右だけ20px：{padding-right:20px;}
        - [省略形①]上下左右のそれぞれの方向に異なる幅の余白を入れる場合（上から時計回りに指定）
            - 上40px右30px下20px左10px：{padding:40px 30px 20px 10px;}
        - [省略形②]上下左右のそれぞれの方向に異なる幅の余白を入れる場合（上下・左右で指定）
            - 上20px右10px下20px左10px：{padding:20px 10px;}

```
imgタグへalt属性付与の考察

## はじめに

2022年4月21日午後7:37[^1]、teratailでプロフィール画像を取得できない障害が置きました。

imgタグのalt属性について少し考えたことを書きます。

## ポエム

次が障害の起きた画面になります。プロフィール画像にimgタグの代替テキストが表示されました。

![障害画面.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311399/e0849f7a-8998-368f-6e51-79ffc2ab041f.png)


imgタグにalt属性を付けることはSEO対策でほとんど必須となっています。障害が置きないとalt属性には表示上の意味がありません。障害が置きてalt属性が表示上の意味を持ちました。

alt属性を付けなければ次の画面になります。デベロッパーツールを使いました。

![altなし画面.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311399/d9f9fcfd-0f9e-d891-5df7-bba47302d0c2.png)

エラー用の画像が表示されたことで画像取得の際にエラーが起きたことが分かります。レイアウトを無視した代替テキストが表示されなくなっています。

alt属性を付けないほうが良かったのではないでしょうか？SEO対策で付けることが必須だと思いますが。

画像を表示できないブラウザでアクセスした際に代替テキストを表示することが良いとされていますが、そのようなブラウザを知りません。どのブラウザを想定していますか？[^2]ブラウザを知らないと画面確認ができません。そのブラウザを日常的に使う人はいるのでしょうか？画像を表示しないブラウジングは考えられません。

## 解決策

飛躍しますが解決策です。SEO対策でalt属性を記述した後、次のCSSを使えばいいと思いました。

```css
img {
    overflow: hidden;
    font-size: 0;
}
```

視覚障害者のために音声を読み上げるソフトがalt属性のテキストを使えますし、画像を取得できない障害が置きたときにも代替テキストを非表示にできます。

## さいごに

障害の起きた画面にびっくりして少し考えたところ、imgタグのalt属性について考えてみました。

解決策のCSSを実戦投入したわけではありませんが、障害時の緩和策として投入することを検討してみてはいかがでしょうか。

[^1]: [teratailのツイート](https://twitter.com/teratail/status/1517090203089137666)

[^2]: 特定の誰かに尋ねているわけではありません。独り言です。
今さら解説するSQL「集合演算子」

# 集合演算子とは
集合演算子を使うことで、複数の問合せを一つにまとめることができる。
（**複合問合せ**とも言われる）

ORACLEサーバーの場合は以下の4つの集合演算子が使える。

|集合演算子|内容|
|:---|:---|
|UNION|問合せ結果を連結し、重複した行を排除する。|
|UNION ALL|問合せ結果を連結し、重複した行を排除しない。|
|INTERSECT|それぞれの問合せ結果のうち、重複するものだけを返す。|
|MINUS|それぞれの問合せ結果のうち、二つ目の問合せ結果にないものを返す。|

 `基本構文`
```
SELECT 列名　FROM テーブル名
UNION
SELECT 列名　FROM テーブル名
```

# 使用時の注意点
## ソートについて
UNION ALLのみ取得結果のソートが行われない。
基本的に1つ目の問合せ結果の後ろに2つ目の問合せ結果を連結した形で結果が表示される。

その他の集合演算子に関しては特に指定しない限り、SELECT区の先頭から順に昇順でソートされる。

ただし、ソート順を指定する際には以下の制約がある。
* 複数の問合せ結果を連結する場合、最後の問合せで「ORDER BY」を記載する必要がある。
  もし途中の問合せで「ORDER BY」を指定するとエラーとなってしまう。
* 「ORDER BY」で記載する列名は最初の問合せで使用している列名を指定する必要がある。

## 指定する列の個数とデータ型について
集合演算子を使うにはそれぞれの問合せで
* 列の個数を揃えること
* それぞれの列で指定されているデータ型は同じデータ型、もしくは同じデータ型グループとすること

が求められる。
これらが満たされていないとエラーとなってしまう。

また、問合せ結果の列の見出しは一つ目の問合せ結果の列名が表示される。

`例`
```
SELECT AAA CCC FROM SAMPLE1
UNION ALL
SELECT BBB CCC FROM SAMPLE2 
```

`取得結果`
|AAA(１つ目の問い合わせの列名)|CCC|
|---|---|
|aaa|ccc|
|bbb|ccc|

## 優先順位について
集合演算子の優先順位は全て同じ。
基本的に前に指定されている複合問合せから順に実行される。
優先順位をつけたい場合は「()」で囲むことで優先的に実行させることができる。

`例`
```
SELECT 列名 FROM テーブル名
UNION ALL
(
  SELECT 列名 FROM テーブル名
  INTERSECT
  SELECT 列名 FROM テーブル名
)
```

上記の場合、先に2つ目と3つ目の問合せが連結され、その問合せ結果を元に1つ目の問い合わせと連結する順となる。