OmniAICreator/Qiita-1.07M huggingface dataset:
BunでMongoDB/mongooseを使う

一昨日、Bunのネイティブ実装であるSQLiteを試してみて動いたのに気をよくして今日はMongoDBをやってみました。

Node.jsでお馴染みの MongoDB 用のフレームワークmongooseを使ってスキーマを作り接続します。

とりあえず、Bunサイトのサンプルを少し補い試しただけなので軽く記録を残しておきます。

Bun>MongoDB 

https://bun.sh/guides/ecosystem/mongoose


```sh
# mongoose をインストールする
mkdir mongoose
cd mongoose
bun init
bun add mongoose
```
```sh
# スキーマ用スクリプトを書く
vi schema.ts
```

```js: schema.ts スキーマ用スクリプト
import * as mongoose from 'mongoose';

const animalSchema = new mongoose.Schema(
  {
    name: {type: String, required: true},
    sound: {type: String, required: true},
  },
  {
    methods: {
      speak() {
        console.log(`${this.sound}!`);
      },
    },
  }
);
```

```sh
# 実行用スクリプトを書く
vi index.ts
```

```js: index.ts 実行用スクリプト
import * as mongoose from 'mongoose';
import {Animal} from './schema';

// connect to database
await mongoose.connect('mongodb://127.0.0.1:27017/mongoose-app');

// create new Animal
const cow = new Animal({
  name: 'Cow',
  sound: 'Moo!',
});
await cow.save(); // saves to the database

// read all Animals
const animals = await Animal.find();
animals[0].speak(); // logs "Moo!"

// disconnect
await mongoose.disconnect();
```
```sh: mongodを起動する
# mongod をインストール
sudo apt install mongodb-server-core
# db用のディレクトリを作る
sudo mkdir -p /data/db
# とりあえず今回は自分のユーザー権限で動くようにした
# 例 sudo chown hoge:hoge /data/db
sudo chown ユーザー名:グループ名 /data/db
# 試しなのでパスワードなど無しでmongoDBを起動する
mongod --journal --smallfiles --port 27017
```
※実際に使う時はパスワード設定など必ずしましょうね。
※この場合、AzureやAWSなどのクラウドなら ネットワークの受信インバウンドの port 27017 をTCPで開けておいたりします。

ここまでで port 27017に立ち上がれば、あとは index.ts を実行すると、Cow から Moo! と返事が返ってきます。

```sh:実行する
# 実行する
bun index.ts
# 結果
Moo!
```
因みに、mondodの起動は例えばこんな感じで確認できます。
```sh:mondodがport 27017に起動してるか確認する
$ ps ax | grep mongod
 116808 pts/2    Sl+    0:03 mongod --journal --smallfiles --port 27017
```

P.S. 「実際に使う時はパスワード設定など必ずしましょうね。」と書きましたが、大事なことなのでおまけで説明しておきますね。

ざっとこんな感じかな。

```sh:

# mongod --journal --smallfiles --port 27017 付近を
# 例えば下記のようにします

# 
# db用のディレクトリを作る 上記では/data/dbでしたが、
# 複数の mongod を走らせる場合用に/data/db/mydbとしておきます
sudo mkdir -p /data/db/mydb
# log用のディレクトリを作る
sudo mkdir -p /db/log/mydb
# MongoDBの設定ファイルを作る
# 必要に応じて /etc/mongod.conf にbind_ipを設定する
# 


# 一旦、authなしで起動
$ mongod --journal --smallfiles --port 27017 --dbpath /data/db/mydb --fork --logpath /db/log/mydb/mongodb.log
$ mongo localhost:27017 # infomation

# これで以下のプロンプト入力を求められる

> use mydb #＜DB名＞を入れる
> db.createUser({
     user: "＜DBのユーザー名＞",
     pwd: "＜DBのパスワード＞",
     roles: [{
        role: "readWrite", db: "mydb"
    }]
 })
>exit # 終了

# その後、認証付きでmongodを起動する
$ mongod --journal --smallfiles --port 27017 --dbpath /data/db/mydb --fork --logpath /db/log/mydb/mongodb.log --logRotate rename --auth


# パラメータ
# --journal ジャーナリングを有効化します
# --smallfiles 小さなファイルサイズでストレージを最適化します
# --port リクエストを待ち受けるポート番号 デフォルト27017
# --dbpath データベースファイルを保存するディレクトリ
# --forkプロセスをフォークしてバックグラウンドで実行します
# --logpath ログファイルのパスを指定します
# 後で使う　
# --logRotate rename　ログローテーションのメソッド
# --auth　認証を使う
```
【SwiftUI】CustomAnimationを使って点滅アニメーションを自作する（iOS17）

# はじめに
iOS17から`CustomAnimation`というものが追加されました。
これは名前の通り、アニメーションをカスタムできる機能っぽいです。
使ってみたので記事にしておきます。

# サンプルアプリ
![Simulator Screen Recording - iPhone 15 - 2023-11-26 at 23.03.52.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/3d981e5a-c217-149f-ed20-ea9d954571ea.gif)

# 実装
経過時間の小数点第一の偶数と奇数を判定して進行値に前後する値を渡す事で、点滅させる事ができます。
```swift
import SwiftUI

struct ContentView: View {
    @State private var isHidden = false
    
    var body: some View {
        VStack(spacing: 10) {
            if isHidden {
                Circle().padding(20)
            }
            
            Button {
                isHidden.toggle()
            } label: {
                Text("アニメーション")
            }
        }
        .animation(.init(BlinkAnimation()), value: isHidden)
    }
}

struct BlinkAnimation: CustomAnimation {
    func animate<V>(value: V, time: TimeInterval, context: inout AnimationContext<V>) -> V? where V : VectorArithmetic {
        guard time <= 1 else { return nil }
        return value.scaled(by: timeBasedScale(time))
    }

    func timeBasedScale(_ time: TimeInterval) -> CGFloat {
        let assss = Int(time * 10)
        if assss % 2 == 0 {
            return time * 2
        } else {
            return time / 2
        }
    }
}
```

# おわり
以下のようにする事で使用側では簡潔に指定する事ができます。
```swift
extension CustomAnimation where Self == BlinkAnimation {
    static var blink: BlinkAnimation {
        .init()
    }
}
```

```swift
 .animation(.init(.blink), value: isHidden)
```
【Android】今さら聞けないlayout_width="0dp"にしなきゃいけないのはなぜ？

# はじめに
今回はレビューで　ConstraintLayoutの中で使われているLayoutに
```
android:layout_width="wrap_content"
android:layout_height="wrap_content"
```
を見つけ、layout_width="0dp"にできそうならしたほうがいいかもです　と意見した際に
なぜlayout_width="0dp"にした方がいいのかを自分の中で疑問に思ったので調べました。
その内容を自分の備忘録のために記事に残します。

# レイアウトの大きさを数字以外で指定する

android:layout_widthやandroid:layout_heightには数字以外にも
**match_parent** は　親に合わせる(なるべく最大サイズ)
**wrap_content** は子に合わせる（なるべく最小サイズ）
**match_constraint** は親がConstraintLayoutの場合に　変化する親のサイズに合わせてサイズを変更される
などで指定することができます。



# 本題
では、なぜlayout_width="0dp"にしなければいけないのでしょうか。
0dpを指定すると**match_constraint**を指定した時と同じになります。
また、layout_weightを合わせて指定する際に　「layout_weightでの幅計算」と「wrap_contentの幅計算」が両方計算するため無駄になってしまう。
パフォーマンスを上げるためにも、layout_weightを使う際にはLayoutサイズを0dpにした方が良いでしょう。
AtCoder初心者 DailyTrainingメモ 2023/11/26

# ABC242 B-問題
https://atcoder.jp/contests/adt_easy_20231017_1/tasks/abc242_b

![242B.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547298/17876519-2006-778b-9eb3-5478fa74a5cc.png)

**ポイント**
受け取る文字列をリストで取得し、ソートする。

````Python:242B.py
# リストで受け取る
S = list(input())

# リストをソートして昇順に文字を並べ替える
S.sort()

# "".join(S) でリストを結合する
print("".join(S))
````

# ABC294 C-問題
https://atcoder.jp/contests/adt_easy_20231017_1/tasks/abc294_c

![294C.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547298/b1d436bb-acda-9062-9461-947d3318abdc.png)

**ポイント**
・リストAとBを合わせてソートする　C = sorted(A + B)
・enumerate を使って、リストCの各値とインデックス +1 をDICへ格納する

````Python:294C.py
N,M = map(int,input().split())
# リストで受け取る
A = list(map(int, input().split()))
B = list(map(int, input().split()))

# リストAとBを合わせてソートする
C = sorted(A + B)

# enumerateで　文字とインデックス+1 を辞書に格納する
DIC = {}
for i, c in enumerate(C):
    DIC[c] = i + 1
# DIC = {c: i + 1 for i, c in enumerate(C)}


for a in A:
    print(DIC[a])
for b in B:
    print(DIC[b])
````
PlatformIOでRP2040-Zeroを動かす

最近は値段の安い[Seeeduino XIAO RP2040](https://www.switch-science.com/products/7634)を使うことが多かったのですが、秋葉原ラジオデパートの[Shigezone](https://www.shigezone.com/)さんでさら安価な[RP2040-Zero](https://www.switch-science.com/products/7886)が売っていたので購入してみました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/f8b2208b-9928-c5c7-eaf9-3ad29d357e17.png)

とりあえず「[PlatformIOでXIAO RP2040を動かす](https://qiita.com/ELIXIR/items/d8724138fc2b069bf1f1)」の記事と同じ設定でビルド＆書き込みできました。
追記：RP2040-Zeroの設定が追加されたので、そちらを使用するとよいかと思います。
```
[env:waveshare_rp2040_zero]
platform = raspberrypi
board = waveshare_rp2040_zero
framework = arduino
```
NEOPIXELおよびピンの番号は違う（というかピン数が多い）ので、[こちら](https://www.switch-science.com/products/7886)を参考にピン番号を変更したところ、LチカおよびNeoPixelで動作を確認できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/02558dbc-5bbf-5bd9-7231-86e3c83af0a6.png)

というわけで苦もなく使えそうですので、こちらのマイコンボードも積極的に使っていきたいと思います。
日本語データセットで10+ヶ国語を発話するTTS開発

韓国で開発をしている大学生です。初めて記事お作成してみます。



# 目次

0. 概要
0. 亜流雀々
0. 本プロジェクトの開発過程
0. 結果




# 概要

Japanese to Multi Language TTS - VITS (MB-iSTFT-VITS)

まず、このプロジェクトは日本語データセットで韓国語を発話できるようにするために始めたプロジェクトです。

その後、HANGULIZEプロジェクトを発見し、ミュートクリーナーにハングルのサイズを追加して10+ヶ国語を発火させることができるようになりました。 外国語を流暢に話す日本人だと感じたら、このプロジェクトは成功だと言えます。

# 亜流雀々

以下は、このプロジェクトに到達するために制作した亜流作です。
​
- RVC-VITS (https://github.com/kdrkdrkdr/RVC-VITS)
    特徴:RVCでデータaugmentation後に学習する
    >変換されたデータセットのイントネーションとキャラクターだけの特徴が生かされないイシューが発生
<br>

- JK-VITS (https://github.com/kdrkdrkdr/JK-VITS)
    特徴:該当言語に音素変換して似た発音ができるように誘導
    >似たような発音をするが正確な発音ができないイシュー発生




# 開発過程

- 音素変換ツールの修正

    既存に開発された[g2pk2](https://github.com/tenebo/g2pk2) の微細なエラー修正と日本語変換を含めてハングル発音に変えられるよう修正しました。 そうして作られたのが[g2pk3](https://github.com/kdrkdrkdr/g2pk3.git)です。 カントリーコードがなくても自分でハングルの発音に変えられる言語はg2pk3に内蔵された韓国語、日本語、英語です。    
    残りのサポート言語は、Hangulizeを通じてハングルに変換され、変換されたハングルを発音表記に変換します。
    Hangulizeもこのプロジェクトに適用できる形に修正しました。
    日本語は[pyopenjtalk](https://github.com/r9y9/pyopenjtalk)の内部コードを修正し、私の好みに合わせて[OpenJTALK](https://github.com/kdrkdrkdr/pyopenjtalk/blob/master/pyopenjtalk/openjtalk.pyx#L239)クラスを修正しました。






















---
- KSS韓国語音声データセットで事前学習モデル学習

    KSSデータセットを選択した理由は、音素クリーナーで使用する音素をハングルの字母で処理したためです。
計357K Stepsで事前練習を終えました。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/749838/2f6486fa-c27e-749a-9f21-281dfbbbbb04.png)
---
- データセット前処理および事前学習モデルを利用して微調整  
[JSUT](https://sites.google.com/site/shinnosuketakamichi/publication/jsut)日本語音声データセットのtranscriptファイルを前処理しました。
前処理過程は日本語→カタカナ→韓国語→韓国語発音→字母分離の順です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/749838/e906d2e0-488e-f233-d50b-754fbf1df0a2.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/749838/7404ffba-bba3-ca57-7bcd-d616e78f1f6a.png)

データセットの前処理後、2番で作った事前学習モデルを利用して微調整しました。
batch_size=32、sample_rate=44100で3000step学習しました。
微調整なので100Kまで学習する必要がなく、3000step以上学習する時、日本語話者からパッチムをしっかり聞くことができないからです。 ミュートクリーナーが韓国語の自毛基盤であるため、これを考慮しなければなりませんでした。



<br>
プロジェクトリンクわこちらで
<br>

https://github.com/kdrkdrkdr/JA2ML-VITS
IT系の資格を取る意味が最近分かりました。

# 記事の概要 
* 結論 資格を取得する意味
* おわりに

## 結論 資格を取得する意味
資格を取得する意味は結論
私がとある転職エージェントさんに質問してのがその答えでした。

私
「資格ってどうなんですか？」

 転職エージェントさん
「資格はいいですよ！皆さん資格を**勘違い**されてるんです。技術を身に着けるというより
**自分のベースを上げるためなんですよ！**」

この話を聞いたとき、なるほど！！！！と思いました。


どういうことかというと
ベース=**前提知識**ということだとその時気づきました。

例えば、ゲームをするためにはそれなりのスペックのパソコンが必要になりますよね。
* A君、B君はパソコンの組み立てできるぐらいの知識がある。
* C君パソコ知らない
といった感じで登場人物がいて最近話題のFPSゲームをやるために
ヨド○○カメラに3人でパソコンのパーツを買いに行ったとしましょう。

A君
「やっぱ144FPSだしたいから、RTX3070かRTX4070のグラボ欲しいよな～」

B君
「そうね～最近だと最低それぐらいのスペックないと厳しいよな～
　となるとボトルネックにならないようにCPUも第12世代core i7かZen3 Ryzen7が良いな」

A君
「その辺になってくると、簡易水冷も欲しくなるし金飛ぶわ～www」

B君
「それな～www」

C君
「心の声:グラボ?? RTX?? corei7?? Ryzen7?? わけわかん...
　興味があるからついてきたど話ついていけねぇ...」

といった感じで、C君は知識がないので何のことなのかさっぱりわからず話もついていけない
といった状況になります。

この状況をお仕事に当てはめると
案件に参画したけど、前提知識がないから話はついていけないし
業務に対しての理解もできずどんどん進んで地獄といった状況になりますよね。

そこで、資格の出番ってわけです。
* 資格はどういった範囲で知識が必要か明確にわかるので知識の基準になる。
* 取得できれば前提知識があるという証明になる。
* おまけに自己研鑽してますよアピールにもなる。


その証明を使って、より高いレベルの現場にいるチャンスができて
高い現場に行けてある程度できるようになれば技術が身についてきて給料UPも狙える。
**結果、自分のベース上がる**といったところです。

ましてやIT資格はどの会社でも使えるので、社内限定資格みたいなのよりよっぽど役に立つのかなと思います。
ちなみに、この話を聞いてからCCNPの勉強を始めました。


### おわりに
私は正直、資格なんて取らなくても給料上がるやんとか業務で身につけた方がよくね？
と考えていました。
当時、転職したらどのぐらいの年収になるのか気になり10人ぐらいエージェントさんと話していたのですが
一番の収穫はこの話でした。
この転職エージェントさんに会えていなかったら私は今頃、休日はダラダラとして何も無いまま
１年過ぎてたかもしれません。

本当に感謝です。

初投稿は技術とは全く関係ありませんが共有したくて記事にしました。
是非、会社に資格を取れ！と言われている方だったりIT未経験で転職したい方のモチベーションに
なれればと思います。

以上
Microsoft Copilot for Azure in Cosmos DB の設定手順と利用方法をまとめた

# はじめに
2023/11/15に`Azure Cosmos DB`の`Microsoft Copilot for Azure`のパブリックプレビューが始まりました。

https://azure.microsoft.com/ja-jp/updates/public-preview-microsoft-copilot-for-azure-capability-now-available-in-azure-cosmos-db/

`Micrososft Copilot for Azure in Cosos DB`を利用することで、自然言語の質問に基づいて`Azure Cosmos DB NoSQL`クエリを作成することができるので、`NoSQL`クエリの細かい文法を忘れてしまった場合でも、一々クエリの文法を調べる手間が省けます。`Microsoft Copilot for Azure in Cosmos DB`は、`Data Explorer`のクエリエディターと統合されており、煩雑な設定をすることなく簡単に利用可能です。本記事では、以下の`Microsoft`ブログの記事を参考にしながら、設定方法と利用方法を簡単にまとめました。

https://devblogs.microsoft.com/cosmosdb/microsoftcopilotforazureincdb/

# 設定手順
まず、`Azure`ポータルから利用するサブスクリプションを選択し、左のメニューから「プレビュー機能」をクリックします。するとプレリリース機能の一覧が表示されるためその中から、「Microsoft Copilot for Azure in Cosmos DB」を探して選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2452857/ada56f39-87b7-ae21-2ac4-8ce680daed33.png)

:::note info
この手順は、`Microsoft Copilot for Azure in Cosmos DB`がプレビュー段階のときのみ必要にります。
:::

https://learn.microsoft.com/ja-jp/azure/azure-resource-manager/management/preview-features?tabs=azure-portal

すると、ポータル右側に下図のような画面が表示されるため、「登録」を押します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2452857/61b07da6-2e4e-2b1b-53cc-32a706d5844b.png)

# 利用手順

利用するプレビュー機能の登録が終わったら、`Azure Cosmos DB`のリソースを選択します。概要画面の「データエクスプローラー」を押します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2452857/79b96c79-23d3-3d0d-9ebc-250edad0e920.png)

表示された画面で、「Query faster with Copilot」のタイルを押します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2452857/ef4d48df-cd4c-6fb6-7585-852dc3f3affa.png)

データエクスプローラーが表示され、`SAMPLE DATA` > `CopilotSampleDb` > `SampleContainer` > `Items`を選択すると、製品にまつわる様々なサンプルデータが保存されていることが確認できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2452857/0f8fdc3c-6bf9-fc74-7c69-071724cf34bd.png)

今回はこのサンプルデータに対して、`Microsoft Copilot for Azure in Cosmos DB`で`NoSQL`クエリを作成・実行していきます。`Copilot`の下に入力欄があるため、「CopilotSampleDBに保存されてるカテゴリー一覧を出力して」と試しに入力して`Copilot`を実行してみます。すると数秒で`NoSQL`クエリが作成されました。クエリを実行するために、画面の上の方にある「Execute Query」を押してみましょう。すると、カテゴリー一覧がリスト形式で出力されました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2452857/f2fce4f6-37ac-9486-12a3-85837c3cd7bd.png)

また、別の質問をしてみます。今度は「CopilotSampleDBの中で説明に"gold"を含む製品を絞り込み」と入力してクエリの作成・実行をしてみます。すると、期待値通りに"gold"を含む製品情報をリスト形式で出力してくれました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2452857/9ac36564-38a5-a52d-411d-e099ce4eb4f9.png)


# おわりに
`Microsoft Copilot for Azure in Cosmos DB`を利用することで、ノンプログラマーやデータベースに不慣れなユーザーでも、簡単にクエリを作成する点や、通常よりも迅速にクエリ作成ができるため、迅速なデータ取得ができる点にメリットがあると感じました。その一方で、本記事には載せていませんが、うまく`Copilot`に指示をしないと期待通りの出力が得られないケースもあったため、どのような指示をすると`Copilot`がうまくユーザーの意図を汲み取ってくれるのか、多少の経験が必要になりそうだと感じました。
AWS EC2に負荷ツールTaurusをインストールする

# やりたいこと

AWS DTLではjmeterしか使えず、taurusファイルで実行したかったのでEC2にいれてみて試してみました

https://gettaurus.org/

# やりかた
debian系ではこれなので

```bash
sudo apt-get install python3 default-jre-headless python3-tk python3-pip python3-dev libxml2-dev libxslt-dev zlib1g-dev net-tools
sudo python3 -m pip install bzt
```

yumでのインストールにそれぞれ変える

```bash
sudo yum update -y
sudo yum install python3 gcc python3-devel java-17-amazon-corretto tk-devel python3-pip net-tools libxml2-devel libxslt-devel zlib-devel -y
sudo python3 -m pip install bzt
```

あとは実行するだけです
ABC330をPythonで（A~E）

トヨタシステムズプログラミングコンテスト2023(AtCoder Beginner Contest 330)

https://atcoder.jp/contests/abc330

# A問題
問題通りに調べる
```python:A
_,L=map(int,input().split())
print(sum(a_i>=L for a_i in map(int, input().split())))
```


# B問題
その数$a_i$が
$L<=a_i<=R$のときは$a_i$
$a_i<L$のときは$L$
$R<a_i$のときは$R$
```python:B
n, l, r = map(int, input().split())
a = list(map(int, input().split()))

ans = []
for a_i in a:
    if l<= a_i <= r: ans.append(a_i)
    elif a_i < l:ans.append(l)
    else:ans.append(r)

print(*ans)
```
# C
尺取り法で調べる
```python:C
d = int(input())

ans = float("inf")
x = 10 ** 6
for y in range(10 ** 6 + 1):
    while x >= 0 and x ** 2 + y ** 2 > d:
        x -= 1
    a, b = abs(x ** 2 + y ** 2 - d), abs((x + 1) ** 2 + y ** 2 - d)
    ans = min(ans, a, b)
    x += 1

print(ans)
```
# D
oのある各地点において
その地点と同じ行と列にあるoの数-1の積の総和が答え
```python:D
n = int(input())
x = [0] * n
y = [0] * n
data = []
for i in range(n):
    d = input()
    data.append(d)
    for j, d_i in enumerate(d):
        if d_i == "o":
            x[i] += 1
            y[j] += 1

ans = 0
for i, d in enumerate(data):
    for j, d_i in enumerate(d):
        if d_i == "o":
            ans += (x[i] - 1) * (y[j] - 1)

print(ans)
```
# E
mexをheapで管理する
このときmexの候補は高々$n+1$なので
その範囲内で調べればよい
```python:E
from heapq import heappop, heappush

n, q = map(int, input().split())
a = list(map(int, input().split()))

mex = [i for i in range(n + 10)]
d = {i:0 for i in range(n + 10)}
for a_i in a:
    if a_i in d:
        d[a_i] += 1

for _ in range(q):
    i, x = map(int, input().split())
    i -= 1
    if a[i] in d:
        d[a[i]] -= 1
        if d[a[i]] == 0:
            heappush(mex, a[i])
    a[i] = x
    if x in d:
        d[x] += 1


    while d[mex[0]] > 0:
        heappop(mex)
    print(mex[0])
```
単体テストが楽しくなる。JUnitの使い方

# JUnitとは
JUnitとはJavaで単体テストを行う際に使用するフレームワークです。

単体テストとは、開発において何段階かテストを行う必要があるのですが、そのテストの中で一番最初に行うテストです。
1つの機能に対してテストを行うのは基本的には単体テストの段階であるため、テストが落ちた際に原因を探りやすいというのがメリットです。

１回テストを作成してしまえば、今後修正が加わった際に同じテストを実行するだけでコードのテストを行うことができます

JUnitでは作成したjavaクラスや関数毎にテストができます。

# JUnitの使い方

### <span>@</span>Test
<span>@</span>Testをメソッドに付与することでテストメソッドと認識させることができます

``` Java
@Test
public void testMethod() {

}
```

### Assert
Assertを使用することで値を比較してテストすることができます。

``` Java
public Int sumNum(int num1, int num2) {
  // num1とnum2の合計値を返す
  return num1 + num2;
}

public Boolean isCompareNum(int num) {
// numが5より大きければtrueを返す
  return 5 < num;
}

@Test
public void testMethod() {
  // sumNumの値が10であるかテストを行う
  int sumNum = sumNum(2, 8);
  assertEquals(sumNum, 10);

  // isUpperNumの値がtrueであるかテストを行う
  boolean isUpperNum = isCompareNum(10);
  assertTrue(isUpperNum);

  // isLowerNumの値がfalseであるかテストを行う
  boolean isLowerNum = isCompareNum(1);
  assertFalse(isLowerNum);
}
```

### <span>@</span>BeforeEach
<span>@</span>BeforeEachをメソッドに付与することで各テストメソッドを実行する前に実行することができます。

``` Java
@BeforeEach
public void beforeEach() {
}

@Test
public void testMethod1() {
}

@Test
public void testMethod2() {
}

// beforeEach() → testMethod1() → beforeEach() → testMethod2() の順序で実行される
```

### <span>@</span>AfterEach
<span>@</span>AfterEachをメソッドに付与することで各テストメソッドを実行した後に実行することができます。

``` Java
@AfterEach
public void afterEach() {
}

@Test
public void testMethod1() {
}

@Test
public void testMethod2() {
}

// testMethod1() → afterEach() → testMethod2() → afterEach() の順序で実行される
```

### <span>@</span>BeforeAll
<span>@</span>BeforeAllをメソッドに付与することでクラス内の全テストメソッドを実行する前に実行することができます。

``` Java
@BeforeAll
public void beforeAll() {
}

@Test
public void testMethod1() {
}

@Test
public void testMethod2() {
}

// beforeAll() → testMethod1() → testMethod2() の順序で実行される
```


### <span>@</span>AfterAll
<span>@</span>AfterAllをメソッドに付与することでクラス内の全テストメソッドを実行した後に実行することができます。

``` Java
@AfterAll
public void afterAll() {
}

@Test
public void testMethod1() {
}

@Test
public void testMethod2() {
}

// testMethod1() → testMethod2() → afterAll() の順序で実行される
```
tauri × Next.jsのデスクトップアプリでAPPRouterのDynamic Routesが使えなかった話

## はしめに
個人開発として最近、デスクトップアプリのフレームワークでTauriでの開発を行っていた時の話です。
フロントエンドに触ったことがあるNext.jsが使えるとのことで、やってみようと思いNext.jsのバージョン13から導入されたルーティングシステム[APPRouter](https://nextjs.org/docs/app/building-your-application/routing)を使って開発をしていました。

## 起こったこと
APPRouterではパスパラメータの場合に`post/[slug]`のようなディレクトリにするとslugがパスパラメータとして取得できるのでそれを利用した開発を行っていました。
開発環境での実行コマンドである`tauri dev`で実行しても正常に動作するため問題なく実装できているものと思っていました。
しかし、いざビルドしてみると。。。

下記のようなエラーが発生！！
```shell
Error: Page "/post/[slug]" is missing "generateStaticParams()" so it cannot be used with "output: export" config.
```
よくよく見てみると静的エクスポートを利用しているときには`generateStaticParams`を利用してビルド時にパラメータに設定する変数をあらかじめ取得して、静的パラメータの生成を行う必要があった（実行時にエラーはいてくれよ！！）
https://nextjs.org/docs/app/building-your-application/routing/dynamic-routes#generating-static-params

## 解決した方法
`generateStaticParams`を実装していくのは面倒だったのでパスパラメータからクエリパラメータにしたら可能なのでは？と思いパスパラメータからクエリパラメータへの変更を行いました。
今回は`next/navigation`にある`useSearchParams`を利用してクエリパラメータを取得しました
```Typescript 
"use client";

import { useSearchParams } from "next/navigation";
import Link from "next/link";

export default function Home() {
  const param = useSearchParams();
  const slug = param.get("slug");

  return <Link href={/post?slug=${slug}} >次のページへ</Link>;
}
```

上記の修正＋[slug]となっていたディレクトリ構成を変更してやっと意図した挙動が実装できました。
基本情報技術者試験合格に向けてやったこと

株式会社OMJテクノソリューションズ Advent Calendar 2023　5日目です！

# はじめに

わたしは今年基本情報技術者試験に合格しました。
他の方々のように密に計画を立てていませんが、
当時の勉強方法をご紹介します。
少しでもお役に立てられればなぁと思います。

:::note warn
不真面目な人間なのできっちりした勉強方法を決めていませんでした。
また当時の勉強方法なのでこの記事で合格の保証はできません。
:::

# A問題

## 1. 試験本を一通り理解する

まずはどんな内容を基に出題されるのか
一通り理解するために試験本を読みました。

こちらの本がおすすめです。

https://amzn.asia/d/eqcQPls

この「キタミ式イラストIT塾」シリーズ、すっっっっごくオススメです！
高校時代、ITパスポート合格を目指す授業がありまして、
そこで教材として渡されたのがこの「キタミ式イラストIT塾」のITパスポートの試験本でした。

わたしは図で物を覚えるタイプなので、
イラストで解説してくれてすごく助かりました。

## 2. 過去問をひたすら解く

電車通勤で計算問題以外を往復で40問。
帰宅後に計算問題を20問。
これをノルマに毎日ひたすら過去問を解くように意識していました。（少ないと思うけど、、）

出題傾向が大体似ているので、こういうパターンのときはこう考えるんだったけな、
という考え方ができるようになり、回答スピードが上がります。

お世話になったスマホアプリ

https://apps.apple.com/jp/app/2024%E5%B9%B4%E7%89%88-%E5%9F%BA%E6%9C%AC%E6%83%85%E5%A0%B1%E6%8A%80%E8%A1%93%E8%80%85%E8%A9%A6%E9%A8%93%E5%95%8F%E9%A1%8C%E9%9B%86-%E5%85%A8%E5%95%8F%E8%A7%A3%E8%AA%AC/id1211959354

主に計算問題でお世話になったサイト

https://www.fe-siken.com/fekakomon.php

（アプリとサイトの使い分けに意味があったわけではないです 😅）

## 3. 2 回間違えた問題に関する単元を復習、勉強したことをまとめる

スマホアプリだと前回正解したかが表示されたので、2 回目間違えたときに
その問題をメモに書いておいて
まとめてググって、当時ノート代わりに使っていたGoogleサイトにまとめて
度々見返したり、問題を解きながらそのGoogleサイトを見て
段々解けるようにしました。

Notionでもなんでもいいから自分の言葉でまとめてみる、っていうのが大事かなと。

# B 試験

## 動画を見ながらサンプル問題を解く

受験対策をしている途中で出題形式が変わったあとで
慌ててサンプル問題を解く方法に切り替えました。

といっても IPA 公式で公開されているサンプル問題だけだと不安だったので
この[Youtubeチャンネル](https://www.youtube.com/@itgakko)の動画を止めて回答して解説聞いて、、
というのを何回か繰り返しました。
B試験は複雑で回答に時間がかかって当日時間が足りないことが目に見えたので
本当に何度も画面が擦り切れるくらい（？）見ました。

# さいごに

大体の方は当日緊張に弱いと思ってるので
受験対策は念入りにして、早く正確に解けるようにしておいたほうがよいです。
ひとつ後悔があるとすれば、模擬受験形式の練習をしていなかったなぁと、、
制限時間付けて実際の形式に近い形で慣れておけば
当日あんなにテンパることもなかっただろうに、、、、

結論、たくさん過去問解いていればなんとかなると思います！！！
こんな記事を最後まで読んでくださった皆さんの合格をお祈りしております:bow_tone1:

それではまた！！
PHPからMySQLへPDO接続

# PHPからDBへアクセスしたい!
PHPでデータベースの情報を参照したいときに使える
## PDOとは
PHP5.1.0以降で動作するデータベース接続クラス。PEAR:Dbより高速。
## 実際に接続する
基本これ
~~~PHP:code.php
try {
    // DB接続
    $pdo = new PDO(
        'mysql:host=localhost;dbname=データベースのテーブルの名前;',
        'ユーザ名',
        'パスワード'
    );
    $stmt = $pdo->prepare('SQL文');
    $stmt->execute();
} catch (PDOException $e) {
    //エラー発生時の処理
} finally {
    //正常時の処理
    $pdo = null;
}
~~~
SQLをセットしたらOK
例
~~~PHP:code.php
try {
    // DB接続
    $pdo = new PDO(
        'mysql:host=localhost;dbname=データベースのテーブルの名前;',
        'ユーザ名',
        'パスワード'
    );
    $data = 'Qiita';
    $stmt = $pdo->prepare('INSERT INTO table (example) VALUES(:data)');
    $stmt->bindValue(':data', $data);
    $stmt->execute();
    //これより下は同じ
~~~

こんなかんじです。
SAP BTPのログイン方法をGoogle IAM変更した際に２段階認証がスキップされる問題

みなさま、お疲れ様です。

最近、SAP BTPのログイン認証方式を IAS から Google IAM に変更した際、２段階認証がスキップされる問題が発生しました。その際の解消方法をまとめました。

## やりたい動き
SAPへのログイン時
※事前に２段階認証の有効をGoogle側で設定しておく

１）Googleへのログイン
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2500270/0bb68309-50b8-16bb-c739-21b0ca6d9888.png" width=50%>

２）２段階認証プロセス
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2500270/1d0352ac-9acb-993e-efba-f44d3379d6fc.png" width=50%>

3)SAP BTP（サイトディレクトリ）へログインする
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2500270/92008ae9-768a-f4aa-5fc8-fbe8a64046f5.png" width=50%>

## 問題
上記の「やりたい動き」に記載している
２）２段階認証プロセスがスキップされてしまう問題が発生しました。

## 問題の原因
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2500270/fd6f7fe1-65f3-fa87-36a0-0c287f2fa36c.png" width=50%>

添付ファイルにある「このデバイスでは次回から表示しない」にチェックが入っているため、２段階認証がスキップされていたようです。
これはデフォルトでチェックが入っているので、トラップですね。

## 解消方法１
Googleサポート＞信頼できるパソコンを追加または削除する
https://support.google.com/accounts/answer/2544838?hl=ja&co=GENIE.Platform%3DDesktop
上記には、適宜端末に合わせた削除方法が記載されていますので、対象の端末を削除してください。

ただ、毎回毎回削除するのは面倒くさいですよね。
そもそもデフォルトでチェックが入っていることが気に入らない人もいると思います。

## 解消方法２
Google Workspace　管理コンソールにて
頻度＞信頼できるデバイスの登録を許可する
参考サイト：https://dxs.co.jp/blog/googleworkspace-twostepverification/
上記のチェックボックスを外すことによって
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2500270/137e6465-9298-b114-20ed-4d96d44d6bd3.png" width=50%>

絶対に２段階認証プロセスを実行させると言う人には、こちらの方が良さそうですね。
UI的にも、わざわざチェックボックスを外さなくて良いので楽です。

## おわりに
お疲れ様でした。
今回、Google IAMの２段階認証実施時に２段階認証が走らなくなり、非常に焦りました。
SAP BTPへのログイン認証方式もこれが使えたりあれば使えなかったり
一長一短のところもありましたのでみなさまにお伝えできればと思います。

## 参考記事
◆Googleサポート＞信頼できるパソコンを追加または削除する
https://support.google.com/accounts/answer/2544838?hl=ja&co=GENIE.Platform%3DDesktop
◆GoogleWorkspace ２段階認証の設定方法
https://dxs.co.jp/blog/googleworkspace-twostepverification/
Go：ゴルーチンとチャネルによる並列処理

# はじめに
Go言語は並列処理を容易に実現するための強力な機能を備えています。
特に**ゴルーチン**（**goroutines**）という軽量スレッドの概念を使って、並行処理を実装できます。
そして、**チャネル**（**channel**）という機能を使うことで、複数のゴルーチン間でデータの受け渡しを行うことができます。
この記事では、**ゴルーチン** **チャネル** を使った並行処理の実装方法を説明します。

# ゴルーチンとは
**ゴルーチン**とは、Go言語のランタイムによって管理される軽量スレッドです。
**ゴルーチン**は、スレッドよりもメモリ使用量が少なく、スレッドの切り替えにかかる時間も短いため、
多数のゴルーチンを同時に実行しても、メモリやCPUの負荷が大きく増加しないのが特徴です。

# ゴルーチンの使用例
```go
package main

import (
	"fmt"
	"time"
)

// 2. タスクの実行
func task(name string) {
	for i := 0; i < 5; i++ {
		fmt.Println(name, ":", i) // nameとカウンター値を出力
		time.Sleep(time.Millisecond * 500) // 0.5秒待機
	}
}

func main() {
	// 1. ゴルーチンの起動
	go task("goroutine1")
	go task("goroutine2")

	// 3. 待機
	time.Sleep(time.Second * 3)
	fmt.Println("メイン関数終了")
}
```

## 実行結果
並列処理のため実行するたびに順序は異なります
```sh
$ go run main.go
goroutine2 : 0
goroutine1 : 0
goroutine2 : 1
goroutine1 : 1
goroutine1 : 2
goroutine2 : 2
goroutine2 : 3
goroutine1 : 3
goroutine1 : 4
goroutine2 : 4
メイン関数終了
```

## コードの説明
1. **ゴルーチンの起動**：goキーワードを使うと、関数をゴルーチンとして起動できます。例：go task("goroutine1")。
この例では、task関数を2つの異なるゴルーチンで並行して実行します。

2. **タスクの実行**：各ゴルーチンは、task関数を独立して実行し、名前とカウンター値を出力します。

3. **待機**：main関数は、ゴルーチンが完了するまで少し待機する必要があります。
これは、main関数が終了するとプログラム全体が終了し、実行中のゴルーチンも中断されるためです。

# チャネルとは
**チャネル**とは、ゴルーチン間でデータの受け渡しを行うための機能です。
**チャネル**は、チャネル型の変数を宣言することで作成できます。

# チャネルの使用例
```go
package main

import (
	"fmt"
	"time"
)

// sendMessages関数は、特定のメッセージをチャネルに送信します
// 3. ゴルーチンで実行される関数
func sendMessages(c chan string, message string) {
	for i := 0; i < 3; i++ {
		c <- fmt.Sprintf("%s %d", message, i) // チャネルにメッセージを送信
		time.Sleep(time.Second) // 次のメッセージ送信まで待機
	}
}

func main() {
	// 1. チャネルの作成
	messageChan := make(chan string)

	// 2. 複数のゴルーチンを並列で実行
	go sendMessages(messageChan, "goroutine1")
	go sendMessages(messageChan, "goroutine2")
	go sendMessages(messageChan, "goroutine3")

	// 4. チャネルからメッセージを受信して出力
	for i := 0; i < 9; i++ {
		fmt.Println(<-messageChan) // チャネルからメッセージを受信
	}
}
```

## 実行結果
並列処理のため実行するたびに順序は異なります
```sh
$ go run main.go
goroutine3 0
goroutine1 0
goroutine2 0
goroutine2 1
goroutine1 1
goroutine3 1
goroutine1 2
goroutine2 2
goroutine3 2
```

## コードの説明
1. **チャネルの作成**：make(chan string)により、string型のデータを転送するためのチャネルmessageChanを作成しています。
2. **複数のゴルーチンの起動**：go sendMessages(messageChan, "goroutine1")などで、sendMessages関数をゴルーチンとして起動し、異なるメッセージで3つのゴルーチンを並列に実行します。
3. **ゴルーチンの関数**：sendMessages関数はゴルーチンで実行され、チャネルにメッセージを送信します。
4. **チャネルからの受信と出力**：メインゴルーチンはチャネルmessageChanからメッセージを受信し、それを出力します。それぞれ独立しているため、競合状態は発生しないのが特徴です。

# まとめ
ゴルーチンとチャネルを使うことで、Go言語では簡単に並行処理を実装できます！
文字の検索 Python3編

https://paiza.jp/works/mondai/string_primer/basic_step6
>文字列 S と文字 c が与えられるので、 c は S の何文字目に現れるかを調べてください。

何もみないで書いたやつ
```py
S = input()
c = input()
order = 1
for i in S:
    if i == c:
       print(order)
       break
    else:
        order += 1
```

答えは`enumerate()`という関数を用いていました
これを用いると、配列の要素だけでなくインデックスも同時に取得可能
下記の様に書きます　i, eleは変数名で変更可能。


 ```PY
s = input()
c = input()

for i, ele in enumerate(s):
    if ele == c:
        print(i + 1)

 ```
PowerAutomate: リストでフィルタークエリーを使って日付を使うときは、UTCを意識

# 背景

フィルタークエリーで日付を使った際に、たまにしか使わないからこその躓きポイントをメモ

# 概要

- タイトルの通り、フィルタークエリーでの日付は、UTC 比較ってだけ。

ついつい、Convert time zone 使って Local 時刻に変換して比較してしまって、「フィルタークエリーの書き方を疑ってしまう」ことがあるので注意

# 実例

## リストデータ

- こんな感じで二件ある場合に

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/866547f6-8581-9004-b61f-e79f2e08c863.png)

## フィルタークエリー

- 以下のように、UTC / LocalTime の二種でフィルターをかける

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/73e0c14d-b942-3fb5-5f2f-37b204547728.png)

## 結果

- こんな感じ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/eb269f40-f316-7236-ad9b-5ab48717af3e.png)

# あとがき

ついつい忘れがちで、なんで取得出来ない？って未だに悩むことも・・ :sweat: 

躓きポイントをいつかまとめておきたいものだ・・
エスケープ処理とDjangoの{{○○|safe}}（safeフィルター）

Djangoでwebアプリを作成しているときに出てきた{{○○|safe}}の意味がよくわかっていなかったので備忘録として周辺の知識と一緒に備忘録としてまとめておく。

# |safeとは
　Djangoのフィルター機能の一種。フィルター機能の話は[こちら](https://office54.net/python/django/template-filter-summary#section2)の記事にゆずるが、テンプレート側がビューから受け取った変数を加工するためのもの。

# |safeの役割
　safeの場合，受け取った変数に含まれているHTMLタグをエスケープさせずに処理してくれるようになる。例えば、変数にHTMLタグが含まれている場合、|safeがない場合はただの文字列として読み込んでしまうが、|safeをつけることでタグとして認識してくれる。

# エスケープ（エスケープ処理）とは？
　上でさらっと出てきたエスケープという言葉。何気なく使っているが、最近までどういう意味か説明できなかった。エスケープ処理なんて言葉もよく聞くが一体何のか。
どうやら、 エスケープ（処理）とは**プログラム中で使用する特殊記号をただの文字列として扱いたいときに行う（処理）** らしい。
　先ほどのDjangoの話だと、ビューからテンプレートに変数を渡すとHTMLタグはエスケープ処理され、ただの文字列の一部として渡されたことになる。
　逆に|safeはエスケープ処理を解除（エスケープを無効化）している。

 # 参考文献
[【Django】テンプレート：フィルターの一覧（使用方法、書き方）](https://office54.net/python/django/template-filter-summary#section2)
[Djangoの {{ 〇〇 |safe }}とは](https://qiita.com/Amana96/items/ba6d75b3f03f0d3f0479)
[エスケープ処理とは？](https://blog.senseshare.jp/escape.html#index1)
Recoil の公式チュートリアルやってみた

## 初めに
最近業務でわからんコードがあり、勉強しました
少し、使った技術等は公式とは変えましたが、環境的には問題ないっぽいんで悪しからず
また、全てのコンポーネント等はApp.tsxに記述していくそうです（公式ドキュメントでは）

※　App.cssとindex.cssの中身は削除してます

## Recoilとは
Metaによって開発されたグローバル状態管理ライブラリ

## まず、プロジェクトの立ち上げ
```
$ yarn create vite
? Project name: practice3
? Select a framework: React
? Select a variant: TypeScript + SWC
```
```
$ cd practice3
$ yarn
$ yarn add recoil
```

## ReactRootの作成
RecoilでStateをグローバルに管理するには、状態管理したいコンポーネントの最上位コンポーネントに`<ReactRoot>`を書いておく必要がある

```typescript
// App.tsx
import React from "react";
import { RecoilRoot, atom, selector, useRecoilState, useRecoilValue } from "recoil";

function App() {
    return (
        <RecoilRoot>
            <CharactorCounter />
        </RecoilRoot>
    );
}

export default App;
```

## Atomの作成
`atom`はアプリケーションの一部のStateを管理する。
ここで管理されるStateはアプリケーション全体で共有され、更新、取得が行われたコンポーネントのみ再レンダリングされる。

`key`: 他の`atom`、のちに紹介する`selector`と区別させるための一意なID。
`default`: 初期値、またはデフォルト値
```typescript
// App.tsx
const textState = atom({
    key: "textState",
    default: "",
});
```

## CharactorCounterコンポーネントの実装
```typescript
// App.tsx
function CharactorCounter() {
    return (
        <div>
            <TextInput />
            <CharactorCount />
        </div>
    );
}
```

## Selectorの作成
`Selector`とは`atom`で管理しているStateの値を何らかの形に加工して、返すもの。
今回で言うと、先ほど作成した`textState`というatomで管理している値の長さを返している。
```typescript
// App.tsx
const charCountState = selector({
    key: "charCountState",
    get: ({ get }) => {
        const text = get(textState);
        return text.length;
    },
});
```

## CharactorCountコンポーネントの作成
上で作成した、Selector `charCountState` を使って、入力した文字列の長さを表示させます。
selectorで返されている値は`useRecoilValue(selector名)`で取得できます
```typescript
// App.tsx
function CharacterCount() {
    const count = useRecoilValue(charCountState);
    return <>Character Count: {count}</>;
}
```
## デモ！！
![qiita_recoil_tutorial.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2525908/2b573ce8-1f56-8886-e91b-b5d09e369bd7.gif)

## 終わりに
どうでしたでしょうか。
今回は以下の公式ドキュメントのGetting Startedをそのまま行ってみました。
誰かの参考程度になったら嬉しいです。

全然関係ないんですが、毎年季節の変わり目には必ず風邪をひいている私ですが、今年からマルチビタミンを積極的に摂取し始めているからか、風邪ひかなくなって逆に怖い今日この頃です。
みなさんも体調にはお気をつけて。。

## 参考
> https://recoiljs.org/docs/introduction/getting-started/
Meta Quest 3で開発する、パススルー

Meta Quest 3でパススルーして、Unityの例のキューブを浮かせます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506075/a580b6cf-a780-756f-3afc-f93069fdab3b.jpeg" width=384 />


# 前提
- Windows10（基本Macでも同じです）
- Unity 2023.2.0f1
- Meta XR Core SDK 59.0.0

### その他
- UnityでビルドしてMeta Quest 3で実行できることを前提としています。まだ一度も実行したことがない人は[こちら](https://qiita.com/matchyy/items/d33501ebe11a2d214abd)の記事から試してみてください。

# 手順
## Unity
例の空が見えている状態までできている前提です。まだの人は[こちら](https://qiita.com/matchyy/items/d33501ebe11a2d214abd)から。
1. OVR Managerの以下2カ所を設定します。   
    - Passthrough SupportをSupported（あるいはRequired）に設定
    - Enalbe Passthroughにチェック
    ![2023-11-25_21h53_15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506075/c399c145-b5ce-c4e7-1911-475fc3027e51.png)
2. OVR Passthroug Layerを追加して、PlacementをUnderlayに設定
    ![2023-11-26_21h30_09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506075/83d9818c-c94c-ebf4-83a8-184b68ac23ee.png)
3. CenterEyeAnchorのCameraのClear FlagsをSolid Colorに設定し、Backgroundを黒（RGB全て0の）アルファ（A）を0に設定    
    ![2023-11-26_21h31_22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506075/caf41a84-8906-fa80-b14d-b7fac0bb5b74.png)   
4. Cubeを作成して、Positionのzを1、Scaleのxyzを0.1に設定します

## インストールと実行
1. インストール
    1. adb install ビルドした.apk
2. Quest3
    1. アプリライブラリを選択
    2. 検索ボックスの右側にあるドロップダウンから、提供元不明を選択
    3. インストールしたプロジェクトを選択して実行

# 参考
- [Passthrough AR](https://developer.oculus.com/documentation/unity/unity-customize-passthrough-passthrough-ar/) at Meta Quest
【AWS】S3に必要なファイルが全てアップロードされたことを確認してステートマシンを動かす実装例【Lambda】

## はじめに
前回の記事ではS3にファイルがアップロードされたことを契機にEventBridge経由でステートマシンを実行する方法を投稿ました。
しかしステートマシンを動かすために必要なファイルが複数ある場合、S3のファイルアップロード契機だけだと1ファイルごとにステートマシンが実行されてしまい、不必要な実行がされてしまったり、誤った結果が保存されてしまう危険があります。
そのため、今回の記事ではステートマシンが必要とするS3のファイルが複数の場合で、それら全てのファイルが処理実行日に作成されたものか(昨日作成されたものをステートマシンで処理しようとしていないかどうか)を確認した後でステートマシンを実行する実装例を記載しました。
※前回の記事

https://qiita.com/Nana_777/items/8dc23b9fc331ba7a7905

## 使うAWSサービス
・Amazon EventBridge
・Amazon S3
・AWS Lambda
・AWS StepFunctions

## アーキテクチャ図
![S3イベントplusLambda.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192949/4aed1da6-3581-9e7e-2974-1e72492214c2.png)


## アーキテクチャ説明
### 1．S3バケットの通知設定
※前回記事参照

### 2．EventBridgeの設定
①EventBridgeルールを作成
※前回記事参照
※今回の記事では実行ターゲットをLambdaに変えている

https://qiita.com/Nana_777/items/8dc23b9fc331ba7a7905

### 3．LambdaでS3のファイルの更新日時チェックとステートマシン実行
①更新日時をチェックするコード例
・この例ではS3にアップロードされたファイルが今日更新されたものかを判定している
```python:sample.py
import boto3
from datetime import datetime, timezone, timedelta

def lambda_handler(event, context):
    # S3バケットとフォルダの指定
    bucket_name = '【バケット名】'
    folder_path = '【更新日時を検証するフォルダパス】'

    # 現在の日時を取得（JST）
    jst = timezone('Asia/Tokyo')
    current_datetime_jst = datetime.now(jst)
    # 年と月の形式に変換した現在日時
    current_ymd = current_datetime_jst.strftime('%Y%m%d')
    
    # S3クライアントの作成
    s3_client = boto3.client('s3')
    # S3バケット内の指定したフォルダ内のオブジェクト一覧を取得
    response = s3_client.list_objects_v2(Bucket=bucket_name, Prefix=folder_path)
    
    # 最終更新日と現在日を比較
    all_files_today = all(
        obj['LastModified'].astimezone(jst).strftime('%Y%m%d') == current_ymd
        for obj in response.get('Contents', [])
    )
```
②ステートマシンを実行するコード例 ※上記コードの続き
・上記コードで判定された結果をもとにステートマシンを実行するか、そのまま終了とするかを分岐している
```python:sample.py
    if all_files_today:
        # 全てのファイルが今日更新されたものであればステートマシンを実行する
        stepfunctions_client = boto3.client('stepfunctions')
        state_machine_arn = '【ステートマシンのARN】'
        response = stepfunctions_client.start_execution(
            stateMachineArn=state_machine_arn,
            input='{}'
        )
    else:
        # 今日の更新年月に最終更新されたファイルが一部またはまったくない場合、何もせずに正常終了
        # ログにS3ファイルがそろっていない旨のメッセージを出すなどしたほうが良い
        
    return {
        'statusCode': 200,
        'body': 'Success'
    }

```
## さいごに
他システムからファイルが連携されてそれを使って日次バッチを実行するようなシステムの場合、EventBridgeの定時実行で確実にファイルが揃う時間に実行開始時間を設定することも良いと思います。ただし前回の記事でも書いたように連携元システムの何かしらの問題でその定時に連携が間に合わなかった場合に古いファイルで処理が実行されれてしまいます。
かといってS3ファイルのアップロードを契機に実行する設定をEventBridgeで行った場合はファイルのアップロードのたびに実行されたりなどの問題が発生します。
全てのファイルが確実に最新のものである状態でシステムを動かすため、Lambda等ですべてのファイルがそろっているかを判定したのちにステートマシンに処理を移すようなチェック機構は有効だと思います。
これによりステートマシンが条件がそろったときのみ動くことが保証され余計なコストの発生も防ぐことができると期待できます
DoTweenに頼らずにUIのTweeningをしたい！

### 想定（実装）する動作
![1eb22081084342741e3a5968bdf37966.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3515732/9668f94c-b5cb-fd06-6c73-d47ebb8849cc.gif)
このように特定のメソッドが呼び出されたら指定した時間トゥイーンする機能を実装する。
### 実装に際して必要な考え方
ある始点aと終点bがあり、ある時間tかけて始点aから終点bへアニメーションする。この時必要な式は以下の通り。 <br>
` t1 = {(1 - t) * a} + (t * b) ` (0 <= t <= 1) [sec] <br>
### 実際に想定通りに機能したコード
今回はdurationと始点、終点加えてイージングモードを指定してその通りに動作する機能を実装したいので `[SerializedFeild]`属性でdurationと始点と終点を指定できるようにする。ここではUIをトゥイーンさせるので、始点と終点は`RectTransform`型、duration（間隔）には`float`型を使った。まず最初に書いたコード。
```cs
_elapsedTime += Time.deltaTime;
float t;
// ～中略～ ここでtへ値の代入をしている
float xPos = (1 - t) * _startRect.position.x + t * _goalRect.position.x;
float yPos = (1 - t) * _startRect.position.y + t * _goalRect.position.y;
_movingImage.rectTransform.position = new Vector3(xPos, yPos, 0);
```
これはdurationが1秒までの値をとる時しか想定していないコードである。これでは不完全なので、以下のコードに修正した。
```cs
_elapsedTime += Time.deltaTime / _duration;
float t;
// ～中略～
float xPos = (1 - t) * _startRect.position.x + t * _goalRect.position.x;
float yPos = (1 - t) * _startRect.position.y + t * _goalRect.position.y;
_movingImage.rectTransform.position = new Vector3(xPos, yPos, 0);
```
`_elapsedTime`へ`⊿t / duration`の値を加算していくことで簡易的にdurationの指定ができるようになった。
### 今回得たもの
Tweeningへの浅はかな理解を少々
### 参考資料
イージングの式
https://easings.net/ja
【Laravel】「500エラー」時はDB接続を確認！

## 環境
Laravel v9.5.1 (PHP 8.1.2)
AWS
Fly.io（サーバー）
Supabase（データベース）

## 要約
500エラーはDB接続が上手くいっていないときに起こりやすいので、環境変数などをもう一度確認しよう

## 問題
PHPの練習がてら、Xのクローンアプリを作成。いざFly.ioでデプロイを試みる。
![a08be6b8c3ba304fd4b220099ac40d41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3620668/0b2a43b0-85e5-adf8-189e-9b8684449d9f.png)
おっ、ローカル環境通り上手くいったのでは？？？
という淡い期待もつかの間、ログイン情報を入力後の画面で「***500 | SERVER ERROR***」が表示された。
![80ce346364a562718ad8ec21ffab3e8f.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3620668/fe7093e1-4a4b-3c9e-206f-859b21978426.png)

## 解決法
ローカルで動くのに本番環境ではなぜ動かないのか？

ググってみたり有識者に聞いてみると、「多くの場合、プログラムではなく環境の問題です」「特にDB接続が上手くいっていない場合が多いので、接続情報を見直してみましょう」とあった。

そこで実際にログを出して接続情報を確認してみると…
Fly.tomlのファイルのenv欄に接続情報を書くのを失念していた。

    [env]
      APP_URL = "https://micropostsdao.fly.dev/"
      APP_NAME = "Microposts"
      APP_DEBUG = false
      DB_CONNECTION = "pgsql"
      DB_HOST = "db.ehgvvqinswchenabocqs.supabase.co"
      DB_PORT = 5432
      DB_DATABASE = "postgres"
      DB_USERNAME = "postgres"
（個人情報は出ていないはず）

## まとめ
ローカル環境では〇、本番環境では×の場合は、環境変数などの定義漏れに注意
[CDGC] 2023.11 ②新しいビジネス・アセットタイプ

# はじめに

<!-- ★『インフォマティカが提供する、 CDGC(データガバナンスとデータカタログ)を使って』までは定型文 -->
[インフォマティカ](https://www.informatica.com/jp/)が提供する、 [CDGC](https://www.informatica.com/jp/products/data-governance/cloud-data-governance-and-catalog.html)(データガバナンス＆カタログ)において、2023年11月にリリースされたバージョンの内容について記載します。
※2023/11時点の情報を元にしています。


新しい５つのビジネス・アセットタイプ ( <B>ビジネスエリア、規制、プロジェクト、地理、リーガルエンティティ </B>) を導入することで、組織内のユーザーの日々の活動の実態をより適切に表現し、データアセットに意味のあるコンテキストを追加することで組織のデータ管理機能を強化できます

詳細は[こちらのマニュアル](https://docs.informatica.com/data-governance-and-quality-cloud/data-governance-and-catalog/current-version/asset-details/understanding-business-assets.html)もご覧ください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110338/823f2b2d-10c4-e261-b44d-15b0198cae8e.png)



# ビジネスエリア
ビジネスエリアとは、より広範な組織内で特定の責任が割り当てられた部門またはビジネス機能です。

例えば、ビジネスエリアを表すために、マーケティング、人事、財務のアセットを作成することができます。
組織内のさまざまなコミュニティの従業員は、さまざまなシステムを使用できます。ビジネスエリアアセットで異なるビジネス機能エリアにシステム関係を割り当てると、特定の種類のデータを含むシステムを簡単に識別できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110338/b05e12d9-4915-1102-0edc-7d1decd8d560.png)


# 規制
規制とは、外部から制定される法律または指令のことで、通常、政府機関によって制定されます。規制は企業の運営方法に影響を与えます。規制は、社内の運営方針がどのように構築されるかに最も直接的に影響します。

「ポリシー」アセットおよび「地理」アセットに接続し、組織運営への影響を説明します。
たとえば、組織がヘルスケア業界の場合、事業展開国におけるさまざまなヘルスケア規制を表すアセットを作成できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110338/8f7fdf13-4b63-acfe-6219-ced1d61a3d69.png)


# プロジェクト
プロジェクトとは、特定の一連の目的を達成するために計画および組織されたアクティビティのコレクションです。

定期的ではなく、より具体的な活動には、プロジェクトアセットを使用します。
たとえば、「年次営業会議」というプロジェクトを作成して、組織内の営業チームの年次会議の活動を管理することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110338/3842e347-240c-6638-e843-70fc86c6e3b6.png)


# 地理
地理とは、リーガルエンティティが活動する地域、リージョン、または国を指します。このアセットタイプは、さまざまなビジネスアセットがさまざまな場所にどのように関連しているかを示す場合に使用します。

異なるリーガルエンティティを地理アセットにリンクして、そのリーガルエンティティがどこで事業を行っているかを確認したり、グループ内のいくつの法人が同じ地域で事業を行っているかを確認したりできます。法人をシステムとデータセットにリンクすると、その法人はリーガルエンティティ アセットを検索できます。
たとえば、ポーランド、ブラジル、インドにオフィスがある場合、これらの国の地理を作成できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110338/6a7be441-1c05-ca6d-9936-718fdcf7a544.png)


# リーガルエンティティ
リーガルエンティティとは、組織独自の企業グループ、信頼できるパートナー、ベンダー、または取引を行う別の組織の一部である可能性のある個別のビジネスエンティティを指します。

例えば、あなたの組織Acme Fitnessがデジタルウェルビーイング製品を作成するAcme Digitalという子会社を持っている場合、'Acme Digital'というリーガルエンティティを作成することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110338/9b12725f-def9-58d5-4162-15f79bbbe5a5.png)


# 参考文献
<!-- ★URLをそれぞれのカタログソースに応じて変更する -->
- [**マニュアル** *ログインが必要](https://docs.informatica.com/data-governance-and-quality-cloud/data-governance-and-catalog/current-version/asset-details/understanding-business-assets.html)
FlutterでUint8Listから画像の高さと幅を取得する

# 必要になった理由
画像を取得した際に正方形であればtrue、そうでなければfalseを返す関数が必要になったからです。

# 結論
```.dart
import 'dart:typed_data';
import 'dart:ui' as ui;

Future<bool> isSquareImage(Uint8List imageBytes) async {
  ui.Codec codec1 = await 
  ui.instantiateImageCodec(imageBytes);
  ui.FrameInfo frameInfo1 = await codec1.getNextFrame();
  int width = frameInfo1.image.width;
  int height = frameInfo1.image.height;
  print("幅: $width");
  print("高さ: $height");
  // 正方形かどうかを判定
  return width == height;
}
```
全加算器 Python3編

https://paiza.jp/works/mondai/logical_operation/logical_operation__basic_step9

繰り上がりのある問題。
まあ、ヒントがあったのでその通りに答えたら正解だった。

```py
a, b,C_1= map(int, input().split())

s_y = a ^ b
c_x = a & b


s = s_y ^ C_1
c_y = s_y & C_1


c_2 = c_x | c_y

print(c_2, s)
```

さて。
なんでこう考えたら正解になるのか。

```
    (C_1:繰り上がり）
    A_2 A_1
+   B_2 B_1
============
 C_2 S_2 S_1 
```

ちなみに半加算器はこれ

```
    (C_1:繰り上がり）
       A_1
+　　   B_1
============
    C_1 S_1 
```
まず普通の計算と同じように考えると混乱する。

<b>今やっているのは、１桁の計算ではなく、その次の桁の計算。</b>
※Sというのは２桁の計算の合計と３桁に繰り上がったC。

（A+B)+C１と普通に考えれば解けるが算術で計算したらだめ。

A + Bの結果であるs_yと、繰り上がりC_１を足してSが求まっている。
で、今A＋Bの繰り上がりc_ｘと　（A+B)+Cの繰り上がりc_yがあるが、
たとえば
C_2が１になりそうな場合というのは
１）A_２ +　B＿２で繰り上がり
２）A_２ + B＿２の合計と、繰り上がりC1で繰り上がり
３）１）と２）の両方　⇒>　A_2とB_2で繰り上がりが発生したら０になり、
　　　　　　　　　　　　　合わせても繰り上がらない
だから、１）or 2)になればOKなので、c_x | c_y　としている

繰り返しがあるので関数にしてしまうとよい

```py
a, b, c1 = map(int, input().split())

# 半加算器のプログラム
def halfAdder(a, b):
    c = a & b
    s = a ^ b
    return (c, s)

cx, sy = halfAdder(a, b)
cy, s = halfAdder(sy, c1)
c2 = cx ^ cy

print(c2, s)
```
何を思ったか『DO bit をたてない Unbound をビルドさせる ports コンフィグ』を(今更)作ってた件

# はじめに
## なんなん???
今更何を思ったか｢DO bit をたてない Unbound をビルドさせる ports コンフィグを書いた Makefile｣を書いただけなんです｡特に意味とか無いんです｡

## どういうもんなの?
先に[こちら](http://www.e-ontap.com/blog/20181104.html)をしっかり観ていただいたほうがより詳しくどういうことかわかると思います｡
もちろんのことなのですが｢この Makefile でなにか起こっても責任取れないですからね!｣と言っておきます｡

# とりあえずの Makefile
```Makefile:/usr/ports/dns/unbound/Makefile.local

OPTIONS_DEFINE += NO_USE_DNSSEC
NO_USE_DNSSEC_DESC = disable DNSSEC


pre-patch-NO_USE_DNSSEC-on:
	@${ECHO_MSG}
	@${ECHO_MSG} "============================================================="
	@${ECHO_MSG} "  'disable DNSSEC(NO_USE_DNSSEC)' is enable."
	@${ECHO_MSG} "  Q: What is this patch?"
	@${ECHO_MSG} "  A: http://www.e-ontap.com/blog/20181104.html"
	@${ECHO_MSG} "============================================================="
	@grep Dnssec ${WRKSRC}/util/net_help.h
	@${ECHO_MSG} "============================================================="
	@${ECHO_MSG} "  If 'disable DNSSEC(NO_USE_DNSSEC)' option is enabled and you wish to disable it,"
	@${ECHO_MSG} "  stop this build process immediately and uncheck 'disable DNSSEC(NO_USE_DNSSEC)' option."
	@${ECHO_MSG}
	@sleep 10

post-patch-NO_USE_DNSSEC-on:
	sed -i '' -e 's/EDNS_DO 0x8000 \/\* Dnssec Ok \*\//EDNS_DO 0x0000 \/\* Dnssec NO \*\//' ${WRKSRC}/util/net_help.h
	@${ECHO_MSG}
	@${ECHO_MSG} "============================================================="
	@grep Dnssec ${WRKSRC}/util/net_help.h
	@${ECHO_MSG} "============================================================="
	@${ECHO_MSG} "  Confirm that the DO bit is now disabled(0)."
	@${ECHO_MSG} "  If it is disabled, write the following information in each configuration file."
	@${ECHO_MSG}
	@${ECHO_MSG} "*** /etc/rc.conf ***"
	@${ECHO_MSG} "unbound_enable=\"YES\""
	@${ECHO_MSG} "unbound_anchorflags=\"-l\""
	@${ECHO_MSG}
	@${ECHO_MSG} "*** /usr/local/etc/unbound/unbound.conf ***"
	@${ECHO_MSG} "module-config: \"iterator\""
	@${ECHO_MSG} "harden-referral-path: yes"
	@${ECHO_MSG}
	@sleep 10

```
書いてる内容としてはハンドブックとかに乗ってる内容だと思うので詳しくは省きますが､この Makefile では｢パッチを当てる前｣と｢パッチを当てた後｣~~警告代わりに~~ 数秒止めてメッセージを表示させてます｡
大元の Makefile.local では｢どうせ自分しか使わない Makefile だしメッセージは入れなくていいか｣と思っていたのですがこの際 Qiita に載せちゃうしせっかくなら｢~~乱暴なクソ雑~~メッセージくらいは入れてとこう｣と思って入れました｡

# 終わりに
一応後書き的要素として書いておきますが､ Makefile.local を書いたのはコロナ禍になってからで､この記事を書き始めたのがアドベントカレンダーが出た日から数日たった後に書いています｡~~じゃあタイトル的に｢何を思ったか(2018年に話題となった)『DO bit をたてない Unbound をビルドさせる ports コンフィグ』を(今更)作って(記事を熟成させてみ)た件｣が正しいような気がしますが長すぎるのもどうかと思うのd(ry~~
多分この記事を｢FreeBSD 勉強会｣で発表するにも｢ペラペラな B5 の藁半紙｣半分以下くらいにしかならないと思うのでお誘いされても｢どうしたもんかw｣ってなるので(ぉぃ

# 追記(2024-02-16 18:56)
只今､緊急で追記しています(YouTuber 風
Unbound 1.19.0 から unbound.conf に以下の設定を書き入れると DO Bit をたてない効果があるそうです｡
ソース: [2024-02-16 Small is beautiful](https://www.e-ontap.com/blog/?date=20240216) - [インターノット崩壊論者の独り言](https://www.e-ontap.com/blog/)
```config:/usr/local/etc/unbound/unbound.conf
disable-edns-do: yes
```
変更点は[このプルリク](https://github.com/NLnetLabs/unbound/pull/944)で見れるみたいです｡

以上､緊急で追記させていただきました｡
VScodeのエディタの文字色を変えてmarkdownを書きやすくする

## 背景
![image-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3600683/5caeba05-938f-7af5-1377-a296b770b016.png)
デフォルトの青文字だと見ずらいし，
見出しや太字でそれぞれ違う色の方が分かりやすいなと不満に思うようになった．
そこで，見出しを緑・太字を赤にして，自分の見やすいように文字色を上書きで変更をしようと思った．
方法に関して調べても意外と出てこないので，環境設定メモの一部として残しておこうと思う．

## 方法：「基本設定：ユーザー設定を開く(JSON)」に色指定を記述

1. コマンドパレットを開く(Ctrl+shift+P)
2. "user json"と検索して，「基本設定：ユーザー設定を開く(JSON)」をクリック
![image-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3600683/9c880b37-a307-8a06-9815-b17eca7e9cc9.png)

3.  Json形式で以下を追記する．
```
{
    ###他の"editor.***"とかある部分###
    "editor.tokenColorCustomizations": {
        "textMateRules": [
        {
            "scope": ["markup.bold"],
            "settings": {
            "foreground": "#F55F49" // md太字の色
            }
        },
        {
            "scope": ["markup.heading"],
            "settings": {
            "foreground": "#52FA62" //mdヘッダーの色
            }
        },
        {
            "scope": ["markup.fenced_code.block.markdown"],
            "settings": {
            "foreground": "#69dfff" //mdブロック
            }
        }
        ]
    } 
} 
```

それぞれ，「scope」を指定して，対象のscopeの部分のみ色を変える仕様．
上記の例で行くと，マークダウンの見出しは`"markup.heading"`に当たる．

## 補足

### カラーコードでの設定が面倒
色が表示されてる四角にカーソルを乗せると，カラーパレットから指定できるのでそっちの方が楽．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3600683/b02864ae-fe74-e0a0-b7de-d2470a056c3d.png)


### scope名を探すのが面倒
1. コマンドパレットを開く(Ctrl+shift+P)
2. "dev scope"で検索して「開発者：エディタートークンとスコープの検査」をクリック
![image-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3600683/4401905e-53fa-007c-aebe-3c3c8ad6302e.png)

3. スコープを知りたい部分にカーソルを合わせる
![image-4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3600683/307aea6d-35fa-23b2-e670-e0a98ffff138.png)

上記の例では，斜体(イタリック体)にカーソルを合わせている．
斜体のスコープは，`markup.italic`となり，見出し同様設定の変更が可能．
kintoneでみんなのGoogleカレンダーを並べる

レガシーとモダンの間をつなぐ絶妙サービスkintone。
できるだけノンコーディングで済ませたいけど、どうしても背中が痒くなってしまうキントーン。
チームメンバーみんなが個人で使っているGoogleカレンダーをkintoneのメンバーに共有したいという話があったので思い切って ~~孫の手~~ APIを使ってみた。

# 作ったもの
kintoneのアプリ。
一覧の「カレンダー」ビューを選択すると、登録済みのGoogleカレンダーを埋め込みで見られる。

# 設定
## kintoneアプリ設定
### フィールド
GoogleカレンダーのID `cal_id`
カレンダーの表示名 `cal_title`
この2つだけ。
### 一覧
カレンダー表示用の一覧を作成し、表示形式をカスタマイズ・ページネーションありとする。
ここで提示された一覧IDはスクリプトの設定に必要なので控えておく。

## kintoneカスタマイズファイル（js）
[kintoneの公式ドキュメント](https://cybozudev.zendesk.com/hc/ja/articles/202905604)を参考にしてゴリゴリ書いた。 ~~旧版みたいだけどやけにノリが軽いなこの公式ドキュメント~~
```js:kintone-customize.js
(()=> {
  'use strict';
  kintone.events.on('app.record.index.show', (event) => {
    const viewId = {一覧ID};
    if (event.viewId !== viewId) {
      return event;
    }
    // カレンダー差し込み先となる親要素をつかむ
    const divEl = document.getElementById('google-calender-parent');
    const records = event.records;
    for(let i=0; i<records.length; i++){
      const r = records[i];
      const t = encodeURI(r.cal_title.value);
      const id = r.cal_id.value;
      // カスタマイズビューに表示させる内容
      divEl.insertAdjacentHTML(
      "beforeend",
      `<iframe src="https://calendar.google.com/calendar/embed?height=600&wkst=2&bgcolor=%23ffffff&ctz=Asia%2FTokyo&title=${t}&mode=WEEK&showPrint=0&showCalendars=0&showNav=1&src=${id}&color=%230B8043" style="border:solid 1px #777" width="800" height="600" frameborder="0" scrolling="no"></iframe>`
      )
    }
    return event;
  });
})();
```

# 最初が肝心ドキュメント
こういう細かい作成物は書き捨てて放置してしまうことが多かったが、忘れたころに大変な目に遭うというのをようやく学んだのでドキュメントもちゃんと作った。
カレンダー登録マニュアルとスクリプトのリポジトリとREADME。
メンバーのITレベルに開きがあるので、Googleカレンダーの一般公開設定とかそういうのもコミコミで。
Render.comのデータベースに外部から接続できない件

Golangでrender.comのデータベースに接続できないという事象が発生した場合の対処法を説明します。

# 解決法
sslmode=requireというようにsslmodeを変更します。
自分の場合はローカル環境のときにsslmode=disableとしており、そのまま本番環境にデプロイしてしまっていました。

# 補足
info→Connections→ExternalDatabaseURLという順で外部からデータベースに接続するためのURLが確認できます。
postgres://ユーザー名:パスワード@ホスト名/データベース名という構成になっています。