OmniAICreator/Qiita-1.07M huggingface dataset:
超ストレス！！　よくわからん説明 slackのチャレンジ


[Trailhead関係　個別の課題別 に戻る](https://qiita.com/Keiji_otsubo/items/56eb7a90bb72138ece1f)

やっぱり、新しいシステムUIはストレスになります。説明を読んでもよく分からん。英語だからさらに理解できん。

[Search For and Share Records Using the Salesforce App](https://trailhead.salesforce.com/ja/content/learn/projects/collaborate-using-the-salesforce-app-in-slack/search-for-and-share-records-using-the-salesforce-app?trail_id=boost-collaboration-with-the-salesforce-for-slack-integration)

どこに入力するんだぁ？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/658aa054-7a7b-f4a0-f615-6ceef1d5f6c0.png)


矢印のところに/salesforceを入力したら、画面に変化があった。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/7957831e-4ca3-29b4-7b04-ec9e45dd599c.png)

まだまだ、終わりそうにない。15分のモジュール。いつもの嘘つきな表示だ。

おまけに、Rose Gonzalezという取引先責任者はないよ。仕方ないので適当にレコードを作ったら検索できたけど、
画面が違う。

むかついたので、そのまま確認ボタンを押すと、思った通り正しくチェックしてないみたいでそのまま100ポイントでした。

だいたい連携もののモジュールは実際には適切にはチェックしてない。
何もしないで、確認ボタンを押すだけで先に進めることも多い。

それにしてもちょっとよくないモジュールです。

[Set Up Opportunity Alerts in Slack](https://trailhead.salesforce.com/ja/content/learn/projects/collaborate-using-the-salesforce-app-in-slack/set-up-opportunity-alerts-in-slack)

さきほどから、怒りが収まらん。何もせずに　確認ボタンを押してみた。
ああ、合格。　思った通りだ。


[Send Messages and Disconnect Your Account](https://trailhead.salesforce.com/ja/content/learn/projects/collaborate-using-the-salesforce-app-in-slack/send-messages-and-disconnect-your-account)

このモジュールは何やらチェックしている感じです。

We couldn’t find Slack Messages added to the Account Layout. Make sure you’ve added the Message Viewer as described above.

この設定だけして、確認ボタンを押したら無事終了。　もうこの説明は読む気がしない。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/2a298dd0-3733-5936-85e5-ff7a8b52f267.png)


# 実際の連携での問題。

+ [Botの表示名に日本語を設定していましたが、アルファベットのみに修正したところ連携を確認できました。](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000FxeNC)
別AWSアカウントのEC2インスタンスをコピーする手順

別のAWSアカウントで作成されたEC2インスタンスを、自分のアカウントにコピーする機会があったので、手順を残しておきます。

# コピー元の作業
コピー元のAWSアカウントで、AWSマネジメントコンソールにログインします。

## イメージの作成
コピーしたいインスタンスを選択し、アクションから「イメージを作成」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236222/36deab86-e8e3-0ce6-4403-98364eb2cf67.png)
任意のイメージ名を入力します。
このとき、サーバを止めたくなければ「再起動しない」にチェックを入れましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236222/486d0277-6ce7-ff0f-3b7f-32114c79f86e.png)
「イメージを作成」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236222/6ddf1a9f-8bbc-0e5b-ca60-748560c1a141.png)
イメージの画面で、作成したAMIのステータスが *pending* から *available* に変わるまで待ちます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236222/140ccb1d-0121-1b80-ae9a-0f56e1d19902.png)
*available* になったら、アクションから「イメージパーミッションの変更」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236222/cb27d05f-ed70-d6e1-5542-3ced7d07a201.png)
次の通り設定します。

- 「プライベート」にチェック
- コピー先のAWSアカウント番号を入力
- ボタン「アクセス許可の追加」をクリック
- 「パーミッションを作成するときは次の関連付けられた…」にチェック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236222/48e9b463-16db-91de-4d6e-7a7a1fba8946.png)
ボタン「保存」をクリックすると、このイメージはコピー先に**共有**された状態になります。

# コピー先の作業
コピー先のAWSアカウントで、AWSマネジメントコンソールにログインします。

## イメージのコピー
イメージの画面で「プライベートイメージ」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236222/1e4e599f-5987-71d6-9f82-7d7373d0fdf4.png)
コピー元と共有しているイメージにチェックし、アクションから「AMIのコピー」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236222/545fbafa-c4fb-5e12-4c9b-2c146c3fac51.png)
リージョンを選択し、任意のイメージ名を入力したら、ボタン「AMIのコピー」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236222/5f43bb95-08e6-7416-279d-79f1339c8409.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236222/5f7d96cf-8c3f-fbac-796c-048575a9083f.png)

## 確認
コピーされた新しいイメージは、所有者が自分のアカウントになっているはずです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236222/389f313f-78dd-a0ea-db57-463a8c9f4873.png)

## インスタンス起動
コピーしたイメージからインスタンスを起動します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236222/f4c14325-bf96-98c2-ea3b-557f286e416d.png)
コピー元のキーペアを持っている場合、キーペアを新たに作る必要はありません。
無事に起動できればOKです。

## コピーに失敗した場合
この手順通りにやってもエラーになることがあります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236222/2b680a25-d3d4-bff1-ef7c-be7475350061.png)
AWS Marketplace から取得したAMIをコピーしようとすると、`Images from AWS Marketplace cannot be copied to another AWS account.` というエラーになります。
ライセンスを取得しましょう。

サブスクライブ（購入）する製品コードを、イメージの詳細から確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236222/14014c8a-dd0e-b3ab-10fe-8a7c7b1e53cc.png)
次のURLでMarketplace にアクセスします。`********` は製品コードに置き換えて下さい。
`https://aws.amazon.com/marketplace/pp?sku=********`

「Continue to Subscribe」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236222/715f2bcd-27a0-0104-09ed-107469d6ed95.png)
「Accept Terms」をクリックすると完了です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236222/2717052e-84da-b7e7-6622-7ac9d4aecb6a.png)
[Ruby] AtCoder過去問 B - A to Z String 

##はじめに
AtCoder過去問B問題をRubyで解いてみました。
よろしくお願いします。

問題はこちらから確認してください↓

https://atcoder.jp/contests/abc053/tasks/abc053_b

##B - A to Z String 
まずは入力受け取りです。
一文字ずつ分けて配列で受け取っています。

```ruby
s = gets.chomp.chars
```

この問題メソッドさえ知っていれば非常に簡単で、要は配列sの中で一番はじめに出てくる(一番先頭に近い)文字Aのインデックス番号(位置)を特定し、配列sの中で一番末尾に近い文字Zのインデックス番号（位置)がわかれば、zのインデックスに+1した数（インデックス番号は0から始まるため+1する)からAのインデックスを引けば文字列の数が分かります。

Aのインデックスはindexメソッドで分かります。
Zのインデックスはrindexというメソッドで末尾からはじめに見つかるZの位置を特定することができます。


```ruby
s = gets.chomp.chars
a_index = s.index("A")
z_index = s.rindex("Z")

puts z_index+1-a_index
```

a_indexに+1していない理由は、ここで欲しいのは配列sの先頭からはじめのAにたどり着くまでの文字の数なのでAは含まれないからです。もともとインデックスは0から始まるので−１する必要はありません。

逆にz_indexはZを含めた、最後のZの位置を調べたいので+1しています。
iPadのPython(Jypyter notebook)実行環境であるJunoを使い始める

# はじめに
2021年10月10日、iPadのPython (Jupyter notebook) 実行環境である Juno を購入した。¥1840也。iPad 用のPython実行環境としては、以前からPythonista 3 を持っていたのだが、Pythonista 3 で使用可能なライブラリは、numpy と matplotlib だけであり、作成できるプログラムが限られてくるため、numpy, matplotlib, scipy, pandas, sklearn が使える Juno を購入したわけだ。同じように scipy, pandas, sklearn が使えるiPad用Python 環境として、 Pyto というものもあるが、App store で評価を見ると、『挙動が不安定でよく落ちる』というものがあり、これが気になったため、比較的安定していると思われる Juno を選択した。
なお、無料のPython環境で、Carnets-Jupiter (with scipy) というものもあり試してみたが、外付けキーボードからのリターンキーによる改行を受け付けなかった為、これは早々に諦めた。

余談だが、最近 M1 iPad Pro 12.9-inch を購入している。先般、長期出張でホテルでの PC 作業を長期間行なったのだが、メインマシンである M1 MacBook Airのお供にiPad Air 4を持って行き、Sidecarを使い2画面で作業を行ったのだが、サブディスプレイとしてもう少し大きな画面が欲しいなあと思ったのが iPad Pro 12.9-inch 購入のきっかけである。自宅では M1 MacBook Air を 27-inch4k モニターに接続して使っているので、比較的快適であるのだが、出張となると大画面モニターを持っていくわけにもいかず、MacBook Air と iPad Airの組み合わせで作業する事になっていたものを、今後は MacBook Air ＋ iPad Pro 12.9-inch の組み合わせで使うことが出来るので、嬉しい。しかしながら、M1 iPad Pro 12.9-inch は私のメインマシンである M1 MacBook Air よりも高価であるため、MacBook 以上の働きをしてもらわなければならない。Juno を入れたことにより Python 環境が、MacBook にかなり近づいたことになり、iPad Pro の今後の活躍に期待しようというわけである。

# インストール
Juno をダウンロード・インストールすると、Files アプリiの中に Juno というフォルダができるので、ここを使っていくことになるが、必ずしもここでなくても、Files アプリで見ることができるファイルならどこでも Juno を実行することはできるようである。Juno は Jupyter notebook のアプリであるため、ipynb ファイルがあれば、それをタップすることにより Juno を実行することができる。

# 少し使ってみる
## ライブラリのインポート
よく使うライブラリをインポートしてみる。numpy, scipy, matplotlib, pandas, sklearn, PIL (pillow)はプレインストールされている模様。
Seabornは入っていないので新規にインストールする必要がある。新規のライブラリインストールは、ファイル名をタップすることにより表示されるメニューのInstall Python Packageから行う。インストールされたライブラリは、Junoフォルダの下にあるSite-packagesに格納され使用可能になる。

![1CF866B8-3377-4EFE-A0E7-086A18EA694C.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129300/9b26699b-3954-288f-27d2-41f6f49102b7.jpeg)

## 簡単なグラフを書いてみる
私の場合、iPadはダークモードで使っている。ライトモードでは問題ないのであるが、ダークモードでグラフを描画すると、下の写真のようになってしまう。figureでfacecolor=‘white’を指定しても効果なし。

seabornの使用なし
![C1D9409E-1910-42C3-B9AE-3134657E8A15.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129300/36834ae6-cd34-4a18-cdbc-c944a7142d19.jpeg)

解決策としてはSeabornを噛ませること。seabornをインポートし、```set(style=‘white’)``` を入れることにより解決できた。 

Sseaborn使用
![C2F431D4-8572-4A34-9555-85FE5774F6CA.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129300/37febd92-f1de-0a57-e500-0181c4445b31.jpeg)

Junoにはよく使うライブラリが含まれており、またライブラリの新規インストールも可能（全てではないらしい）なので、だいぶMacの環境に近付いた気がする。ちなみに、地図作成のためのライブラリ cartopy をインストールしようとしたができなかった。地図作成のため、依存データが色々あるためかもしれない。

これからは、iPad Proでどこまでできるか、色々試していこうと思う。とは言いながらiPad Pro 12.9-inch はこれまで使ってきたiPad Airと比較してかなり重く、取り回ししづらい。慣れるのに時間がかかりそうである。


以　上
RSpecでparamsとheadersを渡す方法

# RSpecとは
Railsでwebアプリを開発する時に、想定通りの挙動になるかを
確認するためのテストフレームワークです。
Minitestとtest-unitもテストとして使われますが
大多数のRailsで開発をするエンジニアはRSpecを使用します。
実務ではコードレビューはスクールみたいに、コードの修正をするのではなく、
RSpecを使い挙動の確認をします。

# paramsとは
フォームから送られてきた値を受け取るメソッドです。

# headersとは
新規登録などのログイン機能などを実装するときに使う
devise_token_authにあり、アプリを操作する時に、
ユーザーの認証情報を送り、アプリを動かします。

# テストでparamsとheadersを渡す方法
createができるかのテストで使われるみたいです。

```staffs_spec.rb

describe "POST /staffs" do
   subject　{post(staff_path,params: params)}

#都合により省略

end
end
```

paramsを渡すコードは

```rb
params: params
```
の部分です。

headersを渡すコードは

```rb
headers: headers
```
になります。

paramsとheadersを送信する時は、

```rb
subject　{post(staff_path,params: params,headers: headers)}
```
上のようなコードになります。


都合によりコードは１部分しかお見せできないのでご了承ください。
RHEL から AIX への NFS マウントで "Remote I/O error" が出力した場合



##### はじめに

何気なく RHEL と AIX 間で、NFS マウントをしようとしたら引っかったので備忘録で記載します。


##### 解決法

下記のTechnote に解決法の記載がありました。
「-o nfsver=3 を設定する」、または、「AIX を NFSv4 で構成」します。

https://www.ibm.com/support/pages/ibm-aix-nfs-mount-failure-linux-client-aix-nfs-server

>There are two ways to resolve the problem.

> 1. Add the option -o nfsvers=3 to the mount command on Linux.

> 2. Configure AIX to support NFSv4.

---

AIX はデフォルトで NFS Client v3 を使用しています。

・ネットワーク・ファイルシステム
https://www.ibm.com/docs/ja/aix/7.2?topic=management-network-file-system

> NFS クライアントは、デフォルトで NFS バージョン 3 プロトコルを使用します。



---
##### 環境

・RHEL 8.4
・AIX 7.2 TL5 (対象フォルダは export 済み)

---
##### 失敗例

RHEL からマウント・コマンドを実施

```
[root@RHEL84_test ~]#  mount -t nfs -o rw,sync aix72_test:/aixtest /RHELtest
mount.nfs: Remote I/O error
```

##### 成功例

RHEL からマウント・コマンドを実施(-o nfsvers=3 を付与)

```
[root@RHEL84_test ~]# mount -t nfs -o rw,sync -o nfsvers=3 aix72_test:/aixtest /RHELtest
```


以上です。
windows10へ2021年10月10日時点で最新のPython3.10.0で jupyter lab をpipでインストールしようとしたら遅延しまくってはまった件について

最近もっぱらMacbookで開発していて、自作PCのwindows10へはjupyterlabはおろか、pythonすらインストールされていないというとても稀有な環境下からjupyter labのインストールを試みた。

そうしたら、結果的に1日以上の時間を浪費したので備忘録。
ただし、結論から得られた教訓をまず言うと、大切なのは問題解決であって、最新が良いわけではないということ。
問題解決の目標大事。

# 経緯
自動売買システム構築やら言語解析のためちまちまとコードを書くためのツールとして、所有する全デバイスにjupyter notebookをインストールしたいと思う。

実行環境は自宅ＰＣ（windows）やリモート（CentOS）を想定しているので、マシンパワーのあるＰＣでDockerを動かしてローカルで検証してリモートに投げようかしら。

じゃあ、windowsでも開発できるようにjupyternotebookあったら便利じゃないですか。

よし、インストール！！！　（所要時間１０秒）

# 遅延にぶつかるまでの流れ
公式サイトから、最新のPythonのインストーラーをゲット（python-3.10.0-amd64.exe）
pythonのバージョン管理はmacでやってるから、windowsではとにかく動けばええやろの精神で。

実行　設定画面でPathは通してもらう

Powershell で　Python --version　実行

無事　3.10.0　と表示されたので、続いて、pip経由でjupyter notebookへ

とおもったけれど、今時jupyter labやんねと思って、調べて下記実行

python -m pip install jupyterlab

怒られたので

pip install --upgrade pip

を実行して、pipをpip-21.2.4へ

これで万全やな

python -m pip install jupyterlab

実行！！

（ここまで、所要時間３０分）

よし、インストール完了まで待つぞ。

そして、3時間後・・・・

インストール完了してないやんけぇええええ
こんちくしょぉぉおぉぉぉおおおおおおおお
おせええぇぇえぇぇぇぇ

ということになりました。ぴえんぴえん。

# 遅延にぶつかってからしたこと(勉強になったが結果的に無意味)
遅延についての情報を集める。

python - Resolving new pip backtracking runtime issue - Stack Overflow

pipの依存関係チェックが厳しくなる - Qiita

なるどわからん。わからんが、pip側の問題なのか、じゃあ、一回アンインストールしてみようかな。

pipをアンインストールして、再びインストール。

その後、python -m pip install jupyterlab　実行

やっぱり遅い、寝る！！

（よく朝、約８時間経過後）

終わってへん、ダメでした！！！！！！！！！！！


#　発想の転換

今の自分には、Wheelの設定ファイルを手動であれこれするスキルも時間もない、詰んだ！！！

いや、ここからだ！！！と、根本的な問題解決は何かに立ち戻って考える。

やりたかったことは、「jupyter lab」の導入だ。

「Jupyter lab」のインストールの不調は、ネット上に報告されてない、と。

うーん。

あ、ダウングレードすればいいんじゃね。（バージョン管理の発想を初期に切り捨てたのがあだになり気づくのが遅れる）

# 解決法

python 3.10.0　を公式インストーラーからアンインストール

公式サイトから、安定板っぽいPython3.7.9インストーラーをゲット
今回pipのバージョンアップもあえてしないことに。

仮設に基づいて、python -m pip install jupyterlab

インストール完了（所要時間約1分）

無事実行できました！！！！！！！わーーーーい。

なんということでしょう。とても時間の無駄ですが、勉強になりました。ほんとうにありがとうございます。

:::note info
学び
盲目的に最新版にこだわるより、安定した動作の得られているものを使おう。
:::
【初学者奮闘録】Gitコマンド『checkout』を『checkin』に変えてほしい件

#はじめに
この記事は、独学開始から約３ヶ月の実務未経験者が作成したものです。
よって、スキルは非常に未熟なため、決して本記事の内容を鵜呑みにされないよう、ご注意ください。
（未熟な私が記事投稿を行なっている背景については、本文の最後にお伝えします。）

#Gitコマンド『checkout』を『checkin』に変えてほしい
※下記からは、あくまでも私の個人的な意見です。

Gitの学習中、以下のコマンドに出会いました。

```
git checkout "移動先のブランチ名"
```

このコマンドは、任意で指定したブランチへ移動する際に入力するコマンドです。
私はふと思いました。

「このコマンドを入力すれば、移動先のブランチに入っていくってことであれば、そこは『chechout』じゃなくて、『checkin』だろ！」
と。

「今いるブランチから退出する」という意味で使用しているのであれば、checkoutでも問題ないと思います。

しかし、少し時間を置けば、こうも思い始めました。
「『今いるブランチからcheckoutして、それから次のブランチへ移動する』という意味であれば、checkoutでも問題はないのか・・・。」
と。

以上、上記のようなやりとりを頭の中で繰り広げながら、Gitの学習を進める初学者の話でした。
ちなみに、下記に添付した書籍では、『プルリクエスト』のことを「プッシュリクエストじゃないのか！」と言っておりました。
https://www.c-r.com/book/detail/1108
面白いので、よろしければ是非。


#最後に
上記でもお伝えいたしましたが、私は独学開始から約３ヶ月の実務未経験者です。
そんな未熟な私が記事を投稿しようと決意した理由は、以下の通りです。
・初学者の記事が多く出回るほどに、プログラミングの学習を検討している方の背中を押せると考えたから（私自身、学習を開始するまでに初学者の記事を読み漁っておりました）
・周りに同じ境遇の仲間がいない、孤独な初学者さんの競争心を掻き立てられるのではと考えたから（学習効率を上げるためにはライバルの存在は重要）
・あるいはこのような稚拙な記事を読んだ初学者さんが「自分のレベルはこいつよりも上」と優越感を与えられるのではと考えたから（学習効率を上げるためには自信を持つことも重要）

プロのエンジニア同様、初学者にもそれなりの努めがあると、私は思います。
今後も、下手くそながらも【初学者ページ】を上げ続けて参ります。

最後まで読んでいただき、誠にありがとうございました。
【Laravel】CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP のせいでtimestampのカラムが勝手に更新されてしまう

# timestampはデフォルトで, CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP属性がつく

マイグレーションファイルで`timestamp`のカラムを設定すると, レコードを更新すると日付が自動更新されるようになっています. DBを確認すると, カラムの属性に`CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP`がついています. これを消せばカラムが自動更新することがなくなります.

```migrate.php
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class TestTable extends Migration
{
    public function up() {
        Schema::create('test_tables', function (Blueprint $table) {
            $table->timestamp('output_at')->comment('出力日時');
        });
    }

// 略
}

```

# nullableにするだけ

マイグレーションファイルのカラムを設定するときに`nullable`と追加すると, `CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP`が消えるようになります. 

```migrate_new.php
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class TestTable extends Migration
{
    public function up() {
        Schema::create('test_tables', function (Blueprint $table) {
            $table->timestamp('output_at')->nullable()->comment('出力日時');
        });
    }

// 略
```
3kbのHTML to Reactパーサ「DOMParserReact」で、HTML文字列のaタグをNext.jsのLinkコンポーネントで表示する

作ったライブラリの宣伝記事です。

https://www.npmjs.com/package/dom-parser-react


## DOMParserReactとは

DOMParserReactは軽量なHTML to Reactパーサーです。HTMLテキストをReactのコンポーネントに変換して表示します。また、表示の際にHTMLのタグを任意のコンポーネントに置き換えることができます。

主な使用想定は、個人ブログなどのコンテンツ部分です。コンテンツ部分は、MarkdownのファイルやヘッドレスCMSのリッチテキストで管理し、それをHTMLにしたものを表示していると思います。このライブラリを使用すれば、そのHTMLを表示する際、CSS in JS等のReactの技術を使って装飾したり、タイトルのようにaタグをSPA用の `Link` コンポーネントに置き換えたりすることができるようになります。

そして、このライブラリの一番の特徴は、その軽さです。minifyで3kb(v0.2.0時点)しかありません。類似ライブラリと比べて非常に軽量なのは、独自のパーサーを使わず、ブラウザJSのAPI `DOMParser` を使用しているからです。

| ライブラリ | バンドルサイズ (minify) | 備考 |
| :-- | --: | :-- |
| dom-parser-react | 3kb | 筆者作 |
| html-react-parser | 27kb |  |
| rehype-react | 42kb | unifiedのプラグイン。計測時は、rehype-reactの他、unified、rehype-dom-parserを使用 |

※上記は筆者調べ。rollup.jsでバンドルして計測。ただし、react、react-domのサイズは除外


## 使い方

それでは、実際の使用方法を紹介します。
NPMで公開していますので、インストールは、npm/yarnから行います。

```sh
npm i dom-parser-react
# or
yarn add dom-parser-react
```

DOMParserReactを使用するには、コンポーネントをインポートして変換するHTML文字列を `source` で指定してください。
そのHTMLを表示するコンポーネントが作成されます。

```jsx
import DOMParserReact from 'dom-parser-react'
// import { renderToStaticMarkup as render } from 'react-dom/server'

const htmlText = `
  <h1>HTML Text</h1>
`

const App = () =>
  <DOMParserReact source={htmlText} />

render(<App />) // `<h1>HTML Text</h1>`
```

上記は `dangerouslySetInnerHTML` と結果がほぼ同じですので、今度はタグを置き換えてみましょう。
`components` プロパティに `{ 置換対象のタグ: 置換後のコンポーネント }` という形式で指定します。下記は、`h1` タグを `Title` コンポーネントに置き換える例です。

```jsx
const htmlText = `
  <h1>HTML Text</h1>
`

const Title = (props) =>
  <div className="title">
    <h1 {...props} />
  </div>

const App = () =>
  <DOMParserReact source={htmlText} components={{ h1: Title }} />

render(<App />) // `<div class="title"><h1>HTML Text</h1></div>`
```

`h1` が `div.title` で囲まれて表示されました。
今回は囲むだけでしたが、例えば、CSS in JSでスタイリングしたコンポーネントを指定したり、アンカーリンクのアイコン等を追加したりもできます。
また、複数種類のタグを置き換えたい場合は複数記載すれば対応可能です。

```jsx
const components = {
  h1: Title,
  h2: SubTitle,
  p: Paragraph,
}

<DOMParserReact source={htmlText} components={components} />
```


## Next.jsで使用する

それでは、実際にNext.jsで使用してみましょう。

と言っても、上記のように `components` を指定するだけです。

```jsx
import Link from 'next/link'
import DOMParserReact from 'dom-parser-react'

const components = {
  a: ({ href, ...props }) => (
    <Link href={href}>
      <a {...props} />
    </Link>
  ),
}

const Post = ({ htmlText }) =>
  <DOMParserReact source={htmlText} components={components} />

```

もしかしたら、読者の中には本当に動くか疑問に思っている人がいるかもしれません。最初に説明したように `DOMParser` はブラウザJSのAPIで、Next.jsのSSR/SSGが実行されるNode.jsにそのAPIはありません。
ですが、DOMParserReactは問題なく動作します。Node.jsでの実行時は、自動でJSDOMというライブラリをインポートし、`DOMParser` をエミュレートします。これによってブラウザと同じように動作し、SSR/SSGが実行されます。もちろん、ブラウザではJSDOMはバンドルしませんので、軽量なサイズのままです。


## 最後に

上記の通りこのライブラリは、HTMLコンテンツを簡単に装飾することができ、ライブラリサイズも軽量でSSR/SSGにも対応しています。ぜひ、個人ブログなどに使用してみてください。


## おまけ

DOMParserReactを使用した、筆者のブログ

https://imasanari.github.io/

Qiita記事を優先したため、最新の投稿はライブラリ使用前の去年のものになっています。そのうち、DOMParserReact作成時のこととかを書いていきたいです。
おい！なんでその処理をコントローラに書いているんだい？

## ある日のパイセン、「データ操作の処理は、コントローラに書かないでくれよ！」

> **なんだって？**
> **そしたらいったい、どこに書けというんだい？**
>
> モデル？
> リポジトリ？
>
> もっと言えば**なぜ、コントローラに書いたらいけないんだい？**
> 
> ファットコントローラを避けるため？
> 責務を分散させるため？
> **わからないことだらけじゃないか！**

そんなふうに思っているそこのキミ。

**今日はボクがとっておきのモノを紹介しよう！**

ボクはこれを知って**世界が変わった**んだ

今まで何となくやる気がでなかったり
身体が重かったりする実装が
**これを使うことですごくスッキリ**してね！

なんていうか、幸福感に包まれるんだ。
生きるのが楽しくなるよ。

**1度知るともうこれを知らなかった頃の実装には戻れない**ね。

本当にとっておきなんだ。
いいかい、ママには内緒だよ？

## 少し知るだけで幸せが訪れる、それがドメイン駆動開発さ

ああ、たまたまだったんだよ。

`Repositry`や`Service`という言葉は知っているし、
なんとなく役割もわかる。
なんなら使ったこともある。

そんなボクがこの本を手にとったのはね。
[ドメイン駆動開発設計入門](https://www.amazon.co.jp/dp/479815072X)

半分くらいまでこの本を読んだボクは、
**慣れ親しんだMVCフレームワークの見え方が劇的に変わった**んだ！

ただ今日触れるのは、ドメイン駆動開発そのものではなく
**ドメイン駆動開発の考え方を反映したとき
どんな処理をどこに書くかということだ**

ドメイン駆動開発（DDD）について気になる人は
ぜひ学んでボクに教えてくれ！


## Modelには、そのモデルの持つふるまいを書く

DDDにおいてのモデルとは何か、みたいな話は置いておこう。
ボクはそれを語れるほど精通しちゃいないからね！
（おっと、ちゃんとあっちの精通はしているぞ！）

例えばブログがあったとしよう。

ブログには記事、つまり`Article`のようなモデルが存在するはずだろう？

`Article`には、タイトルと、内容があるだろう
タイトルにいたっては、文字数制限があるかもしれないな

> **Articleモデル**
> タイトルが必ず存在する
> タイトルは30文字以内である
> 内容が必ず存在する

これが、Articleモデルの持つふるまいだ
逆に、こういうふるまいがなければ`Article`じゃない！

ブログの記事に、ビールの在庫なんて項目は登録できないだろう？
登録できたらきっとそれは
ボクの家の冷蔵庫のモデルだな！

## Serviceには、モデルのユースケースを書く

`Article`には、作成や編集、削除といったユースケースがあるはずだ

`Service`にはそんなモデルのユースケースを書いていく

> **Articleサービス**
> 記事を作成できる
> 記事を確認できる
> 記事を編集できる
> 記事を削除できる

ここで余談だが、DDDには
ドメインサービスとアプリケーションサービスがある
その違いは、ここで話すことではないから、ぜひ調べてみてくれ！


## Repositoryには、モデルのデータの永続化・再構築を書く

`Model`と`Service`をつくったところで
ブログはまだ、まったく使い物にはならないな！

なにせ、データの永続化（保存）・再構築（復元）ができないんだから！

今のブログはまるで、
料理のできないレストラン、ビールの飲めない人生みたいだ！

データの永続化や再構築をするときは、そのモデルのふるまいを
いれてあげないとな！

> **Articleリポジトリ**
> 記事を保存できる
>  ┗**Articleモデル**・ふるまい
> 記事を復元できる
> 記事を削除できる

そして、データの永続化・再構築ができるようになったら、
`Service`に使えるだろう！

> **Articleサービス**
> 記事を作成できる
>  ┗**Articleリポジトリ**・保存できる
> 記事を確認できる
>  ┗**Articleリポジトリ**・復元できる
> 記事を編集できる
>  ┗**Articleリポジトリ**・保存できる
> 記事を削除できる
>  ┗**Articleリポジトリ**・削除できる


また余談になってしまうが、
ハンバーガーの間のポテトやコークだと思って楽しんでくれ！

本来なら
`Repository`には`Interface`をつくったほうがいい
それは、依存関係逆転の原則があるからだ

残念ながら、依存関係逆転の原則や
`interface`とは何か、はここで話すことではないんだ
ハンバーガー屋でも、小麦粉そのものは売ってないんでね！


## Controllerはどこへいった？

> ねえママ！
> `Controller`をどこにやったんだい？
>
> ちゃんとここに置いておいたのに！

そう思ったかい？

モデルのふるまいを`Model`に
ユースケースを`Service`に
データの永続化・再構築を`Repository`に
書くようにしたことで

`Controller`には、ほとんど書くことがなくなってしまった！

しかし、それでいいんだ
`Controller`はフロントと、これらのロジックとのデータの橋渡しをするだけでいい！

こう考えると、太る理由がわからないだろう？

え？ゴシップ好きのトニーがなんで太ってるかって？
彼はハンバーガーの食べすぎさ！


## ドメイン駆動開発、少量でもこの高揚感！

ここまで読んでくれたキミ、ありがとう！

ボクはドメイン駆動開発の、ほんの少ししか齧っていないけれど
少量でもとてつもない高揚感に包まれているよ！

最初はあまりにもブッ飛ぶもんだから
人目につきやすいところ使うときは気をつけてくれよな！


**Follow ME !!!**
**I'm sure to follow you back!**
twitter: [@marty_ojiya](https://twitter.com/marty_ojiya)
JavaScriptのコンテキスト

# はじめに
コンテキストについて学習したので備忘録を残します。
初学者です。
間違っている箇所がありましたら申請お待ちしております。

# コンテキストってなに？
JavaScriptでの意味
実行コンテキスト(コードを実行する際の文脈・状況)

# コンテキストには3種類ある
*覚えるべきは2つ*
**グローバルコンテキスト**
**関数コンテキスト**
~~evalコンテキストは不要~~ 関数eval自体が非推奨のため


**グローバルコンテキスト**
*使用可能な値*

- 実行中のコンテキスト内の変数・関数
- グローバルオブジェクト
- this


**関数コンテキスト**
*使用可能な値*

- 実行中のコンテキスト内の変数・関数
- arguments
- super(特殊な環境でのみ使用可能)
- this
- 外部変数

# 実際のコードで確認しよう
コメントアウトをみてね

```javascript
// グローバルコンテキスト JavaScriptファイル内直下の実行環境(変数や関数)
let a = 0;
function b() {
  console.log(this, arguments, a); //これに加えてsuperと外部変数が使える(外部変数 = 関数の外の変数)
  // b();の関数コンテキスト
}

b();

// 関数コンテキスト 関数{}の中の実行環境 (波括弧の中)
// thisやargumentsは実行される環境によって取得する値が違う
```
# まとめ
**コンテキストとはコードを実行する際の文脈・状況**
**グローバルコンテキスト**
*jsファイル直下の関数や変数*

        - 実行中のコンテキスト内の変数・関数
        - グローバルオブジェクト
        - this
        
---
**関数コンテキスト**
*関数の中括弧の中*

    - 実行中のコンテキスト内の変数・関数
    - arguments
    - super(特殊な環境でのみ使用可能)
    - this
    - 外部変数
【JavaScript】変数と参照の振り返り④　AND条件とOR条件


#はじめに

Udemyの[【JS】ガチで学びたい人のためのJavaScriptメカニズム](https://www.udemy.com/course/javascript-essence/)の講座の振り返りです。

前回の記事

https://qiita.com/nao0725/items/263dc7a74981fc33a27c

#目的

* 変数についての理解を深める


#本題
###1.AND条件とOR条件

####ANDの条件と仕組み

````javascript
// AND条件　かつ　a && b 
// aとbがtureでないといけない

const a = 1;
const b = 1;
// 出力結果で1が返ってくる　＝　ture
console.log(a && b)
``````

````javascript
const a = 0;
const b = 1;
// まずaがturethyなのかどうか確認する　
// aがtureの場合 ＝＞　bの値を返す
// aがfalseの場合 　＝＞　aの値を返す
// ここではaは０なのでaの値を返す
console.log(a && b)
````

````javascript
// もしcの値を代入したら
const a = 1;
const b = 2;
const c = 3;
// この場合a,b,cそれそれfalseに値しないのでcの値3が出力される
console.log(a && b && c)

// AND条件はfalthyなものが途中であった場合は、その値を返す
// もしなかった場合は一番最後の値を出力する
```````



####ORの条件と仕組み

`````javascript
// OR条件　または　
// aもしくはbがture

const a = 0;
const b = 1;
console.log(a || b)
`````







````javascript
// // まずaがfalsyかturethyなのかどうか確認する　
// // aがtureの場合 ＝＞　aの値を返す
// // aがfalseの場合 　＝＞　bの値を返す
const a = 1;
const b = 0;
// この場合aがturethyなので、1と出力される
console.log(a || b)
````
````javascript
// もしa = 0, b = 1, c = 2なら
const a = 0;
const b = 1;
const c = 2;
// この場合aがfalsyなので、bの値1と出力される
console.log(a || b)
// 下記の場合でもbがturethyなので1が出力される
// もし、b = 0(false)ならcの値２が出力される
console.log(a || b || c)

// OR条件はtureが見つかった時点で値を出力される
// 見つからなかった場合は一番最後の値が出力される
````

もし、AND条件とOR条件が混在していたら、

````javascript
const a = 0;
const b = 1;
const c = 3;
// 下記の条件では3が出力される　
// aはfalseでOR条件なのでbの値を調べに行く
// bはturethyなのでAND条件によってcの値を調べに行く
// cもturethyなのでAND条件によってcの値を調べに行く
console.log(a || b && c)
`````

このように書いてしまうと、わかりにくいので
基本的にはグループ化をして記述する

````javascript
// もしd = 0が条件に加わったら
const a = 0;
const b = 1;
const c = 3;
const d = 0;
// グループ毎に演算をおこない、最後にAND条件で結果を出力される
console.log((a || b) && (c || d))
// aとbはOR条件によって、tureが見つかった時点で結果を出力するので、１
// cとdはOR条件によって、3と出力される
// AND条件はfalsyな値が見つかった時点で結果を出力するが今回はどちらもtureなので
// 一番最後の値である右のグループの3が出力される
````

今日はここまで！

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

* [【JS】ガチで学びたい人のためのJavaScriptメカニズム](https://www.udemy.com/course/javascript-essence/)
electron-forge publishのエラー対応/トラブルシューティング

# 概要

Electron-forgeのS3 publishでちょっとバタバタしたのでまとめ

## 実施環境

| 環境 | バージョン |
|:-|:-|
| OS  | Windows 10 20H2 |
| node | 16.5.0 |
| npm  | 6.14.15  |
| electron | 15.0.0 |
| @electron-forge/cli | 6.0.0-beta.61 |
| @electron-forge/publisher-s3 | 6.0.0-beta.61  |

# エラー･原因･対処

## ERR! code E404

`npm publish`を実行すると以下のエラーが発生します｡

```
npm ERR! code E404
npm ERR! 404 Not Found - PUT https://registry.npmjs.org/auto-printing - Not found
npm ERR! 404
npm ERR! 404  'auto-printing@1.0.0' is not in the npm registry.
```

### 原因

コマンド不正で､意図と違う`publish`コマンドが実行されている｡

### 対策

`run`が必要です｡

```bash
npm run publish
```

## ✖ Resolving publish target: @electron-forge/publisher-s3

```
✖ Resolving publish target: @electron-forge/publisher-s3
An unhandled error has occurred inside Forge:
Could not find a publish target with the name: @electron-forge/publisher-s3. Make sure it's listed in the devDependencies of your package.json
Error: Could not find a publish target with the name: @electron-forge/publisher-s3. Make sure it's listed in the devDependencies of your package.json
```

### 原因

`@electron-forge/publisher-s3`がインストールされていません

### 対策

```bash
npm install @electron-forge/publisher-s3
```

## Error: Region is missing

### 原因

configにregion指定がありません｡

公式ドキュメント[PublisherS3Config](https://js.electronforge.io/publisher/s3/interfaces/publishers3config) には､記載がありませんが､必須パラメタのようです｡

当該[Publisherのソースコード](https://github.com/electron-userland/electron-forge/blob/master/packages/publisher/s3/src/PublisherS3.ts)をみるとregionが必要なことがわかります｡

### 対策

```json:package.json
 "config": {
    "forge": {
      "publishers": [
        {
          "name": "@electron-forge/publisher-s3",
          "config": {
            "region": "ap-northeast-1",
            "bucket": "xxx",
            "folder": "xxx",
            "public": false,
            "accessKeyId": "xxxx",
            "secretAccessKey": "xxx"
          }
        }
      ]
    }
  },
```

## AccessDenied: Access Denied

### 原因

S3へのアクセス権限がありません｡

### 対策

権限を付与します｡

publish先ディレクトリへの`PutObject`権限が必要です｡

当方の指定例です｡

```json:electron-publish-policy
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "s3:PutObject"
            ],
            "Resource": "arn:aws:s3:::<bucketname>/<directoryname>/*"
        }
    ]
}
```
VSCodeでJestを活用するための便利な拡張機能

Jestを少しでも簡単・便利に書くために便利な拡張機能です。

## Jestとは
JavaScript用のテストフレームワークです。

```sample.js
const sample = (param) => {
    return param + 1;
};
export default sample;
```

```sample.test.js
import sample from "./sample";

test("sample", () => {
    expect(sample(1)).toBe(2);
});
```

## 拡張機能
### 1. [Jest](https://marketplace.visualstudio.com/items?itemName=Orta.vscode-jest)
ファイルを変更したタイミングで、自動でJestが実行される。
コード記入→`yarn test`とか叩く必要がなくなるので、テストコードの記入やリファクタリングの高速化が図れる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2129291/675b6b93-c82e-4364-42b8-77872890bb0c.png)


### 2. [Jest Runner](https://marketplace.visualstudio.com/items?itemName=firsttris.vscode-jest-runner)
テストメソッド上部に Run | Debug が表示され、クリックすることで個別でのテストが実行できる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2129291/1f0e2ef2-b111-de9f-2f5e-3e27e503912e.png)

### 3. [Jest Test Explorer](https://marketplace.visualstudio.com/items?itemName=kavod-io.vscode-jest-test-adapter)
Jest Runnerが一覧からも実行できるようになったもの。
個人的にはJest Runnerよりも使いやすいと思う。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2129291/95cf0ee4-8e44-7030-ff8e-1c8ff88d37e5.png)



### 4. [Jest Snippets](https://marketplace.visualstudio.com/items?itemName=andys8.jest-snippets)
JestのMatcherをサジェストに表示してくれる。
`te`を選択した場合は`expect().toEqual();`となる。
`toEqual`以外も用意されているため、コーディングが早くなれる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2129291/7937c9b8-15fb-48d9-9d11-da11b1d8c734.png)
タップさせて吹き出しをpopさせる。

まずはpopさせるクラスを用意する

```swift
class PopViewController:UIViewController {
  override func viewDidLoad() {
        super.viewDidLoad()
         view.backgroundColor = .systemOrange
    }
}
```

遷移前の画面でコード作成。

```swift
//遷移先のVCをインスタンス化
  let viewController = PopViewController() //popoverで表示するViewController
//遷移方法をpopover
        viewController.modalPresentationStyle = .popover
//吹き出しのサイズを設定する
        viewController.preferredContentSize = CGSize(width: 200, height: 150)
        
        let presentationController = viewController.popoverPresentationController
//up 吹き出しを表示させる向きを設定する
        presentationController?.permittedArrowDirections = .up
//どこを基準に表示させるかのsourceViewを設定
        presentationController?.sourceView = cell
//吹き出しを表示させる位置を設定。
        presentationController?.sourceRect = cell.bounds
 //popoverさせるためのdelegateメソッド
        viewController.presentationController?.delegate = self
        present(viewController, animated: true, completion: nil)

```

必要なdelegateメソッドを用意

```swift

class ViewController: UIViewController, UIPopoverPresentationControllerDelegate{
//Iphoneで表示させる際のdelegateMethod
func adaptivePresentationStyle(for controller: UIPresentationController, traitCollection: UITraitCollection) -> UIModalPresentationStyle {
        return .none
    }

}
````

どこかで関数を発火すればOK!!
Git記事26選

# はじめに
**Git**に関して調べ問題を解決してくれた記事をストックしてきました。それを見やすいように一つの記事にまとめました。せっかくなので共有します。ここで紹介した記事のどれかにあたれば、Gitに関する基本的な問題は解決できるでしょう。

# コマンド、概念など

https://backlog.com/ja/git-tutorial/intro/01/

https://qiita.com/gold-kou/items/7f6a3b46e2781b0dd4a0

https://qiita.com/renesisu727/items/248cb9468a402c622003

https://zenn.dev/cryptobox/articles/abc13529ac0a04

https://qiita.com/ren0826jam/items/cf766a6fd43049b3cff4

https://qiita.com/shimotaroo/items/b73d896ace10894fd290

https://qiita.com/uhooi/items/c26c7c1beb5b36e7418e

https://qiita.com/ueki05/items/5c233773e3186989bfd3

https://qiita.com/yukibe/items/9ef9d54f2e7d53cfb51c

https://qiita.com/osamu1203/items/cb94ef9da02e1ec3e921

https://gigazine.net/news/20150407-10-years-git-linus-torvalds/


# Git Flow

https://qiita.com/KosukeSone/items/514dd24828b485c69a05

https://www.atlassian.com/ja/git/tutorials/comparing-workflows/gitflow-workflow

https://dev.classmethod.jp/articles/introduce-git-flow/

https://qiita.com/emjo1804/items/9daea4cd42980f179032

https://qiita.com/tbpgr/items/4ff76ef35c4ff0ec8314

https://zenn.dev/akino/articles/1dcecd60009dbb

# Git with VSCode

https://qiita.com/jesus_isao/items/63557eba36819faa4ad9

https://qiita.com/y-tsutsu/items/2ba96b16b220fb5913be

https://qiita.com/mnao305/items/b3c5f5943066a0bb8e2e

https://miya-system-works.com/blog/detail/128

# 各種テクニック

https://qiita.com/konatsu_p/items/dfe199ebe3a7d2010b3e

https://qiita.com/yamamoto7/items/fe15a1e7e360b4015fae

https://qiita.com/saika_0/items/0debd54158c788fa1b53

https://qiita.com/suzu12/items/b27cc76e96edb623a54f

https://qiita.com/suzu12/items/00a91591a36436e71a89

https://www.keisuke69.net/entry/2021/03/01/002010

https://zenn.dev/penguin4731/books/11bee5738e367f

# おわりに
他に追加したほうがいい記事がありましたら教えていただけると幸いです。
カレンダーの共有設定を自動化する

+ [ロールが”営業”のユーザーのカレンダー設定を一括で設定できないでしょうか？](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007eqxiP)

他のユーザのカレンダーを自分のカレンダーに表示しようと思うと画面からユーザを選んでの設定になります。
これを自動化できないかという質問がありました。

調べてみると同じ質問が見つかりましたが、できないという回答でしたね。
本当なのか？

調べてみるとカレンダーの共有時には
CalendarView　オブジェクトが追加されていることが分かりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/71c2142c-6bf8-46a1-c678-3014fe15615d.png)

また、このオブジェクトの説明にはちゃんとApexで追加する例題がありましたね。

https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_calendarview.htm?search_text=calendarview

```
Group userGroup = [SELECT Id FROM Group WHERE Name = 'Sales Group' LIMIT 1];
List<Id> groupId = new List<Id>();
groupId.add(userGroup.id);
List<GroupMember> groupMembers = [SELECT UserOrGroupId FROM GroupMember
   WHERE GroupId IN: groupId];

List<CalendarView> calendarViews = new List<CalendarView>();
for (GroupMember groupMember : groupMembers) {
   CalendarView calendarView = new CalendarView(name = 'Opportunity Close
    Dates', SobjectType = 'Opportunity', StartField = 'CloseDate', DisplayField =
    'Name', OwnerId = groupMember.UserOrGroupId);
   calendarViews.add(calendarView);
}
insert calendarViews;
```

では、これを参考に作りましょう。

```
public with sharing class addCalendarView {
    
    public static Boolean addRecord() {

        SET<String> targetUserSet = new SET<String>();
        //ここに必要なユーザ名をセットする
        targetUserSet.add('xxxxx@brave-hawk-3moqt3.com');
        targetUserSet.add('cbrown@apblue44210807.com');
        
        List<User> targetUserList = [SELECT Id, UserName,LastName,FirstName FROM User WHERE UserName =: targetUserSet];
        
        List<CalendarView> insertCalendarViewList = new List<CalendarView>();
        for (User u : targetUserList){
            for (User u2 : targetUserList){
                if ( u.Id <> u2.Id) {
                    CalendarView cw = new CalendarView();
                    cw.Name = u.FirstName + ' ' + u.LastName;
                    cw.SobjectType = 'Event';
                    cw.StartField = 'StartDateTime';
                    cw.DisplayField = 'Subject';
                    cw.OwnerId = u2.Id;
                    
                    insertCalendarViewList.add(cw);                    
                }                
            }
            
            
        }
        
        if( insertCalendarViewList.size() > 0) insert insertCalendarViewList;
        
        return true;
    }

}
```

テストクラス

```
@isTest
public class addCalendarView_test {

    @isTest
    public static void test01() {
        
        Test.startTest();
        addCalendarView.addRecord();
        Test.stopTest();
        
        List<CalendarView> targetCalendarViewList = [select Id,Name,SobjectType,StartField ,DisplayField,OwnerId FROM CalendarView];
        System.assertEquals(targetCalendarViewList.size(), 2);
    }
}
```
実際に処理できましたが、何故かMy Calendarsに分類されてしまいました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/939615a5-b82e-bb9c-9581-9ba6af347e44.png)


元の質問

[カレンダーの共有について](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000Bshqa)
GCP AI Platform NotebookからCSVをDLする際にデータが途切れることを回避する方法

# 問題

GCP AI Platform Notebookでpythonを用いて計算を行った後、CSVを出力したとします。これをそのままDLしたら、テーブルの途中までしか入っていませんでした。

# 解決方法

zipに変換してからDLすることで回避できました。

```python
import zipfile

with zipfile.ZipFile('./output/new_comp.zip', 'w', compression=zipfile.ZIP_DEFLATED) as new_zip:
    new_zip.write('../output/test.csv', arcname='test.csv')
```
latexに入れる図のpdfをいい感じにまとめてcropする

# 問題設定

論文投稿時、latexに includeしてるpdfの図の余白が無駄な問題を解決したいです。
そこで、latex環境が整ってるPC(MacTexとかインストールした場合)だと、付随してpdfcropというコマンドがインストールされてます。

```sh
$ pdfcrop
PDFCROP 1.40, 2020/06/06 - Copyright (c) 2002-2020 by Heiko Oberdiek, Oberdiek Package Support Group.
Syntax:   pdfcrop [options] <input[.pdf]> [output file]
```

これを使って、下記のように階層化された論文の図を、まとめて pdfcropにかけます

ちなみに適当な図の plotとして[このサイト](https://matplotlib.org/stable/gallery/lines_bars_and_markers/scatter_masked.html#sphx-glr-gallery-lines-bars-and-markers-scatter-masked-py)のものを使いました

```sh
$ tree
├── figs
│   ├── aaa
│   │   ├── a-1.pdf
│   │   ├── aa-1
│   │   │   └── a-01.pdf
│   │   └── aa-2
│   │       └── a-02.pdf
│   └── bbb
│       └── b-1.pdf
└── plot.py

```

# pdfcropをディレクトリ以下のpdfに全て適用

```sh
$ pwd
/Users/XXX/figs
$ find ./ -type f -exec pdfcrop {} {} \;
```

ちなみに、二個目の `{}` をはずして実行すると、pdfファイルが置き換えられず、`a-1.pdf` に対しては、 `a-1-crop.pdf` を生成してくれます。


# 置き換え前と置き換え後で比較
左が、crop前で、右がcrop後のpdfを入れた場合です。texでマージン操作などはしていません。

![Screenshot 2021-10-10 at 4.24.13 PM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/56510/9cf5afe1-bece-4251-9031-d34cba49e401.png)
![Screenshot 2021-10-10 at 4.24.21 PM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/56510/57590015-5ded-c312-5b91-267938e576a0.png)


# ソースコードなど
- Overleaf (Read Only)
https://www.overleaf.com/read/ymxhyphgycnf

# 終わりに
もっといい方法があれば教えてください。
【覚書】JSDoc + ts-check で as any as を実現する

`//@ts-check` で JS を書いていて、
`as any as` とか `as unknown as` とか
`(window as any).hoge` とかみたいな書き方がしたくなったので調べた。

# ふつうはこうなる

```js
//@ts-check

document.createElement("div").innerText = 12345;
// -> Type 'number' is not assignable to type 'string'. ts(2322)
```

# TypeScript ならこれでゴリ押せる

```ts
document.createElement("div").innerText = 12345 as any as string;
document.createElement("div").innerText = 12345 as unknown as string;
```

でも JSDoc では当然このような書き方はできない・・・

# `ts-expect-error` は代案にならない

TypeScript では `as any as` を使用することで、以下のように変数の型をそのまま変更できるが

```ts
const value = 12345 as any as string;

type X = typeof value;
// -> type X = string
```

`@ts-expect-error` はエラーを無視するだけなので、変数の型は変化しない。

```js
const value = 12345;
//-> const value: 12345

//@ts-expect-error
document.createElement("div").innerText = value;
```

だから `@ts-expect-error` を `as any as` と同じように使うことはできない。

# JSDoc の `@type` だとエラる

```js
//@ts-check

/** @type {string} */
const value = 12345;
// -> Type 'number' is not assignable to type 'string'. ts(2322)

document.createElement("div").innerText = value;
```

# これが JSDoc の正解

といっても、あまりスマートじゃないし裏技じみてるが。

```js
//@ts-check

/**
 * @template T
 * @param {(type: T) => any} def
 * @param {unknown} from
 * @returns {T}
 */
const resolveTypeAs = (def, from) =>
  //@ts-expect-error
  from;

const value = resolveTypeAs(
  /** @param {string} _ */ (_) => _,
  12345
);
// -> const value: string

document.createElement("div").innerText = value;
```

`resolveTypeAs` という、型を強制的に書き換える関数を作る。
第一引数で `@param` に無名関数の引数として `T` となる型を渡す形にした。
令和3年度データベーススペシャリスト 自己解答 (午後2 問2） ※記載中

# 午後1 問1 60分

### 設問1 - (1)
ア:チェーン法人締め契機

リレーション:
物流拠点 -> 引当在庫
物流拠点 -> 払出在庫
チェーン法人 -> チェーン店舗
商品 -< PB商品
商品 -< NB商品
荷姿区分 -> 払出在庫
締め契機 -> チェーン法人締め契機

### 設問1 - (2)
イ:ピース梱包内訳

リレーション:
受注 - 店舗別梱包指定受注
出庫指示番号 - 出庫指示番号
出荷実績 -> 梱包実績
梱包実績 -> ピース梱包実績
梱包実績 -> ケース梱包実績
出庫実績 -> ピース出庫実績
出庫実績 -> ケース出庫実績
ピース梱包実績 -> ピース梱包内訳
ピース出庫実績 -> ピース梱包内訳
ケース出庫実績 - ケース梱包実績

### 設問1 - (3)
a:商品コード(PK)、チェーン法人コード(FK)
b:商品コード(PK)、売り上げ金額ランク
c:チェーン法人コード(PK)、商品カテゴリコード(PK)、商品カテゴリ名
d:
e:物流拠点コード(PK)、商品コード(PK)、製造ロット番号(PK)、在庫数、引当済数、引当可能数
f:物流拠点コード(PK)、商品コード(PK)、製造ロット番号(PK)、荷姿区分（PK)、荷姿別在庫数

### 設問1 - (4)
g:
h:受注番号(PK)、チェーン店舗コード(PK)
i:
j:出庫指示番号(FK)
k:
l:
m:
n:拠点コード(FK),締め年月日（FK),回目(FK)
o:
p:荷姿区分(FK)
q:出庫ケース数
r:出庫ピース数
s:段ボール箱区分、出荷実績番号(FK)
t:出庫実績番号(FK)
u:梱包実績番号(PK),出庫実績番号(PK)
v:車両番号、出荷年月日時刻

### 設問2 - (1)
リレーション:
受注先 -< チェーン本支部
受注先 -< チェーン店舗

### 設問2 - (2)
あ:チェーン組織コード(PK)
い:受注先フラグ
う:
え:
お:
か:
き:<font color="OrangeRed">(未記載)</font>
く:<font color="OrangeRed">(未記載)</font>

### 設問2 - (3)
①:<font color="OrangeRed">(未記載)</font>
②:<font color="OrangeRed">(未記載)</font>
③:<font color="OrangeRed">(未記載)</font>

# 感想

あとで書く
requestAnimationFrameで端末負荷を測定する

## 背景
最近ブラウザから端末負荷を測定したい場面に出くわしました。
弊社ではwebrtcを扱っていて、ライブ中の端末負荷の変化を測定したかったのですが、残念ながらブラウザAPIは用意されていません。  

そこで`requestAnimationFrame`apiを使用して画面の描画回数を測定することで、間接的に端末負荷の指標とすることにしました。

## Window.requestAnimationFrame()
requestAnimationFrameは本来はアニメーションを実装するために使用するAPIです。

https://developer.mozilla.org/ja/docs/Web/API/Window/requestAnimationFrame
> ブラウザにアニメーションを行いたいことを知らせ、指定した関数を呼び出して次の再描画の前にアニメーションを更新することを要求します。

ブラウザが画面を描画するたびにコールされ、そのタイミングで任意の関数を実行したい場合に使用するのが一般的かと思います。

今回は、ブラウザが画面を描画するたびにコールされることを利用して、描画1回あたりに要した時間を計測しています。
1回あたりに要した時間が分かれば、画面描画のfpsも計算することができます。
つまり、端末負荷が上がって画面がカクカクする状態になればfpsも下がることを利用して、端末負荷の指標としましました。

正常時の基準とべきfpsは60ですが、注意も必要です。

> このコールバックの回数は、たいてい毎秒 60 回ですが、一般的に多くのブラウザーでは W3C の勧告に従って、ディスプレイのリフレッシュレートに合わせて行われます。

特にゲーミング用のディスプレイなどはリフレッシュレートが高く設定されている場合もあり、必ずしも60を基準にできるとは限りません。

## そもそももっと直接計測する方法はないのか？
#### google meetはどうやって端末負荷を計測しているのか？
googleの公式ではないので確かではないですが、chrome extensions apiを使用していると思われます。

https://stackoverflow.com/questions/64442820/how-is-google-meet-able-to-show-cpu-usage

試しにgoogle meetをchrome以外のブラウザでアクセスしてみると、cpu使用率のグラフが表示されなくなっています。
かなり有力そうです。

残念ながらextensionsのapiをfrontendのコードから呼び出すことはできないので断念しました。
googleは外部に公開していない内部apiを通じて取得しているのではなかろうかと推測されます。

## 実装
requestAnimationFrame()のコールバック関数の中で、再起的にrequestAnimationFrame()を呼び出しています。
60回ごとに平均を計算しています。（60はあくまで目安です）

~~ポイントは`Infinity`です。理由が分かっていないのですが、時々`lastCalledTime`と`currentTime`が一致してしまうことがあり、fpsが`Infinity`になってしまいます。~~
これを避けるために、`Infinity`を除外する処理を加えています。
** requestAnimationFrameのcallbackの引数に渡ってくる、`highResTimestamp`を使うことでこの問題は解消できました。
（一応Infinityのチェックを入れてますが、なくても良いかもしれません）

```typescript
const measureFps = () => {
  let lastCalledTime: number | undefined;
  let counter = 0;
  let fpsArray: number[] = [];

  const calcFps = (highResTimestamp: DOMHighResTimeStamp) => {
    if (lastCalledTime === undefined) {
      lastCalledTime = highResTimestamp;
    } else {
      const delta = (highResTimestamp - lastCalledTime) / 1000;
      lastCalledTime = highResTimestamp;
      const fps = 1 / delta;

      if (counter >= 60) {
        const sum = fpsArray.reduce((a, b) => a + b);
        const average = sum / fpsArray.length;
        counter = 0;
        fpsArray = [fps];
        console.log({ average });

      } else if (fps !== Infinity) {
        fpsArray.push(fps);
        counter++;
      }
    }
    requestAnimationFrame(calcFps);
  };

  requestAnimationFrame(calcFps);
};
```
参考： https://gist.github.com/WA9ACE/d51659371a345a9327bd

それほど多くもないですが、`Infinity`を弾いた分は誤差になるので根本解決はしたいなと思ってます...

それにしてもネイティブアプリはいいなぁ。読んで頂きありがとうございました！
【Javascript】画像URLを入力した瞬間に画像プレビューできるテキストエリアを作ってみた

#### はじめに
最近業務でjavascriptでUI実装をする機会が増え、その最中今後も使いそうな機能については備忘録をのこしておこうと思っての投稿です！
「ネット検索した画像URLをそのまま画像出力をする機能が必要だったためその実装メモです！
### こんなかんじ👇

![プレビュー.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549258/da30a6dd-c841-d5dc-75ab-887bceae3cfc.gif)


#### 完成コード
```php:hoge.blade.php



     // 画像URL入力
         <input type="url" id="service-infomation-image-url" oninput="serviceInfomationImagePreview()" name="image_url[]"  placeholder="画像URLを入力してください">

             <div class="item-wapper6"> //画像マウスオーバーで拡大するcss
               <div class="img-wapper6"> //画像マウスオーバーで拡大するcss
                 <span>
                   <div id="image-position" class="-ml-16 mr-80 -mt-5"></div>
                 </span>
               </div>
             </div>
     
          //Javascript
        <script type="text/javascript">
        function serviceInfomationImagePreview() {
          var url = document.getElementById("service-infomation-image-url");
          var urlValue = url.value ;
          var imagePosition = document.getElementById("image-position");
          imagePosition.innerHTML = '<img src="' + urlValue + '" class="mt-7 ml-16 w-full h-full object-center object-cover lg:w-8 lg:h-8" />';
        }
        </script>
```
id="image-position”のタグの配下領域にこのimgタグをセット。
textareaタグに入力した値がこの　このimgの値に動的にセットさせる。
　この処理のトリガーをinputタグに入力したタイミングにするため
oninput="serviceInfomationImagePreview()とします。
　こうすることで入力した時点でurlの画像が即時描画という流れです！

```css:hoge.css
.item-wapper img:hover {
    transform: scale(3);
    transition-duration: 0.3s;
    margin:0 0 0 30px;
}
 
.item-wapper img{
    transition-duration: 0.3s;
}
```
画像マウスオーバーで拡大するcss
[heroku]一般的なデプロイまでの流れ

# はじめに
本記事では、Herokuの一般的なデプロイまでを記述します。
忘れてしまったり、理解できていない部分が多かったので、アウトプットします。

# 手順
### Heroku CLIインストール

```
% brew tap heroku/brew && brew install heroku
```

```
% heroku --version
これでバージョン確認することもできる
```

```
% heroku login --interactive
ログインするため、メールアドレスとパスワードを入力
パスワードは表示されない

ログインできれば
Logged in as メールアドレス
と表示される
```

### Heroku上にアプリケーションを作成

```
% heroku create アプリケーション名
Heroku上に作成するものをカレントディレクトリにしておく
```

```
設定ができたか確認できる
% git config --list | grep heroku
```

### HerokuでMysqlを使用できるようにする
`Heroku`では、
使用するデータベースの設定が、`デフォルト`で`PostgreSQL`になっているので、
ClearDBアドオンを追加し、
MySQLを使用するための設定を行います。

```
% heroku addons:add cleardb

% heroku_cleardb=`heroku config:get CLEARDB_DATABASE_URL`

% heroku config:set DATABASE_URL=mysql2${heroku_cleardb:5}
```

### Heroku上に`master.key`を設定する
`環境変数`として`master.key`の値を設置します。

`Herokuへプッシュする前に設定します`

```
% heroku config:set RAILS_MASTER_KEY=`cat config/master.key`
「RAILS_MASTER_KEY」という変数に値を設定する
```

```
% heroku config
環境変数を設定できたか確認
```

### 動作環境を変更
私が普段使用しているRubyのバージョンでは、Herokuのstackは使用できませんので、
ここで変更する必要があります。

Heroku-20
↓
Heroku-18

```
% heroku stack:set heroku-18 -a アプリケーション名
```

### Herokuへアプリケーションを追加

```
% git push heroku master
```

### Heroku上でマイグレーションファイルを実行
pushしただけでは、
データベースにはマイグレーションの情報が反映されないため、
`heroku run`をします。

```
% heroku run rails db:migrate
```

### 公開情報を確認

```
% heroku apps:info
以降に、
URLが表示されるので、アプリケーションを確認します。
```

### エラー発生時のログの確認

```
% heroku logs --tail --app アプリケーション名
これでログを確認することができます。
```

以上です。


# 終わりに
Herokuのデプロイの方法は頭に入っていると思っていましたが、
デフォルトが`PostgreSQL`だったりと、理解が要所要所抜けているなと感じました。

デプロイしなければアプリケーションを作成できたことにならないですし、
ここは正確に理解します。

明日も頑張ります！
社内の有志でWebサービスを作った

# 作ったもの

エンジニアの"めんどくさい"を無くすためのWebサービスです。チームのスキルマップを作ったりMarkdown形式でドキュメントを書けます。Twitter等のアカウントでログインして使用できます。

[NekoPointer](https://nekoptr.com/)

# 使ったプログラミング言語とか

*  Python(DjangoとFlask)
*  Java(Spring Boot)
*  Vue.js
*  Angular
*  Ruby on Rails
*  C++
*  PostgreSQL

# 技術的な知見

※以下は個人の感想です。所属する組織の公式見解ではありません。

## Django

DjangoはPythonのWebフレームワークで、今回のプロジェクトではrestframeworkを使用し、Web APIの実装に使用しました。モデル定義をPythonのコードで行い、直接SQLを記述することなくDB操作が可能です。restframeworkを使用することでDBから取得したレコードをJSONにシリアライズすることができ、例えばIDからユーザ情報を検索して返すようなAPIであればほとんどコードを書くことなく実現できます。シンプルな処理であればとても簡単です。シンプルな処理なら。Djangoに限らずフルスタックなフレームワークにはありがちだと思いますが、ちょっとでも凝った処理をやろうとすると苦労します。このへんは勉強不足な面もありますが、restframeworkはわりと日本語の資料も少ないので結構大変です。DBのマイグレーション機能は便利。

## Java

好みの問題だとは思いますが、Web APIの実装でJavaとSpring Bootは無難な選択肢だと思います(現時点では)。Pythonなどの動的型付け言語はコード規模が大きくなるとつらいし、Rustはまだフレームワークの選択面では枯れていない印象です。個人的にはJavaは好きではないのですが...。

## AngularとVue.js

スキルマップ作成機能はAngular、その他はVue.jsを使用しました。Vue.jsのほうがとっつきやすく資料も多いのでこれから勉強する人はやりやすいと思います。多人数で開発するならAngularの方がいいかもしれませんが、今回の規模だとあまりメリットが生かせませんでした。

## C++

[書いた](https://qiita.com/h_yasunori/items/a4e75507f72dead183f8)

# サービスを作ろうとした動機

※以下は個人の感想です。所属する組織の公式見解ではありません。

## 会社の知名度アップ

現状特に達成できてないですが...。

## 技術力の向上

本を読んでプログラムを学べるタイプの人と実装してみないと理解が進まないタイプがいて、後者の人が勉強しやすい環境を作ろう、というのが目的の一つでした。Webサービスを一人で開発し運用していくことはなかなか大変なのでじゃあみんなで作りますか、というのが最初の思い付きでした。仕事をしていく中である程度勉強できるのがいいのですが、実際のシステム開発は数年間に渡って開発や保守が続けられることが多く、なかなか新しい技術に触れることができません。
実際やってみると開発の時間は思うように確保できないし、新しいことを勉強しながら実装するので思ったような進捗を出せず苦労しました(当たり前と言えば当たり前ですけど)。
IT業界とタイムスタンプ

![01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2154088/653776e2-98b1-f5a5-d1a2-e8bc41f8dfa8.jpeg)
![02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2154088/d44c0376-4a31-72d9-199f-e7cbaab34933.jpeg)
![03.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2154088/89fe75d6-49a7-0a9a-db40-d1c1ee3ffb25.jpeg)
![04.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2154088/62240660-6136-6b84-d467-842e8f9faaf4.jpeg)
![05.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2154088/eacff4d1-2837-3317-db97-dedf53efc5c5.jpeg)
![06.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2154088/94176078-8c5b-3d9a-5f5e-4d7490570342.jpeg)
![07.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2154088/50533a62-ea0b-14db-4f6e-733fcfc6f82c.jpeg)
![08.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2154088/0c9476c7-3a94-3c56-c751-706977fe73cc.jpeg)
令和3年度データベーススペシャリスト 自己解答 (午後1 問1、3）

# 午後1 問1 60分

### 設問1 - (1)

a:付与ポイント
b:発行日時
c:支払金額
d:購入数
e:ポイント設定コード(FK)
f:ポイント付与率
g:<font color="OrangeRed">(未記載)</font> -> ★配布上限数?
h:クーポンコード(PK)
i:会員コード(PK) ★
j:クーポンコード(PK)
k:レシート番号(PK)

### 設問1 - (2)

クーポン設定対象店舗 <- 店舗
クーポン設定 -> クーポン設定対象店舗
クーポン設定 -> クーポン配布
クーポン設定 -> クーポン利用
クーポン利用 -> 支払
支払方法 <- ポイント設定

### 設問2 - (1)

候補キー:
{加盟企業コード、加盟企業商品コード}、{加盟企業コード、横断分析用商品コード}

部分関数従属:あり、加盟企業コード -> 加盟企業名

推移的関数従属:
あり、{加盟企業コード、加盟企業商品コード} -> 横断分析用商品コード(★) -> 横断分析用商品名

(★) 候補キーの一部なので推移的関数従属にはならない（気がする）

### 設問2 - (2)

横断分析用商品コードの設定には数日を要するため(23文字) 

(3)
正規化:
第1正規形

関係スキーマ:
加盟企業: 加盟企業コード(PK)、加盟企業名、契約開始日、契約終了日
加盟企業商品: 加盟企業コード(PK)、加盟企業商品コード(PK)、加盟企業商品名、JANコード、横断分析用商品コード(FK)
横断分析用商品: 横断分析用商品コード(PK)、横断分析用商品名

### 設問3 - (1)

<font color="OrangeRed">(未記載)</font> ★支払いの翌日以降にポイントの後付けを行なった場合

### 設問3 - (2)

付与ポイントをポイント残高に反映したかを判断するフラグ

# 午後1 問3 30分(途中時間切れ)

### 設問1 - (1)
イ:1000 (= (1,6000,000 / 400 / 2 / 2))
ロ:3000 (= (1,6000,000 / 400 / 2) + (1,6000,000 / 400 / 2 / 2))
ハ:COUNT(*) ★
ニ:TOTAL
ホ:沿線

### 設問1 - (2)
テーブル定義の変更なく商品の入れ替え処理ができる(24文字)

### 設問1 - (3)
a:物件コード,'A1',1
b:エアコン='Y'
c:UNION ★
d:物件コード,'A2',1
e:オートロック='Y'

### 設問1 - (4)
あ:1,200,000
い:2

### 設問2 - (1)
f:LEFT JOIN ★
g:LEFT JOIN ★
h:S1.設備コード = 'A1' ★
i:S2.設備コード = 'A2' ★
j:S.設備コード IN ('A1','A2') ★

### 設問2 - (2)
<font color="OrangeRed">(未記載)</font> ★(30文字)

### 設問2 - (3)
k:<font color="OrangeRed">(未記載)</font> BS1.物件コード = 'A1'
l:<font color="OrangeRed">(未記載)</font> 'Y'
m:<font color="OrangeRed">(未記載)</font> 'N'
n:<font color="OrangeRed">(未記載)</font> LEFT JOIN ★
o:<font color="OrangeRed">(未記載)</font> 物件コード = 'A1'

※ ★: 見直したい箇所です

# 感想

問1: 問題文を読み進めていくが、概念データモデルや関係スキーマがなかなか埋められず、時間だけが過ぎていくので焦った。推移的関数従属の定義がきちんと頭に入ってなかったせいで設問2に時間がかかった。設問3は見直すと内容的には簡単だった。

問3: 時間がない状態でよく解けた方だと思う。全体的に言えることだが全ての問題を解こうとせず、高得点の問題を解く方向に舵を切った方がよいと思った。