OmniAICreator/Qiita-1.07M huggingface dataset:
MySQLで複数のカラムに値を代入したい時

## はじめに
ある日、ターミナルでMySQLを通じてテストレコードを作成していました。

その時、「あれ？複数のカラムに代入する時ってどうするんやろ？」となったので、対応法をまとめます。

## 環境
MySQL: ver 8.0.35 

## 問題
```terminal: ターミナル（MySQL）
mysql> desc purchase_orders;
+-------------------+--------------+------+-----+---------+----------------+
| Field             | Type         | Null | Key | Default | Extra          |
+-------------------+--------------+------+-----+---------+----------------+
| id                | int unsigned | NO   | PRI | NULL    | auto_increment |
| title             | varchar(50)  | NO   |     | NULL    |           
|
| purchase_abstract | text         | NO   |     | NULL    |           
|
| created_at        | timestamp    | YES  |     | NULL    |           
|
| updated_at        | timestamp    | YES  |     | NULL    |           
|
| user_id           | int unsigned | NO   |     | NULL    |           
|
+-------------------+--------------+------+-----+---------+----------------+
```

このようにNot Null制約付きの複数のカラム（titleとpurchase_abstract）に値を同時に代入するケースです。

```terminal:ターミナル入力（失敗例）
> $user->purchase_orders()->create(['title' => 'purchase test'],
  ['purchase_abstract' => 'purchase test'])
```

これでは、以下のように「purchase_abstractにはデフォルトバリューがないぞよ！」と怒られてしまいます。

```terminal: ターミナル出力（エラー）
Illuminate\Database\QueryException SQLSTATE[HY000]: General error: 1364 Field 'purchase_abstract'
doesn't have a default value (SQL: insert into purchase_orders 
(title, user_id, updated_at, created_at) values (purchase test, 3, 2023-12-00 00:00:00, 2023-12-00 00:00:00)).

```




## 解決法
* 正解は以下のコマンド
* createの後ろのかっこ（brackets）の位置に注意ですね

```:ターミナル入力（正解例）
> $user->microposts()->create(['content' => 'micropost test',
'other_column' => 'other_value', // 他のカラムも同様に追加できます]);
```

```: ターミナル出力（正解例）
= App\Models\PurchaseOrder {#7286
    title: "purchase test",
    purchase_abstract: "purchase test",
    user_id: 3,
    updated_at: "2023-12-00 00:00:00",
    created_at: "2023-12-00 00:00:00",
    id: 1,
    }
```
【個人的備忘録】Arduino Unoのレジスタに直接アクセスしてPWMしてみた

# 9番ピンと10番ピンで交互にPWM
```c
const int MOTOR1_PIN = 9;
const int MOTOR2_PIN = 10;

unsigned int PWM_FREQ = 100;
unsigned long CLOCK_FREQ = 16000000; //16MHz
unsigned int RATIO = 256; //分周比256
float duty = 0.8;
unsigned int top_val = CLOCK_FREQ / (2*RATIO*PWM_FREQ);

void setup() {
  pinMode(MOTOR1_PIN, OUTPUT);
  pinMode(MOTOR2_PIN, OUTPUT);
  TCCR1A = 0;
  TCCR1B = 0;
}

void loop() {
  // 9PinのPWM
  // モード(位相・周波数基準PWM + TOP.ICR1: WGM13 WGM12 WGM11 WGM10 = 1 0 0 0)
  TCCR1A = 0b10000000;//10:9ピンON 00:10ピンOFF 00:N/A 00:WGM11 WGM10
  TCCR1B = 0b00010100; //000:N/A  10:WGM13 WGM12  100:分周比256
  // Top値
  ICR1 = top_val;
  //duty比
  OCR1A = (unsigned int)(top_val * duty); //9ピンはOCR1A

  delay(5000);
  
  // 10PinのPWM
  // モード(位相・周波数基準PWM + TOP.ICR1: WGM13 WGM12 WGM11 WGM10 = 1 0 0 0)
  TCCR1A = 0b00100000;//10:9ピンOFF 00:10ピンON 00:N/A 00:WGM11 WGM10
  TCCR1B = 0b00010100; //000:N/A  10:WGM13 WGM12  100:分周比256
  // Top値
  ICR1 = top_val;
  //duty比
  OCR1B = (unsigned int)(top_val * duty);//10ピンはOCR1B

  delay(5000);
}
```

# 参考
https://garretlab.web.fc2.com/arduino/inside/hardware/arduino/avr/cores/arduino/wiring_analog.c/analogWrite.html
https://geek.tacoskingdom.com/blog/52#part-h3-1-h2-0
https://usicolog.nomaki.jp/engineering/avr/avrPWM.html
https://ht-deko.com/arduino/portregisters.html
【Minecraft】アーマースタンドを使ったカスタムモブ製作のあれこれ

## はじめに
バニラ環境において、RPG配布ワールドを制作する場合、一つの壁となるのが「モブの見た目の差別化」です。

ゾンビやスケルトンといった人型モブに、既存の防具やブロックを被せるのも一つの手段ですが、やはり独自の見た目を用意したい！と思う方もいるでしょう。

本記事では、バニラとは全く違った見た目を持つモブ(以下「カスタムモブ」)を実現する方法の中で、アーマースタンドとリソースパックを使用した方法についてのノウハウを紹介していきます。

![2023-12-13_18.29.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3589884/6c031c09-05fe-9c73-94a9-f68b762ec5fd.png)
今回例となるカスタムモブたち

## カスタムモブの基礎
本記事におけるカスタムモブは、

**パーツ(アイテムモデル)を装備したアーマースタンド** を **当たり判定となるモブ** に **TPで追従させる**

という形の実装が基本となります。

![armorstand.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3589884/bfb03b13-82cd-279d-bb3d-60c7cb7dd852.png)
パーツを装備したアーマースタンドのイメージ(Blockbench)

基本的には、パーツ(頭・胴体・足など)の数だけアイテムモデルを用意し、それらをアーマースタンドに装備させ、当たり判定となるモブを中心に、TPの位置を調整することで形を作っていきます。
![2023-12-13_18.29.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3589884/b8260e30-2151-8492-ab30-77daae8f0b2c.png)
渓流の蜥蜴 レトリ(全8パーツ8エンティティ+当たり判定)

細かい記述は省きますが、以上が基礎部分となります。

## アーマースタンドの利点
そもそも最近は、Displayという優秀なエンティティが登場していて、アーマースタンドを使用する必要があるのか、と思う方もいらっしゃるでしょう。

アーマースタンドには、以下のメリットがあると考えます。
- 3つのパーツを1エンティティで保持できる
- 回転の仕様が直感的

#### 3つのパーツを1エンティティで保持できる
アーマースタンドを使用すると、頭・右腕・左腕と3か所でパーツを描画することができます。
回転の軸が固定であるという問題はありますが、これにより、複数のパーツを1つのエンティティにまとめられる場合があります。
パーツが中央に集中している、小型や節足動物型のモブに有効です。

例えば下記のモブの場合、表示に必要なのは2エンティティです。
- 頭・前脚&後脚(両手)
- 胴体・中脚(両手)

![2023-12-13_18.27.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3589884/308560b8-29f7-f18f-4845-3f4fa45a31f4.png)
マーブルバグ(全6パーツ2エンティティ+当たり判定)

#### 回転の仕様が直感的
アーマースタンドは、Poseタグによって頭・胴体・腕・足の回転を設定できます。
XYZによる指定であるため、スコアとの同期が容易です。

Displayの場合の回転は、四元数形式によって表されているため、アーマースタンドに比べると直感的ではなく、知識や慣れが必要となります。
(私は四元数形式による回転を理解しきれていないため、詳細な比較はできません)

## アーマースタンドの欠点と対策
アーマースタンドには、一つの重大な欠点があります。
それが**回転がずれる**問題です。
アーマースタンドによるカスタムモブ製作を試みた方なら、一度は体験したことがあるのではないでしょうか。

![Mottled.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3589884/5d8087d3-abe1-4d35-a793-9337424f6083.png)
ずれのイメージ

これは、アーマースタンドの回転が持つ、特殊な仕様によって引き起こされるものです。
詳細は不明ですが、恐らくTPや回転を視覚的に補完する機能によるものだと思われます。

実際には、カスタムモブが急旋回をした際、静止していた状態から動き始めた際などに発生し、突然パーツがあらぬ方向を向いてモデルが崩れたり、攻撃モーションと当たり判定がずれたりなど、様々な問題が発生します。

この問題の対策として、**こまめに回転を加える**という手段があります。
**数Tickに一度、1度程度の小さな回転を加える**だけで、このずれは大きく軽減されます。

## おわりに
本記事の内容は以上となります。
拙い内容ではありますが、問題解決や、カスタムモブ製作のきっかけになれば幸いです。

余談ですが、本記事において使用した画像は、全て制作中のRPG配布ワールド「FinzKiil(フィンズ・キイル)」のものです。
今冬に第一作をリリース予定ですので、リリースされた際には是非プレイしていただけると嬉しいです！

ここまで読んでいただきありがとうございました！

![2023-05-20_23.29.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3589884/c2d5c85d-183b-b86f-4eed-3012c8b9c32b.png)
のんびりエンジニアやるなら大分県がいい理由(大分vs東京)

# 自己紹介
- 大分県生まれ大分県育ち東京都在住
- スタートアップのCTO
- フリーランスエンジニアとしても活動中
- React/TypescriptとDjangoが好き
# こんな人におすすめ
- 本気でエンジニアになりたい人
- すでにフリーランスとして活動している人
- フリーランスへの転身を考えている人]]

# 以下は例外
- 未経験からのんびりフリーランス目指してる人(本気ならOK)
- 勉強に時間取れない人
- 向上心がない人


# 本題 = なぜか?
- 人が少ない
- 意外とコワーキングある(しかも安い)(¥1000~/1day)
- 生活費が安い
- 手厚いサポートもある..らしい?

# 東京に来て感じたこと
- 人が多い！
- コワーキング高い！！(¥3000~/1day)
- 生活費高い！！

以上！！

# 自分が大分にいた時の例
- 作業場所 - カフェor公園orコワーキング(!?)
- 毎日カフェを転々と回って作業
- 全て経費で落とす

# とは言っても東京ならではのいいとこもあるよね
 結論 -> 格安LCC乗って月１とかで行く方がコスパいい！
【24日目】OSS連携してみたい(20)！連携できそうなOSSについて

この記事は筆者オンリーの[Advent Calendar 2023](https://qiita.com/advent-calendar/2023/aichallenge_racing_for_mas)24日目の記事です。  

お疲れ様です。
クリスマスイブですね。

本日はAutowareと連携できそうな？？？OSSを紹介してみたいと思います。
(PythonRoboticsは有名なので割愛させていただきます)


# OSS
## ３次元点群処理

https://github.com/3d-point-cloud-processing

東工大の金崎朝子准教授が開発した３次元点群処理のOSSです。
先生の著書には３次元点群処理があり書籍もおすすめです。

## SLAM
https://github.com/soblin/slam

友納正裕先生が開発されたSLAM入門のリポジトリです。
本家がみつけられなかったのでご参考。
先生の著書には「SLAM入門 ロボットの自己位置推定と地図構築の技術」もありおすすめです。
また、先生のソースコードを基にROSに対応したソースコードもネット上で見られます。

## 確率ロボティクス
https://github.com/ryuichiueda/LNPR_BOOK_CODES

千葉工大の上田隆一准教授が開発された確率ロボティクスのリポジトリです。
先生の著書には「詳細確率ロボティクス」もありおすすめです。

# 終わりに
私の学習分野の都合上、SLAM、確率ロボティクスの書籍からの紹介が多くなってしまいました。
私も自己位置推定などもAutowareに組み込んでみたかったのですが、ちょっとどう組み込めがわからず
紹介のみにとどめました。
やってみようかな。。。
Date型の比較でやりがちなミスのメモ

### Date型どうしで同値か比較したい
そのまま比較するとfalseとなってしまう。
```javascript
let date1 = new Date('2023/12/13 19:30');
let date2 = new Date('2023/12/13 19:30');

date1 === date2 // false
```
>date1とdate2は別のインスタンスなのでfalseと判定される

#### 対策
```javascript
let date1 = new Date('2023/12/13 19:30');
let date2 = new Date('2023/12/13 19:30');

date1.getTime() === date2.getTime() // true
```
>.getTime()でミリ秒単位の数値に変換して比較する
陰のSREがNewRelicでBotを可視化してみた

[ディップ株式会社 Advent Calendar 2023](https://qiita.com/advent-calendar/2023/dip-dev)の記事です。

## はじめに

陰のSREになりたくて日々研鑽している、自称アニヲタSREです。
平素は弊社サービスの開発や運用に従事しております。

昨今、SREチームを持つ組織が多い中、弊社にはインフラ全般を見るチームはありますが、明確にSREチームは存在しておらず各プロジェクトやチームがうまく連携してやってます。

今年を振り返るに私はNewRelicに多く関わってきました。
DatadogからNewRelicへの移行に始まり、データや指標の可視化、開発メンバーへの布教など日々の運用でNewRelicを非常に活用しています。

NewRelicで日々観測していると明らかにBotと思わしき負荷が見られたためBotのアクセス状況を可視化してみました。

## 結論

作成したクエリ例です（もっと良い書き方があったらご教授ください💦）。
NewRelicのQuery Your Data > Query builderでクエリを実行します。
（NewRelicのLogのmessageにUserAgentが含まれている場合を想定）

「TIMESERIES」を入れているので折れ線グラフとして可視化されます。

```sql
SELECT count(*) FROM Log WHERE message NOT RLIKE '.+(robots.txt).+' AND message RLIKE '.+((bot)|(crawl)|(spider)|(krowler)).+' FACET capture(message, r'.+((?P<botname>((test-bot)|(compatible;\s.+;)|(AdsBot[-G]{2}oogle)|([a-z]+bot/[0-9.]+\s)))).+') SINCE 1 day ago WITH TIMEZONE 'Asia/Tokyo' TIMESERIES LIMIT MAX
```


今回、確認用に用意した環境のBotアクセス状況を見てみます。



![img1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782637/1a5ce2d7-5fa0-4b65-2c70-a1603a766094.png)


WAFを入れているとは言え、結構来てますねー。
クエリ内の「LIMIT MAX」を入れることで検出した全てのBotを見ることができますが、省略すると上位件数のものだけになります。

NewRelicの良いところは様々なChart typeが用意されているところです。

上記クエリの「TIMESERIES」を削除してクエリを実行し、Chart typeを「Bar」にするとBot毎の件数をより見やすくできます。

![img2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782637/3a98e742-416c-0bff-82bc-0c80f92e533f.png)


これらのChartはクエリ実行画面右下の 「Add to dashboard 」から簡単にダッシュボードに組み込むことができます。

同じダッシュボード画面内にALBリクエストログやサーバ負荷Chartなどと一緒に置いておけば、Botが影響しているのかどうかわかりやすくなるのではないでしょうか。
ダッシュボード画面の右上で日時を設定できるため、同じ時間軸で複数のChartを確認することができるのが良いですよね！

![img3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782637/4a92a010-3d6a-7c8c-d413-789aed6e75cd.png)


## さいごに

今後とも陰のSREとして活動していこうと思いますが、
弊社には陰にひそまず大いに活動できる場が沢山あり絶賛エンジニアを募集中です！！
カジュアル面談もありますのでお気軽にご応募ください！！！

https://recruit-dip.com/career/
うるるでの1年を振り返る

この記事は株式会社うるる（ULURU） Advent Calendar 2023　13日目の記事になります。

# お前誰よ

初めまして、うるるNJSS事業本部情報収集推進課の一色と申します。普段はnSearchのクローラー周りと、NJSSのクローラーの運用・保守を担当しています。また不定期に個人ブログでJRの最長片道切符に関する記述をしています。

# 前職について

前職ではECサイト向けの検索エンジンの開発をしていました。内容はアプリ部分の運用・保守や、社内ツール作成、検索クエリの調整、クロール等です。

# 転職のきっかけ

前職での在籍期間が長くなり、エンジニアとして新しい環境で挑戦したいという思いが強くなり、転職を考え始めました。数社よりお声をかけていただきましたが、その中でもうるるは前職における全ての経験を評価してくれたので、うるるへの入社を決めました。

# 入社後の業務

入社後に携わっているものとしては、NJSS関連とnSearch関連の大きく2つになります。

## NJSS関連

NJSS関連では、クローラーの運用保守を行なっています。入社当初は、Djangoのクローラーでしたが、現在はTypeScriptのクローラーを担当しています。また、Laravelのプロジェクトに関わったこともありました。

## nSearch関連

入社してからしばらくしてから担当するようになりましたが、現在はこちらの運用保守がメインとなっています。こちらでは、Ruby on Rails を使っています。

# うるるでの業務を振り返って

## うるるで達成感を感じたこと

前職での経験を買って頂いたこともあり、入社前にチームで抱えていた課題については早々に解決に向けた施策を打つことができました。また、うるるでは前職と比較すると多くの開発言語に触れてきました。前職ではPHPと時々、Pythonでしたが、うるるではPython、Ruby、PHP、TypeScriptと４つの言語に触れてきました。また、Django、LaravelといったWebフレームワークやTerraformのようなインフラの自動管理システムにも触れてきました。新しく学んだ技術を用いて業務を遂行することによって、前と違った達成感を感じました。

## うるるで戸惑ったこと

前に書いたRubyとTypeScript、Webフレームワーク、Terraformに関しては、前職では扱ってこなかったこともあり、うるるで0から学んだものになりました。0から学ぶものが多かったですが、これらに関しては、業務でのキャッチアップとともに、書籍を購入して、時々参照するようにしました。また、前職では１つの大きなプロジェクトをずっと担当し、役割が少し変化したという事しか変わることがありませんでした。しかし、うるるでは、色々なプロジェクトに携わりその度に新しい事を覚えるので、前職に比べて覚える事が多いと感じましたが、それでもしっかりやり抜くするようにしています。

## 転職後の感想

前に書いたWebフレームワーク、Terraformに関しては他の企業でも一般的に用いられている技術であり、そのような一般的な技術に業務で触れる機会がなかった自分にそのような機会をくれたうるるには感謝しています。


# 今後やってみたいこと

今のクローラーに関する知識を深めるとともに、前職で検索エンジン周りを扱っていたこともあり、形態素解析等の自然言語処理に関することにも挑戦してみたいです。
文系大人初心者プログラミングするよ🔰start2

学習するにあたって、何から手を付ければよいやら～という感だったため
とりあえずプログラミングスクールに入ることに。

資金に余裕があるわけでもなくって
さすがに数十万一括振り込むときは:frowning2:でしたが
まあでも！飛び込んでみるか！と
決めてしまえば一瞬で始まりました✨
（申込みの前のオンライン相談から「やります」の良いお返事しました）
結局決めるまでが長いんですよね～:smile:
あーだこーだ言い訳を探しますが、
やっぱ最初に「やってみたい」と思った気持ちって
ほんと大切にしたほうがいいすよね。なんでも。人生。

で、早速取り掛かるわけですが、
プログラミング準備段階の『環境構築』なるものの壁に早々にご対面し
やる気がものすごい勢いで落ちていく、、、

『環境構築』て名前から難しそうだもん。
未だに聞きたくない4文字熟語です。

その後HTML,CSSと続き、ようやくRuby、Javascriptを学習することに☺
Workato：コマンド以外のメッセージもWorkbotで受け付けられるようにする

# はじめに
Workbot for Slackに対して、定義されたコマンド以外のメッセージを送信すると、存在しないコマンドが送信されたとして、通常は以下のような結果が返されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64876/cbdf9fb0-e071-e2c7-70ca-f4b8d25e1fa9.png)

コマンドを入力すれば様々な処理をWorkatoに実行させることは可能ですが、コマンドを入力するのではなく、任意のキーワード（文字列）を扱いたいというケースもあるかと思います。

例えば、Workbotで生成AIと対話するチャットボットを作成したい場合は、Workbotのコマンドではなく、自然言語で入力して処理させたいと思うでしょう。

このような場合は、以下の手順でレシピを作成することで、Workbotコマンド以外のメッセージも受け付けられるようになります。

# レシピ

以下のレシピは、Workbotは DM(Workbotアプリ) へ送信されたメッセージ、あるいは `@workbot` メンションされたメッセージをトリガーで取得し、そのメッセージをSlackへ返す単純なレシピです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64876/e2bf4040-4de2-9a2b-78ed-3772ffe68d9d.png)

# 手順
## Step1 Workbot for Slackコネクターを追加し、トリガーを設定します。
`New event` トリガーを指定し、 `Message(message)` イベントを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64876/8be8bb53-5342-0b93-56d6-4b1490b3cb79.png)

## Step2 トリガーで発生したメッセージに対する処理を定義します。
以下では、直前にSlack上で入力されたメッセージをSlackへ返します。

# 実行結果
DM(Workbotアプリ) にメッセージが送信されるか、あるいは `@workbot` へメッセージをメンションすると、次のように結果が返されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64876/4bf1e672-5a1c-329e-8966-7dcfc49974e7.png)


# 制限事項

このレシピを運用すると、トリガーあるいはアクションで条件指定をしない限り、Workbotは DM(Workbotアプリ) へ送信されたメッセージ、あるいは `@workbot` メンションされたメッセージすべてに無条件で反応するようになります。

このため、適宜Trigger conditionを設定し、特定の条件に一致するメッセージのみに反応するようにしていただくことをおすすめします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64876/696c440b-65c9-acea-051b-772b296d8b52.png)

また、このレシピを運用することで、これまで存在しないコマンドが入力された際に出力された次のメッセージ（Huh... didn’t quite get that. Which app can I help you with?）が出力されなくなります。必要ない方もいらっしゃるかもしれませんが、制限事項としてあわせてご認識ください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64876/7757b861-759e-7af4-ea6d-4b2872415fbb.png)

その他、Workbotの一部機能に制限が生じる（トラブルが発生する）ことも可能性として考えられますので、この手順を運用される際は、綿密にテストを行ったうえで運用を開始されることをお勧めします。
新人エンジニアが学びを毎日アウトプットできた秘訣

## はじめに
本記事は[リンクアンドモチベーション Advent Calendar 2023](https://qiita.com/advent-calendar/2023/lmi)の14日目です。

こんにちは、2023年に新卒入社しました井川と申します。
プログラミング未経験の状態から、エンジニアチームに配属されて勉強の毎日を送っています。

その中で、学びをきちんと血肉化するには、ただインプットするだけでなくインプット・スループット・アウトプットの流れが大切になってくるとよく言われます。
でも、アウトプットってなかなか難しいですよね。
面倒臭いし、業務に追われてそんな時間は取れないし…

かくいう私もそうでした。
先輩から学びを毎日Slackに投稿しようと言われていましたが、先輩方に見せられるような学びなんてないという思いから長いこと避けていました。
しかし、先輩から数日でもいいからやってみようと言われ、渋々はじめてみることにしました。
それからは1日も欠かすことなく、Slackで日々の学びを投稿しておりました。

なぜ続けられたのか？
それは、毎日投稿することで様々なメリットを感じたためです。

この記事では、そのメリットと習慣化するためのコツをお伝えできたらと考えております。



## なぜ毎日のアウトプットが重要か？
そもそも学びを毎日アウトプットすることがなぜ重要なのか？と疑問を持つ方も多いと思います。
毎日投稿をして感じたメリットをまとめます。

#### 発信することで先輩方から新たな知見が得られる
写真のように、読んでおくといいサイトのリンクをいただいたり、関連して覚えた方がいい知識を教えていただけたりします。
毎日行う事で、先輩方から得られる情報は増え続けていきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3622457/6aec0b2c-bcf0-e05c-8d2d-b0a31daee532.png)

#### 自分の頭の中が整理できる
アウトプットをするには、正確な理解が必要になります。
そのため、理解が甘い部分が分かり、その部分を調べるというステップを踏むことができます。
毎日行うことで、1日の終わりに整理してPDCAを回す事ができます。

#### 分からないことに対するアンテナをはる事ができる
投稿できる事がないかを毎日探すため、分からない部分や曖昧な部分を見つける事ができます。
毎日行うことで、自分の理解で曖昧な部分がないかを探す癖がつきます。

---

主なメリットはこの3つです。
アウトプットを習慣化するだけでもいいですが、毎日行う事で自然と身体が動くという癖づけができるため、特におすすめです。

また、これ以外にも様々なメリットがあると感じました。
- 忘れた時に確認できる
- 小さなことを組織に発信するハードルが下がる
- これまで話したことがない先輩方とコミュニケーションを取るきっかけになる
- 成長実感が湧かない時に見返すと、理解できたことがこんなにたくさんあると少しだけ自信になる

新人のうちに抱えることの多い、孤独感や無力感といった悩みを解消することにもつながると感じたので、ぜひやってみてください。

## アウトプット習慣化のポイント！
メリットは分かったけど、そんな簡単に習慣にはできない、と思う方もいらっしゃるでしょう。

私が毎日学びを投稿するために心がけていたこと3つをお伝えします。

#### 投稿のハードルを下げること！

実際に私の投稿をお見せします。ここまで投稿のハードルは下げてしまっていいと私は思っています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3622457/cf72a5ec-2465-2798-63bb-4b3cfe3e7a3b.png)
もはや一行しか学びを書いていません（笑）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3622457/ec8cda00-5c43-1289-7e9e-8ec71ef76bef.png)
もはや学びですらありません、疑問です（笑）
（優しい先輩方が疑問に答えてくださってますね）

上記のように、投稿のハードルを下げるという点では、「一行でもOK」「自己満足でもOK」と思うことで継続できていました。

#### 仲間を見つけること！
やはり、一人で継続するのはとても難しいです。
1人でも良いので仲間を見つけて、一緒に投稿するとお互いに声を掛け合ってできます。

#### 最初にチーム内で宣言すること！
勇気がいる行動ですが、なかなか効果的な方法です。
未来の自分へ圧をかけておくことで、やらなければならないものになります。

## 最後に
これから、学びの毎日アウトプットだけではなく、1つタスクを終えるたびにより体系的な学びをアウトプットしていきたいと思います。
みなさんもぜひ学びを社内外問わずアウトプットして、色々な組織で学び合いの文化をより浸透させていきましょう。
4メソッド(puts・print・p・pp)の出力結果の微妙な違い

## はじめに
今回、Rubyでプログラム問題を解いていた際、
```
$ ruby random.rb
["A", "B"]
["C", "D", "E", "F"]
```
の2行の配列の形で出力したいところを、
```
$ ruby random.rb
A
B
C
D
E
F
```
でしか出力できず、その理由が
puts, print, p, ppで微妙に挙動が異なることを学んだので、
アウトプットとしてまとめてみたいと思います。

### puts
- オブジェクト出力後の末尾に、`改行を加えて`出力する
- putsメソッド自身の戻り値は、nil
```
puts 12345
puts 'abcde'
12345
abcde
=> nil

# 改行文字\nで改行される
puts "abc\nde"
abc
de
=> nil
```


### print
- putsとは反対に、`改行を加えない`で出力する
- putsメソッドと同じく、printメソッド自身の戻り値もnil

```
print 12345
print 'abcde'
12345abcde=> nil

# 改行文字\nで改行される
print "abc\nde"
abc
de=> nil
```


### p
- putsメソッドと同じく`改行を加えて`出力する。
- ただし、文字列を出力すると、その文字列が`ダブルクオート""で囲まれて`返ってくる
- またpメソッドは、`引数で渡したオブジェクトそのもの`が、メソッドの戻り値になる

```
p 12345
p 'abcde'
12345
"abcde"
=> "abcde"

# 改行文字\nは改行文字のまま出力される
p "abc\nde"
"abc\nde"
=> "abc\nde"
```

### pp
- pメソッドでは扱いきれない、大きくて複雑な配列やハッシュ、オブジェクトの内容を見やすく整形して出力してくれる
- pメソッド同様、引数で渡したオブジェクトそのものが、メソッドの戻り値

## 配列を渡した場合の挙動の違い
今回の記事を書くきっかけとなったポイントですが、
配列を渡した場合、それぞれの違いが顕著に見られる

```
a = ["A", "B", "C"]

# putsの場合(要素ごとに改行)
puts a
A
B                                                
C                                                
=> nil

# printの場合
print a
["A", "B", "C"]=> nil

# pの場合
p a
["A", "B", "C"]
=> ["A", "B", "C"](オブジェクトそのものが戻り値)  
```

## 使い分け
- putsとprint: `一般ユーザ向け`
- pとpp: `開発者向け`
- putsとprintは`改行の有無`で使い分ける

また、
putsとprintは引数で渡されたオブジェクトに対して`.to_s`メソッドを呼び出し文字列に変換している一方、
pメソッドは.to_sメソッドではなく`inspect`メソッドを呼び出す
(pメソッドでは文字列が”"で囲まれて出力されていたのは、
内部的にStringクラスのinspectメソッドが呼び出されていたから。)

この点に関しては下記の記事に詳しく解説されています
[.to_sメソッドとinspectメソッドの違い](https://www.sejuku.net/blog/77039)



## まとめ
今回の内容を一覧にすると、下記のようにまとめられます。

| メソッド | 出力後の改行 | 配列の表示 | 文字列変換 | 戻り値 | 対象者 |
|-----|-----|-----|-----|-----|-----|
|  puts  |  あり　|  要素ごとに改行  |  to._s  |  nil  |  一般ユーザ  |
|  print  |  なし  |  改行しない  |  to._s   |  nil  |  一般ユーザ  |
|  p |   あり  |  改行しない  |  inspect  |  引数のオブジェクト  | 開発者|
|  pp |  あり  |  見やすく整形 |  inspectに似た方法  |  引数のオブジェクト  |  開発者  |

## 参考文献
[プロを目指す人のためのRuby入門[改訂2版] ](https://www.amazon.co.jp/%E3%83%97%E3%83%AD%E3%82%92%E7%9B%AE%E6%8C%87%E3%81%99%E4%BA%BA%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AERuby%E5%85%A5%E9%96%80-%E6%94%B9%E8%A8%822%E7%89%88-%E8%A8%80%E8%AA%9E%E4%BB%95%E6%A7%98%E3%81%8B%E3%82%89%E3%83%86%E3%82%B9%E3%83%88%E9%A7%86%E5%8B%95%E9%96%8B%E7%99%BA%E3%83%BB%E3%83%87%E3%83%90%E3%83%83%E3%82%B0%E6%8A%80%E6%B3%95%E3%81%BE%E3%81%A7-Software-Design/dp/4297124378/ref=tmm_pap_swatch_0?_encoding=UTF8&qid=&sr=)
MCP9701温度センサーで遊ぶ(ichigojam)(テーブル方式)


x MCP9701-E/TO 販売コード 103199

x ANAのコメントは、取って、お好みのままに
x 温度センサーを使ってテストは、していないがたぶん動く
x ichigojam webで開発した

目的
温度センサーのテスト

参考

https://qiita.com/caa45040/items/d32cd71f79fde2a9fdc4


```

5 REM MCP9701
10 D="#9#9#9#8#7#7#6#5#5#4#3#3#2#1#1#0-9-9-8-7-7-6-5-5-4-3-3-2-2-1-1 0 1 1 2 2 3 4 4 5 6 6 7 8 8 91010111212131414151616171818192020212222232424252626272828293030313232333434353636373838394040
20 A=250:REM A=ANA()
30 A=A/4:A=A*2
40 PRINT CHR$(PEEK(D+A+0));
50 PRINT CHR$(PEEK(D+A+1))


```
快適なアウトプット環境の作り方


# 環境
Ubuntu 23.04
# はじめに
快適なアウトプット環境を作ってみかった
# 手順
## VSNotes
- 拡張機能をインストール

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531484/e1890218-6cb1-6b32-f350-6dd3ef4b0a5a.png)

- `ctrl+shift+P`でコマンドパレット開いて`VSNotes: Run setup`を実行
notesを保存するディレクトリを聞かれるので選択
Google Driveなどオンラインストレージをマウントしといて選択したら、いろんなデバイスから参照できるから便利
['Google Driveのマウントの仕方'](#道中で得た知見)

- コマンドパレットから`VSNotes: Create a New Note`を実行
Markdown形式でアウトプット出来る〜！

## おすすめ拡張機能
- Copy as Markdown
開いてるタブのリンクをマークダウン形式でクリップボードにコピーしてくれる

https://chrome.google.com/webstore/detail/fkeaekngjflipcockcnpobkpbbfbhmdn

Cursorでもいけた（そりゃそうなのだけど）
​![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531484/9996a3cd-e23c-e3a7-cfd4-e9df3a5cde75.png)


# おわりに
他にもタグ機能とかあるらしいのでまたまとめよう〜
# 道中で得た知見
## いろんなVSCodeのショートカット
- `ctrl+shift+x`: 拡張機能を開く
- `ctrl+\`: 画面分割
- `ctrl+k -> ctrl+\': 縦に分割 (Cursorだと`ctrl+k`でAI君起動しちゃう...)
- `ctrl+ <任意の数字> `: その画面にフォーカスする 
## Google Driveのマウント方法
```bash
$ sudo apt-add-repository ppa:alsessandro-strada
$ sudo apt update
$ sudo apt install google-drive-ocamlefuse
```
`sudo apt-add-repository ppa:alessandro-strada`
: alessandro-stradaさんが持ってる**PPA**(Personal Package Archive)をシステムに追加する

`sudo apt install google-drive-ocamlfuse`
: Ocamlという言語で、fuseという仮装ストレージを使ってマウントしてるらしい

```bash
$ mkdir ~/gdrive
$ google-drive-ocamlfuse ~/gdrive
```
- 先にディレクトリ作っとく

その後ブラウザでアカウント認証したらちゃんとマウントされてる
## Ubuntuでウィンドウの切り替え
`alt+Tab`
(多分どのOSでもそう..siranakatta..)

## 仮想デスクトップの切り替え
`ctrl+alt+↔`
3本指スワイプでも切り替えできる

## いろんなRun Command
`alt+F2`でRun Commandが入力できるようになる。
- `gnome-terminal`: ターミナル
- `nautilus`: Windowsでいうエクスプローラー
    `nautilus path`とするとそのまま開ける！**便利〜！**
    (ノーチラスというギリシャ神話の貝みたいな架空の生き物らしい）
    **知見〜！**
円周方向応力 第10章 薄肉圧力容器 基本例題10.14 p342「材料力学演習(20221021)」をsympyでやってみたい。(英:thin wall structure）

# オリジナル
[基本例題10.14 p342](http://zairikiweb.starfree.jp/zai_enshuh/zai_enshuh_ver.3.3.pdf#page=347)＜[「材料力学演習(20221021)一括(ver.3.3)」を勉強したい。#sympy](https://qiita.com/mrrclb48z/items/c3274daf5f7a99cfe027#%E4%BD%9C%E6%A5%AD%E4%B8%AD%E7%A7%81%E3%81%AE%E8%A7%A3%E7%AD%94sympy)
　　　　　　　　？？？タブレット等で、pdfを開く事ができないかも。？？？　
# sympyで
ver0.2
```python
from sympy import *

var('σt1,σt2',real=True)
var('R1 ,R2' ,real=True)
var('p,t,D'  ,real=True)
eq=Eq(σt1/R1+σt2/R2,p/t)
rep={R1:D/2}                                      
print("#   ",eq) 
print("# 1)",solve(eq.subs({σt2:0})                .subs(rep),σt1)[0])  
print("# 2)",solve(eq.subs({R2:R1}).subs({σt2:σt1}).subs(rep),σt1)[0])  
#    Eq(σt2/R2 + σt1/R1, p/t)
# 1) D*p/(2*t)
# 2) D*p/(4*t)
```

ver0.1
```python
# ver0.1
from sympy import *

var('σt1,σt2',real=True)
var('R1 ,R2',real=True)
var('p,t,D' ,real=True)
eq=Eq(σt1/R1+σt2/R2,p/t)                        ;print("#   ",eq)
# 
eq1=eq .subs({σt2:0})                           ;print("# 1)",eq1)
print("# 1)",solve(eq1.subs({R1:D/2}),σt1)[0])  ;print()  
# 
eq2=Eq(eq.lhs.subs({R2:R1}).factor(),eq.rhs)    ;print("# 2)",eq2)
eq2=eq2.subs({σt2:σt1})                         ;print("# 2)",eq2)
print("# 2)",solve(eq2.subs({R1:D/2}),σt1)[0])  
#    Eq(σt2/R2 + σt1/R1, p/t)

# 1) Eq(σt1/R1, p/t)
# 1) D*p/(2*t)

# 2) Eq((σt1 + σt2)/R1, p/t)
# 2) Eq(2*σt1/R1, p/t)
# 2) D*p/(4*t)
```

# いつもの? sympyの実行環境と 参考のおすすめです。
(テンプレート)

https://qiita.com/mrrclb48z/items/00dd08b0317069be9342
貯水槽の壁の厚さt 第10章 薄肉圧力容器 基本例題10.02 p335「材料力学演習(20221021)」をsympyでやってみたい。(英:thin wall structure）

パイソニスタの方へ
・solveで、不等式を教えて下さい。
・Inequality Solversの使い方を教えて下さい。
https://docs.sympy.org/latest/modules/solvers/inequalities.html

# オリジナル
[基本例題10.02 p335](http://zairikiweb.starfree.jp/zai_enshuh/zai_enshuh_ver.3.3.pdf#page=340)＜[「材料力学演習(20221021)一括(ver.3.3)」を勉強したい。#sympy](https://qiita.com/mrrclb48z/items/c3274daf5f7a99cfe027#%E4%BD%9C%E6%A5%AD%E4%B8%AD%E7%A7%81%E3%81%AE%E8%A7%A3%E7%AD%94sympy)
　　　　　　　　？？？タブレット等で、pdfを開く事ができないかも。？？？　
# sympyで
```python
from sympy import *

var('σa,σt'  ,real=True)
var('Q,H'    ,real=True)
var('D,t,p,g',real=True)
var('x'      ,real=True)
eq=Eq(σt,D/(2*t)*p)                 ; print("#",eq)
eq=Eq(σt,D/(2*t)*p).subs({p:Q*g*H}) ; print("#",eq)
lt=Lt(σt,σa)                        ; print("#",lt)
lt=Lt(σt,σa).subs({σt:eq.rhs})      #; print("#",lt)
# print( solve(lt,t) )
lt=Lt(σt,σa).subs({σt:eq.rhs})      #; print("#",lt)
lt=Lt(lt.lhs*t/σa,lt.rhs*t/σa)      #; print("#",lt)
gt=Gt(lt.rhs,lt.lhs)                ; print("#",gt)
# Eq(σt, D*p/(2*t))
# Eq(σt, D*H*Q*g/(2*t))
# σt < σa
# t > D*H*Q*g/(2*σa)
```



# いつもの? sympyの実行環境と 参考のおすすめです。
(テンプレート)

https://qiita.com/mrrclb48z/items/00dd08b0317069be9342
インシデント管理サービスについて考えてみる

こんにちは。
私はシステム保守運用については初心者です。
運用保守部門に配属され、知らないこと沢山あり毎日学習の日々です。
そんな中、上司から「インシデント管理がうまくできていない、アラートの取りこぼしが多い、不要なアラートが多いからサービスの導入検討してくれない？」というお達しがあり、今猛チャージで情報収集しているところです。
自分なりに情報収集していく中でインシデント管理やインシデント管理サービスの認識について気になる点がいくつか出てきたのでまとめようと思います。
確実に誤っている点あるかと思いますのでその点は若手故のご愛嬌ということで皆様お許しください。
## インシデント管理の定義
こちらはZendesk様のブログで紹介されているのでそちらを引用いたします
インシデント管理：
何らかの理由でユーザーがシステムを正常に利用できなくなったときに、その原因を取り除き、再びシステムを正常に利用できるようにするためのサポート体制のことを指す。ITサービスや情報システムの運用管理で使われ、主にユーザーサポートが担当するのが一般的。

https://www.zendesk.co.jp/blog/incident-management-jp/#:~:text=%E3%82%A4%E3%83%B3%E3%82%B7%E3%83%87%E3%83%B3%E3%83%88%E7%AE%A1%E7%90%86%EF%BC%88Incident%20Management%EF%BC%89%E3%81%A8,%E3%81%AE%E3%81%8C%E4%B8%80%E8%88%AC%E7%9A%84%E3%81%A7%E3%81%99%E3%80%82

## インシデント管理サービスとは？
インシデント管理サービスの定義はPagerduty様のブログで紹介されているのでそちらを引用いたします。
インシデント管理サービス：
「通常状態とは異なる何か」がおこった場合に検知・通知し、根本となる原因を探ってくれるサービスを指します。
そして、インシデント管理サービスと検索した際に挙げられるのは以下です。
・Servicenow
・Zabbix
・hinemos
・Redmine
・ServiceDesk Plus
・Pagerduty
・Jira Software
・konpira
・XonOps

上記サービスにはシステム障害の検知に特化したサービスや監視を目的としたサービスも含まれます。
もう少し言うと、インシデント管理サービスはインシデント管理とITSM・ServiceDesk・ヘルプデスクサービスの大きく２つに分かれると理解しています。
その理解に立った上で上記サービスをまとめると以下になります。
＜障害の検知・監視サービス＞
・Zabbix
・hinemos
＜インシデント管理サービス＞
・Servicenow
・Pagerduty
・Jira Software
・konpira
・XonOps
＜ITSM、ServiceDesk、ヘルプデスクサービス＞
・Servicenow
・ServiceDesk Plus
・Redmine
簡単な流れとしては、
①監視サービスで発報されたアラート（インシデント）をインシデント管理サービスで受ける。②インシデント管理サービスではアラートのフィルタリング設計、ナレッジの登録をしておいて対処不要なアラートを削減する③ITSM、ServiceDesk、ヘルプデスクサービスに連携され各担当者が案件の状態を確認し、必要に応じて対処 です。

サービスによっては、ServiceDeskとしての側面を有していたり、インシデント管理もオプションで用意している場合もございますので詳細は各サービスサイト等でご確認ください。
## 自部門で必要なサービスは？
私が所属する部門では月間のアラート件数が約500件発生していて、
その内対処不要なアラートが7~8割を占めます。

現状の運用は、監視サービスからServicenowにアラートが連携され、各担当者がServicenow上で案件の状態を確認し、必要に応じてコミュニケーションしていく運用です。

運用における課題は、
①対処不要なアラートが多い
②アラートの重要度の重みづけができていない
①はオペレーターの負荷が大きく、②は重要なアラートを取りこぼすリスクが存在します。
Servicenow上でフィルタリングの設定とアラートの重要度の重みづけができれば上記改善されるのですが、そこまで詳細にできる訳ではないようでした。（もし、できるようでしたら教えてください）
なので、自組織においてはアラートのフィルタリング設計が細かく設定できるインシデント管理サービスが必要と考えています。
## まとめ
インシデント管理サービスといってもそれぞれ得意な領域はあって、特徴を踏まえておくことが大事だなと思いました。加えて自組織の運用の課題が何でそれに対して解決できるサービスは何なのかを明確にすることが重要です。
文系大人初心者プログラミングするよ🔰start


38歳にして、急にプログラミングをはじめることに。
急に？というか、元々やってみたいなと思っていました。

仕事で必要とか、何かの理由がはっきりあるわけではなく
目標が明確にあるわけでもない。

ただ、なんとなく
今はITとは違う業界で働いているけど、
ITに関わることができるようになるといいなぁ　とか
プログラミングとか出来たら素敵そう　とか:upside_down:
そんなことはずっと思っていて

まあでも？
仕事しながらだし、文系ですし
38歳他にやることあるやんとか笑
もにょもにょ考えてたら何年か経っており、、
思い切ってプログラミングスクールを申し込みました

さらっと学習をしてみたけど
とにかく卒業優先で進めてきたので
復習と今後使えるように学習してきたことをまとめたいなと思って
自分の忘備録用に記事書いていきます:hugging:！
thin wall structure x軸方向応力σxと円周方向応力σt 第10章 薄肉圧力容器 基本例題10.01 p335「材料力学演習(20221021)」をsympyでやってみたい。

 # オリジナル
[基本例題10.01 p335](http://zairikiweb.starfree.jp/zai_enshuh/zai_enshuh_ver.3.3.pdf#page=340)＜[「材料力学演習(20221021)一括(ver.3.3)」を勉強したい。#sympy](https://qiita.com/mrrclb48z/items/c3274daf5f7a99cfe027#%E4%BD%9C%E6%A5%AD%E4%B8%AD%E7%A7%81%E3%81%AE%E8%A7%A3%E7%AD%94sympy)
　　　　　　　　？？？タブレット等で、pdfを開く事ができないかも。？？？　
# sympyで
ver0.2 (普通?は,ver0.1でしょうか？)
```python
from sympy import *

var('σx,σt',real=True)
var('D,t,p',real=True)
var('l'    ,real=True)
print("#",solve(Eq(pi*D*t*σx,pi*D**2*p/4),σx)[0])
print("#",solve(Eq(l*t*σt*2,D*l*p)       ,σt)[0])
# D*p/(4*t)
# D*p/(2*t)
```

ver0.1
```python
from sympy import *

var('σx,σt',real=True)
var('D,t,p',real=True)
var('l'    ,real=True)
Nx=pi*D*t*σx
Px=pi*D**2*p/4
eq=Eq(Nx,Px)
print("#",solve(eq,σx)[0])
Nt=l*t*σt
Pt=D*l*p
eq=Eq(Nt*2,Pt)
print("#",solve(eq,σt)[0])
# D*p/(4*t)
# D*p/(2*t)
```

# いつもの? sympyの実行環境と 参考のおすすめです。
[(テンプレート)](https://qiita.com/mrrclb48z/items/00dd08b0317069be9342)

# いつもと違うおすすめです。

https://qiita.com/mrrclb48z/items/65ae027b8a0fb1f0daa2

#### 参考文献

~~＞一部に等分布荷重を受ける単純支持はり~~
~~＞JSME p139~~
　
~~＞片持ちばり 1)~~
~~＞構造力学公式集 表5.1 片持ちばりの公式　p128~~
あるディレクトリ下にある.ts, .tsxファイルから、ramda.jsのどの関数が使用されているのかを調べるスクリプトをFSharpで書いてみた

会社でramda.jsの研修用資料を作成することになりました。全部の関数を紹介するのは無理があるため、とりあえずあるモノレポで使われているramda.jsの関数をすべて調べることにしました。

```fsharp
open System.IO
(* dir pathを渡されると、再帰的にファイルのパスを返す関数 *)
let rec getFiles dir =
    let files = Directory.GetFiles(dir)
    let dirs = Directory.GetDirectories(dir)
    files |> Array.append (dirs |> Array.collect getFiles)

(* ファイルのextnameがts, tsxである場合のみtrue *)
let isTsOrTsx (filePath: string) =
    let ext = Path.GetExtension(filePath)
    ext = ".ts" || ext = ".tsx"

(* file pathにnode_modulesが含まれていたらexclude *)
let excludeNodeModules (filePath: string) =
    let nodeModulesIndex = filePath.IndexOf("node_modules")
    nodeModulesIndex = -1

(* ().ts or .tsx) && not node_modules *)
let validFiles (dirPath: string) =
    getFiles dirPath |> Seq.filter isTsOrTsx |> Seq.filter excludeNodeModules

(* ファイルの中を1行ずつ確認し、"ramda"という単語があれば、その行を返す *)
let isRamdaLine (filePath: string) =
    let lines = File.ReadAllLines(filePath)

    lines
    (* ramdaがあれば返すけれど、複数行あってimport文が終了のときはNG *)
    |> Seq.filter (fun line -> line.Contains("\"ramda\"") && not (line = "} from \"ramda\";"))

(*
  import { drop, includes, take } from "ramda";
  こうあったときに、drop, includes, takeを取り出す
*)

let takeFunctionName (line: string) =
    (* lineがlength0であれば空 *)
    if line.Length = 0 then
        [||]
    else
        (* 文字をseqとして考えて、「{」が来るまでを削除。 *)
        let dropUntilBrace = line |> Seq.skipWhile (fun c -> c <> '{')
        (* 「{」を削除 *)
        let dropBrace = dropUntilBrace |> Seq.skip 1
        (* 「}」が来るまでを取得 *)
        let takeUntilBrace = dropBrace |> Seq.takeWhile (fun c -> c <> '}')
        let t = takeUntilBrace |> Seq.toArray |> System.String.Concat
        (* カンマがあればsplitしてtrimする *)
        let splitByComma = t.Split(',') |> Array.map (fun s -> s.Trim())
        (* join *)
        splitByComma

(* entry point *)
[<EntryPoint>]
let main argv =
    let dir = Seq.tryHead argv

    match dir with
    | Some dir ->
        let absolutePath = Path.GetFullPath(dir)
        let seqs = validFiles absolutePath |> Seq.collect isRamdaLine

        seqs
        |> Seq.map takeFunctionName
        |> Seq.concat
        |> Seq.distinct
        |> Seq.sort
        |> Seq.iter (fun s -> printfn "%A" s)

    | None ->
        printfn "no dir"
        exit 1

    exit 0
```

ちょっと力技で解決したところもありますが……。
普段はこんなにコメント書きませんが、あんまり使わない言語はcopilotに頑張ってほしくてコメント多めです。あとで見たときにコメントがないと、メイン言語以外だと本当にリーディング辛いし。

ということで、わが社のモノレポでは
"append"
"clone"
"collectBy"
"concat"
"difference"
"drop"
"dropLast"
"equals"
"filter"
"flatten"
"fromPairs"
"head"
"includes"
"insert"
"intersection"
"isEmpty"
"isNil"
"keys"
"last"
"map"
"mergeAll"
"move"
"omit"
"partition"
"pick"
"pickAll"
"pipe"
"pluck"
"prop"
"range"
"reject"
"remove"
"repeat"
"reverse"
"sortBy"
"splitEvery"
"sum"
"tail"
"take"
"takeLast"
"toPairs"
"union"
"uniq"
"values"
"without"
"xprod"
という関数が使用されていました。
どうせならuniqというかdistinctする前にカウントしておいて頻度順に並べ替えできるようにすれば良かったな。というか、そのように作り直しましょう。
Oracle よく使われるメソッドメモ

```
・例：DECODE（LTRIM(CONCAT(TO_CHAR(CREATED,'hh24'),'時'),'0'),'時',1,0）
 -TO_CHAR(DATE,FORMAT)　//DATEを整形する
 -CONCAT(AAA_String,ADD_String) // AAA_String後ろにADD_Stringをつける
 -LTRIM(AAA_String, '0') //AAA_Stringの左側の０を削除する、'0'書略の場合、スペースを削除する
 -DECODE(expression,search_value,result,default_value) //expression=search_valueの場合、resultを返す、そうじゃない場合、default_valueを返す

例の意味は「夜０時〜１時まで作ったデータの場合、１を返す、そうじゃない場合、０を返す」

・/*+ PARALLEL(table_name, degree) */ //table_nameのテーブルを「degree」段階で並行する

・NVL（expr1, expr2） //expr1がNULLの場合、expr2を返す、そうじゃない場合、expr1を返す

・例：　「SELECT EMP_ID, LISTAGG(SHIKAKU,',') WITHIN GROUP(ORDER BY SHIKAKU) AS SKILL FROM S_EMP_SHIKAKU GROUP BY EMP_ID;」
 -LISTAGG(column_name,',') WITHIN GROUP(ORDER BY order_column) //column_nameは結合したい項目、order_columnは結合した項目の順序指定

 例の意味は「社員IDごとの資格を’,’区切って表示する」

 ・TRUNC（SYSTEMDATE）　// 現在日時「2023/12/13 18:09:45」 出力は「2023/12/13 00:00:00」
  TRUNC(123.45) // 結果は「123」

・MOD（10,3） // 10/3のあまりは「１」を返す

・LPAD（EMPID,5,'0'） //EMPIDは５桁足りない場合、左側０を補足

/*+ APPEND */ //データベースの大量データ挿入パフォーマンス向上　
```
Androidスマートフォンのおすすめアプリ(ツール)

本記事は、[めんどい太郎の Advent Calendar 2023](https://qiita.com/advent-calendar/2023/mendoitarou_first_calendar) 16日目の記事です。

# はじめに

この記事は初心者が書いています。

今回はAndroidのおすすめアプリ(ツール)を紹介します。

# アプリ

箇条書きします

- GitHub
- Termius
- ConoHa
- Microsoft Math Solver
- Files
- ショートカット＋

## GitHub

[Google Play Store](https://play.google.com/store/apps/details?id=com.github.android)

GitHubの公式アプリです。

2段階認証の設定ができたりします。めちゃ便利です。

ただ、ToDoが使えないのが微妙です。

## Termius

[Google Play Store](https://play.google.com/store/apps/details?id=com.server.auditor.ssh.client)

AndroidでSSHができます。

以外と便利です。

ESCなどがボタンで表示されたりするので結構便利です。

まぁキーボードが小さいのでコマンドうち間違えたりしますが()

このアプリはクラウド同期ができますが有料です。

まぁ別にクラウド同期はしなくていいと思います()

SFTPもできちゃうのが神です。

めちゃ便利です。

## ConoHa

[Google Play Store](https://play.google.com/store/apps/details?id=com.conohaapps)

ConoHaのVPSやWingなどを契約している人は非常に便利なアプリです。

モニタリングできますし、コンソールにアクセスすることもできます。

かなり便利です。

サーバーを再起動したりもできるのがいいです。

サーバーのIPアドレス確認に使ったりします。

## Microsoft Math Solver

[Google Play Store](https://play.google.com/store/apps/details?id=com.microsoft.math)

計算ソフトです。

方程式の計算ができたり、途中式が表示されるのが便利です。

よく使ってます。

## Files

[Google Play Store](https://play.google.com/store/apps/details?id=com.marc.files)

Androidに標準で搭載されているファイルマネージャーが起動できるアプリです。

標準搭載のファイルマネージャーじゃないとappのdataが見れないので案外役に立ちます。

## ショートカット＋

[Google Play Store](https://play.google.com/store/apps/details?id=net.west_hino.shortcut_plus)

システムUIデモモードを起動できます。

時間を秒表示にしたい人間なので使います。

まぁ初期化時に一回使うぐらいですが。

# 終わりに

Androidでおすすめなアプリ(ツール)を紹介しました。

これからも追加するかもしれません。
MCP9701で遊ぶ(表引き)(もっと)


x MCP9701-E/TO 販売コード 103199

MCP9701で遊ぶ(表引き)(もっと)

おまけ(ichgojam)


https://qiita.com/caa45040/items/183db8f70c96765b3009


目的
温度センサーのテスト
もっと簡素化



![o_cop853.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/ae428c8f-4913-95a3-71f5-b0248006b64f.jpeg)




```c++


//S_SER_9701_O5_031_1

//インクルド
#include <Arduino.h>
#include <HardwareSerial.h>


//定義
char ss[] =  {
  "#9#9#9#8#7#7#6#5#5#4#3#3"
  "#2#1#1#0-9-9-8-7-7-6-5-5"
  "-4-3-3-2-2-1-1 0 1 1 2 2"
  " 3 4 4 5 6 6 7 8 8 91010"
  "111212131414151616171818"
  "192020212222232424252626"
  "272828293030313232333434"
  "353636373838394040414242"
  "434444454546474748494950"
  "50#0#0#0#0#0#0#0#0#0#0#0"
  "#0#0#0#0#0#0#0#0"
};


//初期化
void setup()
{

  delay(3000); //not delete

  //シリアルの初期化
  Serial.setTx(PA2_ALT1);
  Serial.setHalfDuplex();
  Serial.begin(9600);

} //setup


//メインループ
void loop()
{

  //アナログ値の読み込み
  int s = analogRead(PB7);   // PIN1

  //s=250;

  //温度の表示

  Serial.print  ( (char)ss[((s>>2)&0x7f)*2]   ); //10の桁
  Serial.println( (char)ss[((s>>2)&0x7f)*2+1] ); // 1の桁

  //1秒の待ち
  delay(1000);

} //loop



```
Pythonで「リストの長さ(要素数)を取得する」の動作を確認してみた

# 概要

Pythonで「リストの長さ(要素数)を取得する」の動作を確認してみました。以下のページを参考にしました。

https://www.javadrive.jp/python/list/index5.html

# 実装

以下のファイルを作成しました。
```sample.py
colorlist = ["Blue", "Red", "Green", "White", "Black"]
print("要素数は " + str(len(colorlist)) + " です。")
```

以下のコマンドを実行しました。
```
$ python3 sample.py 
要素数は 5 です。
```

# まとめ

何かの役に立てばと。
【PostgreSQL】パラメータによるパフォーマンスチューニング

## 初めに
性能を最大限に引き出すためには、様々な設定パラメータの理解と適切なチューニングが必要です。本記事では、PostgreSQLの設定パラメータについて、特にパフォーマンスに影響を与えるパラメータにフォーカスしてまとめていきます。

## PostgreSQLの設定パラメータとは

PostgreSQLの設定パラメータは、データベースの動作を制御する様々な値です。これらのパラメータは、PostgreSQLの設定ファイルである`postgresql.conf`に記述されています。パラメータにはデータベースの動作モード、リソースの利用方法、ログの詳細度など、さまざまな項目が含まれています。

## パフォーマンスに影響を与える主要なパラメータ

### shared_buffers

shared_buffersは、PostgreSQLがデータベースのキャッシュとして利用するメモリ領域のサイズを指定します。このパラメータを大きくすると、より多くのデータがメモリ上にキャッシュされ、ディスクへのアクセスが減少します。しかし、設定値を大きくしすぎると、OSのキャッシュ領域を圧迫する可能性があります。通常はシステムメモリの25%程度を設定することが推奨されます。

### work_mem

work_memは、ソート操作やハッシュテーブル作成など、クエリ実行中に発生する一時的なデータを格納するためのメモリ領域のサイズを指定します。この値を大きくすると、ディスクへの書き込み（ディスクI/O）が減少し、クエリのパフォーマンスが向上します。ただし、同時に実行されるクエリの数により、必要なメモリ量が増加するため、設定には注意が必要です。

### maintenance_work_mem

maintenance_work_memは、データベースのメンテナンス操作（VACUUM、ANALYZE、CREATE INDEXなど）に利用するメモリの最大量を指定します。この値を大きくすると、メンテナンス操作のパフォーマンスが向上します。ただし、他の操作に必要なメモリを圧迫しないよう、適切な値を設定する必要があります。

### effective_cache_size

effective_cache_sizeは、PostgreSQLがクエリの最適化を行う際に、OSがディスクキャッシュとして利用可能なメモリ量として想定するサイズを指定します。これにより、クエリプランナーはディスクアクセスの代わりにメモリアクセスが可能であると想定して、最適なクエリ計画を作成します。通常はシステムメモリの50%を設定することが推奨されます。

## パフォーマンスチューニングの注意点

設定パラメータの調整は、データベースのパフォーマンスを大きく向上させることが可能ですが、適切な値を見つけるためには検証が必要です。実際のワークロードに基づいてパラメータを調整し、その結果をモニタリングすることが重要です。

また、全てのパラメータを最大値に設定することが最適とは限りません。各パラメータは互いに影響を与えるため、バランス良く調整することが重要です。

## まとめ

PostgreSQLのパフォーマンスは、設定パラメータにより大きく左右されます。しかし、その設定は一筋縄ではいかず、システムの特性やワークロードにより最適な値は変わります。適切なパフォーマンスチューニングには、各パラメータの理解と、それらの調整による影響を評価する能力が求められます。これらの知識を身につけることで、PostgreSQLのパフォーマンスを最大限に引き出すことができます。
Salesforce認定アドミニストレーター試験レポート

この投稿は先日「Salesforce認定アドミニストレーター試験」に合格しましたので、
そのレポートになります。

【目次】
１．受験することになった経緯
２．主な勉強方法（使用した教材）
３．試験結果・感想
４．まとめ

１．受験するまでの経緯
　2023年度に入ってすぐに、担当プロジェクトにおいて、2024年度から
　既存システムのUI部分をSalesforceで作り変えることが正式に決まりました。
　私はSalesforceの実務経験ゼロの状態ですので、
　そのスキルを身に付けるのが急務となりました。
　一方、当社では同様にSalesforceでの開発が必要となるプロジェクトの
　引き合いが複数存在し、技術者育成を兼ねた本認定試験の勉強会が発足しましたので、
　そこに参加させてもらうこととなりました。

２．主な勉強方法（使用した教材）
①Trailhead(trailmix)
　勉強会でもまずはTrailheadの実施が有効ということで、以下のTrailmixを
　100%になるまで実施しました。
　但し、文章を読んで全て理解するのは私のような初心者には厳しく、
　分量的にも時間がかかり過ぎることが実施してみてすぐに分かりました。
　そこで各モジュールの最後にあるテストを文章で答えを探して解く形にしました。
　最後のテストには選択式の問題の場合と、プレイグラウンドでハンズオンを行う場合が
　ありますが、いずれも同じ方法で実施しました。
　これにより、Salesforceの画面を実際に触りながら全体感も把握できました。
　②の問題で間違えた時に読んでいなかった文章を読んで教科書のような
　使い方もできるので、他に教科書は要らないですし、必須と思います。
　（ハンズオンはあちこち躓いて時間もかかりますが、確実に理解を深めることに
　　繋がったと思います）

https://trailhead.salesforce.com/ja/users/welcome4/trailmixes/prepare-for-your-salesforce-administrator-credential

②Web問題集
以下に挙げた問題集をこの順番で3回繰り返して解きました。
間違えた問題に関する事項は上記trailheadの文章や公式ヘルプを検索して、
理解するようにしました。

A.SALES 4 BOX（424問）
　難易度低めですが、一通り解くと知らない用語に出くわすことは無くなる印象。
  但し、重複・類似した問題も多いので、2回目からは間違えた問題のみ解く形としました。

https://sales4box.com/admin_q10/

B.Salesforce認定アドミニストレーター公式模擬問題を翻訳&解説してみた（153問）
　Aには解説がほとんどなく、公式のヘルプを探りながら理解するといった感じで
　効率が悪かったので、解説が詳細なページは無いかと探して行きついたのがこれです。
　（その後、勉強会でも紹介されたので安心感をもって取り組んだ）
　公式模擬問題がベースなので問題の質は一気に上がりますが、
  解説が丁寧なので理解がだいぶ進んだと思います。

https://qiita.com/Takaa/items/f2eb81e49c614fb767de

C.JPN試験（206問）
　実際の問題に近い問題がどこかに無いかと有料も含めて探したところ、
　以下が無料で精度も高そうだったので、こちらの2023/10/6バージョンと
　2023/11/16バージョンを実施しました。
　類似の問題がかなり出ていたと思うので、実施して正解でした。
　但し、私は学習中に2023/11/16バージョンが出たので、結果的に2バージョンを
　実施しましたが、重複が多いので1バージョンでも良かったかもしれません。
 
https://www.jpnshiken.com/exam/ADM-201-JPN-salesforce-certified-administrator-adm-201%E6%97%A5%E6%9C%AC%E8%AA%9E%E7%89%88-8818.html

３．試験結果・感想
　試験は105分で60問を解きますが、見直しも含めて半分くらいの時間で完了しました。
　結果は「合格」で、以下表の通り、正答率は83%程度と思われます。
　65%で合格ですので、余裕を持って合格できて良かったです。
　（単元ごとの問題数と結果得点は公表されないため、
　　結果は計算により求めた想定値となります）
|単元|配点(%)|問題数(想定)|得点数(想定)
|---|--:|--:|--:
|設定とセットアップ|20|12|9
|オブジェクトマネージャとLightning アプリケーションビルダー|20|12|9
|セールス＆マーケティングアプリケーション|12|7|6
|サービス＆サポートアプリケーション|11|7|6
|生産性向上とコラボレーション|7|4|2
|データ管理＆分析|14|8|8
|ワークフロー/プロセスの自動化|16|10|10
|(合計)|100|60|50

４．まとめ
　実務経験ゼロの初心者からの受験でしたが、上記のような対策で合格できました。
　実際の問題では知識を問うというよりは、各想定される場面において、
　何を使えば実現できるかや、どういう設定をするのが望ましいかという
　問題になっており、丸暗記では難しいとは思いました。
　今回の受験までの学習でSalesforceがどういったものかは理解できたので、
　実務にも生かしていきたいと思います。
　この次は忘れない内に認定Platformアプリケーションビルダーに挑戦します！

以上
【Rails】gem configで定数管理を行う手順

# はじめに
`CORS`の設定でこのようにドメインをベタ書きしている点が気になったので、gem `config`を用いて定数管理する方法をまとめました。
```ruby:config/initializers/cors.rb
Rails.application.config.middleware.insert_before 0, Rack::Cors do
  allow do
    origins 'http://localhost:8000'

    resource "*",
             headers: :any,
             methods: [:get, :post, :put, :patch, :delete, :options, :head]
  end
end
```

# 導入手順
https://github.com/rubyconfig/config

```ruby:Gemfile
gem 'config'
```
```ruby
bundle install
```

`generate` コマンドを実行すると、`config`配下に環境別で定数管理できるファイルが作成されます。
```ruby
rails g config:install
```
```ruby
config/initializers/config.rb
config/settings.yml
config/settings.local.yml
config/settings/development.yml
config/settings/production.yml
config/settings/test.yml
```

|ファイル名|役割|
| ---- | ---- |
| config/initializers/config.rb | 全体設定ファイル|
| config/settings.yml | すべての環境で利用する定数を定義 |
| config/settings.local.yml | ローカル環境で利用する定数を定義 |
| config/settings/development.yml | 開発環境のみで利用する定数を定義 |
| config/settings/production.yml | 本番環境のみで利用する定数を定義 |
| config/settings/test.yml | テスト環境のみで利用する定数を定義 |

# 使用方法
`yml`形式で書くことができ、`Settings`はじまりで定数を呼び出すことができます。
```yml:config/settings/development.yml
front_domain: http://localhost:8000
```
```yml:config/settings/test.yml
front_domain: http://localhost:8000
```
```yml:config/settings/production.yml
front_domain: https://sampleapp.com
```

このように各環境に同じキーで値を設定することで、**呼び出しは1回で済みます。**

```ruby:config/initializers/cors.rb
Rails.application.config.middleware.insert_before 0, Rack::Cors do
  allow do
    #origins 'http://localhost:8000'
     origins Settings.front_domain

    resource "*",
             headers: :any,
             methods: [:get, :post, :put, :patch, :delete, :options, :head]
  end
end
```
ユーザシナリオを想定したテストで障害抑制をしてみたおはなし

◆この記事を読むのにかかる時間：約5分程度
◆この記事の主な対象者：仕様変更や共有漏れなどによる障害を減らしたい方
## 1.はじめに

みなさま今年も一年お疲れさまでした。
恒例のアドベントカレンダーの時期になりました。

私事ですが、今年は担当するタイトルが増え、
新たな環境で障害削減の取り組みなどを進める機会が多くありました。

今回は新たに実施した「ユーザシナリオを想定したテストで障害の抑制を図った」取り組みについて、ご紹介していきたいと思います。

## 2.課題感
今回の事例とするタイトルでは以下のような課題感に直面していました。

<b>a.ユーザーの意向を最後まで検討するがゆえに、仕様確定の遅延・QA期間中の変更が多発</b>
上記に伴って実装の遅延や設定値の調整などがテスト中も多く発生しており、
<b><font color="red">綺麗な実装状態でのテストが行えない状況</font></b>が多く発生していました。

<b>b.職掌内、QAへの仕様変更の共有が上手くされていないパターンが頻発している</b>
例えば、<b><font color="red">設定変更が入ったが、別の影響箇所の表記は古い仕様のまま</font></b> などの不整合が目立つ状況が多く発生していました。
また、<b><font color="red">テスト後の機能に対して変更が入っても関係者に連携がないままリリースされてしまう</font></b> といった、リスクの高い状況もありました。

## 3.対策
課題の事象に関しては、
前提として、仕様変更があった際には関係者に周知を実施する、
テスト終了後に変更を行わない、といったフローを設けていますが、
それでも事業やタイトル、市場の状況変化にあわせて、仕様変更は発生します。

QAチームもなるべくこれらの状況に柔軟にかつ、ユーザが不利益を被ってしまう障害リスクを排除するように対応するため
テスト終了後～リリース前の最終状態での、
<b><font color="red">仕様が最新化された状態で施策の整合性が保たれているか
テスト未依頼のままリリースされているものがないか</font></b> 、<b><font color="red">既存機能に問題が生じていないか</font></b>などの確認を目的とした、
<b><font color="red">「ユーザの観点を想定した通しテスト」</font></b>を実施することにしました。

テストの概要は以下となっています。

<b>確認実施タイミング</b>
QA期間後～リリースまでの数営業日の間に実施。
※可能な場合はQA期間の最終日などを充てる

<b>確認観点</b>
主に以下のような観点で実施。
・各影響範囲の仕様情報と実機/設定値の状態が一致しているか
　→仕様変更の共有漏れによる不一致を防ぐ観点
 
 ・実機内で出ているもの対して整合性が取れており違和感がないか
 
・定常的に入る施策更新が過不足なく正しく入っているか
　→ユーザが利用する定常箇所などで、連携漏れなどによる作業未実施を防ぐ観点
 例）ガチャラインナップの更新など

以下にテストサンプルのケースを添付します。

![tc_sumple001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540789/eec65556-9432-494b-2643-99d2d6da8f3f.png)

## 4.取り組みから得られた結果
実際に本テストを導入したことで以下の結果が得られました。

<b>数値結果：</b>
<b><font color="red">1リリース平均で約12.7件の不具合検知をおこなうことができた。
※1リリース毎に検知される不具合総数の約10-20%</font></b>

<b>主な検出内容：</b>
・仕様変更の共有漏れの箇所やQA実施後に連携なく調整をした内容
・定常施策での更新漏れ
・表示系の違和感や不備など（優先度は高くない見切れやレイアウトなど）

テストの目的としている連携・共有漏れなどに起因する不具合が検知できているという点で、
一定の取り組みの効果はあるように感じました。

一方で、当然ながらコスト面はテストを実施した分膨らんでしまうため、
その点は開発チームと事前にしっかりと合意を得ておく必要があります。

## 5.おわりに
いかがだったでしょうか。

同じような状況でのテスト・障害抑制の課題感を抱えている方々は、
特にゲームの開発現場だと多いのではないかと思います。
この記事の取り組みが参考になりましたら、ぜひお試しいただけると幸いです。

それでは皆さま、よい年末をお過ごしください。
FeatureFlagを使った機能のE2Eテスト

この記事はZOZOアドベントカレンダー Series５　１５日目の記事です。

アウトカムをどんどん出していくためにFeatureFlagを活用しているチームは多いと思います。

簡単に機能をON/OFFできる仕組みは有用ですし、なにより安心してリリースできるのがいいですよね。

困った点としてはE2Eテストをどうするか？

リリース時にONして、不具合が出たらすぐOFFできるようにしたいと言ったケースもあるため、E2EテストではOnのときのテストとOffのときのテストを両方やっておきたいですよね。

ただ、どうやって切り替えるのかが問題です。

自分たちのチームでは、E2Eテストを３つに分けました。

1. FeatureFlagを使っていない機能のテスト
2. FeatureFlagをONにしてFeatureFlagを使っている機能のONときのテスト
3. FeatureFlagをOFFにしてFeatureFlagを使っている機能のOFFときのテスト

といった感じです。結果は最後にマージして出力します。

また、自分たちは、AWSのAppConfigを使っていて、ECSのサイドカーコンテナ経由でFeatureFlagを取得しているので、基本localhostでFlagを取得できます。

そこでローカルでのテストは[WireMock](https://wiremock.org/)を使ってFeatureFlagのモックを活用しています。

WireMockでは、スタンドアロン版とJunit組み込み版がありますので、E２EテストするときはJunitの組み込み版を、ローカルで開発しているときはスタンドアロン版と使い分けることでFeatureFlagのON/OFFの開発が容易にできるようになります。

ぜひご活用ください。
metabaseでDBの登録時に no more authentication methods available が出たときの対処法

# metabaseでDBの登録時に no more authentication methods available が出たときの対処法

DBの追加時に以下のメッセージが出ることがありました。

```
no more authentication methods available
```

エラーメッセージがおかしいです。
おそらく認証に失敗したときに出るエラーです。

認証情報が正しいことを確認してください。
Azure Bot Service で Azure Communication Services のチャネルを利用する際の注意点

# はじめに
Azure では、Azure 上で Bot を作成から公開まで管理できる [Azure Bot Services](https://learn.microsoft.com/ja-jp/azure/bot-service/index-bf-sdk?view=azure-bot-service-4.0)があります。

その[チャネル](https://learn.microsoft.com/ja-jp/azure/bot-service/bot-service-manage-channels?view=azure-bot-service-4.0#channels-list)の一つに、[Azure Communication Services](https://learn.microsoft.com/ja-jp/azure/communication-services/overview)があります。要は Azure Communication Services でスレッドを作成し、チャットを送信した際に Azure Bot Services から応答が返ってくるようなイメージです。

今回はその下記のチュートリアルを実施した際に注意点をメモ程度に記載します。
[クイック スタート: ボットをチャット アプリに追加する](https://learn.microsoft.com/ja-jp/azure/communication-services/quickstarts/chat/quickstart-botframework-integration)

# チュートリアルやってみた
まずはチュートリアルをそのままやってみると、なぜか Bot Services から応答が返ってこない。。。（EchoBot なので、”:Echo: Hello World” と返却されるはず）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679419/ee27a373-a1f5-6862-4d6b-14cf6f172f51.png)

Azure Bot Services の方も正常性が問題となり、スレッドがないと出る。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679419/0c320eb0-d930-cd82-b300-77ab04f5c53e.png)

スレッドを早く閉じすぎたからかなと思い、下記のコードを一度消して見たところ、Azure Bot Services の正常性は治ったもののやはり Azure Bot Services から応答がない。。。
```c#:program.cs
chatClient.DeleteChatThread(threadId);
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679419/44f2514b-b35d-4b54-771a-45b42acf8d40.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679419/8b899691-43ab-aeb0-be0d-257141329c5a.png)


# 原因
原因としては、chatThreadClient では定期的に GetMeesages メソッドでスレッド内のメッセージをポーリングして取得するのですが、Azure Bot Services からの応答が返ってくる前にアプリの処理が終わっていたことが原因でした。

なので、じょうきしょりのまえにスリーブ処理を入れてあげると、正常に Azure Bot Services から応答が返却されました。
```c#:program.cs
 Console.WriteLine("====Interval Sleep====");
 Thread.Sleep(5000);
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679419/3657e51d-861f-8194-f886-3f4242a97c2d.png)


# まとめ
当初はサーバー側のログを色々見ていても気付かず、ドキュメントにも明確に記載がなかったので意外と躓き記事にしました。chatThreadClient が  GetMeesages メソッドを行うポーリング間隔を変更できるかどうかについては、分かり次第こちらの記事に追記します。
Notion APIでYouTubeやVimeoの動画を埋め込む方法

# はじめに
Notion APIの正式リリースからもうすぐで二年を迎えます。
リリースされてから様々な機能が追加されましたが、今回はNotion APIを利用してYouTubeやVimeoの動画を埋め込む方法を紹介します。

# 事前準備

今回は以下のステップでNotion APIの環境を構築しました。

1. 「[my-integrations](https://www.notion.com/my-integrations)」のページからAPIキーを発行
1. APIで操作したいNotionのページの「Connections」＞「Add connections」から先程作成したインテグレーションを追加
1. 操作したいページのURLからブロックIDを取得

詳細は以前執筆した以下の記事や公式のガイドをご確認ください。

https://qiita.com/thomi40/items/fe2a828746f31ad827ba

https://developers.notion.com/docs/create-a-notion-integration

# Notion APIでYouTubeの動画を埋め込む
早速Notion APIでYouTubeの動画を埋め込んでみましょう。
`block_id` と `$NOTION_API_KEY` はそれぞれの環境に合わせて設定してください。

```shell
curl -X PATCH 'https://api.notion.com/v1/blocks/{block_id}/children' \
  -H "Authorization: Bearer $NOTION_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Notion-Version: 2022-06-28" \
  --data '{
    "children": [
      {
        "type": "video",
        "video": {
          "type": "external",
          "external": {
            "url": "https://www.youtube.com/watch?v=CpqhPcswA1Q"
          }
        }  
      }
    ]
  }'
```

ブロックのタイプは `"type": "video"` で指定し、 `external` の `url` でYouTubeのURLを指定します。
YouTubeのURLは以下の形式を指定することで埋め込まれることを確認しました。
* `https://www.youtube.com/watch?v=[id]` 
* `https://www.youtube.com/embed/[id]` 

「2023年12月 APIテスト用」というNotionのページに対してcurlを実行すると、以下のキャプチャのようにYouTube動画が埋め込まれました。

<br>

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134341/c462b008-a932-63ea-1a20-71d735c04808.png" width=50%>


# Notion APIでVimeoの動画を埋め込む

動画の埋め込みは先ほど紹介した `"type": "video"` が基本ですが、Vimeoの埋め込みに関してはこの記事を執筆している2023年12月時点ではvideoブロックをサポートしていないため、以下のように別の方法で埋め込む必要があります。


```shell
curl -X PATCH 'https://api.notion.com/v1/blocks/{block_id}/children' \
    -H "Authorization: Bearer $NOTION_API_KEY" \
    -H "Content-Type: application/json" \
    -H "Notion-Version: 2022-06-28" \
    --data '{
        "children": [
            {
                "embed": {
                    "url": "https://player.vimeo.com/video/783455051"
                }
            }
        ]
    }'
```

YouTube動画の場合はvideoブロックを使用しましたが、Vimeoの場合は`embed`でURLを指定することで動画を埋め込むことが可能です。
VimeoのURLは `https://vimeo.com/〜`ではなく、`https://player.vimeo.com/video/〜`の形式を指定しました。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134341/0ecbf7b0-0541-cbda-9b3f-9d5e2c363334.png" width=50%>

curlコマンドを実行すると先程のYouTube動画の下の部分にVimeoの動画が埋め込まれました。

# まとめ
今回はNotion APIを使った動画の埋め込みに関して紹介しました。
動画の埋め込みは基本的にはvideoブロックを指定し、Vimeoの場合はembedブロックを使うことで動画を埋め込むことができました。
それぞれの詳細は以下のドキュメントも参考にしてください。

https://developers.notion.com/reference/block#embed

# 告知
明日はM.Hさんによる「Stable DiffusionのSDXL1.0モデルと拡張機能のあれこれ」です。
引き続き、[GMOアドマーケティング Advent Calendar 2023](https://qiita.com/advent-calendar/2023/gmo-am) をお楽しみください！
【解決】Mac + Logicool MX Ergoのジェスチャー「デスクトップ移動」が効かない問題

# 結論

どうも内部的には単に「Ctrl + ←/→」のショートカットを実行しているだけのようなので（真偽不明）、Preference>Keyboardの以下の2つが無効になっていると動作しないみたいです。チェックをつけて有効化しておきましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304979/73c80e0e-d86a-629e-184a-f71aab3da325.png)