OmniAICreator/Qiita-1.07M huggingface dataset:
Laravel8.xのEloquentから$dates機能が消えた!?

# 概要
LaravelのEloquentモデルにて日付プロパティを`Carbon`インスタンスとして扱いたい場合、Laravelのバージョン(7.xから8.x)によってキャストの仕方が異なります。

## Eloquentでの日付キャストする方法
### [Laravel7.x 日付ミューテタ](https://readouble.com/laravel/7.x/ja/eloquent-mutators.html)

>モデルの$datesプロパティをセットすることにより、データ属性を追加できます。

```php
protected $dates = [
    'seen_at',
];
```

### [Laravel8.x 日付のキャスト](https://readouble.com/laravel/8.x/ja/eloquent-mutators.html)

Laravel8.xのドキュメントでは、日付ミューテタの記述がなくなっています。

>デフォルトでは、Eloquentはcreated_atカラムとupdated_atカラムをCarbonのインスタンスへキャストします。これによりPHPのDateTimeクラスを拡張した、多くの便利なメソッドが提供されます。モデルの$castsプロパティ配列内で日付キャストを追加定義すれば、他の日付属性をキャストできます。通常、日付はdatetimeかimmutable_datetimeキャストタイプを使用してキャストする必要があります。

```php
protected $casts = [
    'seen_at' => 'datetime:Y-m-d',
];
```

## 使い方
`Carbon`の`format`メソッドを利用する場合

```php
$user = App\User::find(1);

return $user->seen_at->format('Y-m-d');
```

なお、配列やJSONにシリアル化する場合にはEloquentモデルで定義しているフォーマットを採用してくれるようです。

>dateまたはdatetimeキャストを定義するときに、日付の形式を指定することもできます。この形式は、モデルが配列またはJSONにシリアル化される場合に使用されます。

# まとめ
Eloquentの日付プロパティを`Carbon`インスタンスとして扱いたい場合は、Laravel8.xからは、`$dates`ではなく`$casts`で定義する。
フォーマットも同時に定義しておけば、配列やJSONとしてシリアル化する場合に個別フォーマットする必要がない。
フィクションなどから拾う情報処理用語 その22 確率 (人造人間キカイダー)

人造人間キカイダー 第8話「カーマインスパイダーが無気味に笑う」(脚本：長坂秀佳、監督：北村秀敏、技斗:三島一夫 (C)石森プロ、東映)より

連続子供誘拐事件が起きていた。大勢の子供が拐われていた。孤児を養育する施設「ぐみの木学園」の研一少年も襲われかけた。その「ぐみの木学園」に自称伊賀忍者服部半蔵の16代目末裔の私立探偵服部半平ことハンペンが来ていた。そして光明寺ミツ子とマサル姉弟も来ていた。調子こいたハンペンは「助手の」ジローに任せるとほざいていたがジローはそこにはいなかった。「ぐみの木学園」教師雪村アキ子と研一少年から話を聞くハンペン。

ハンペン「さ、お聞きしましょう。君を3回も襲ったその怪物というのは、一体、どんな奴でしたか?」
雪村アキ子「あの、それが…あ、あー。」

なーんとハンペンの後ろに研一少年を襲った怪物ことカーマインスパイダーが降りてきていた。それをアキ子は見て気がついたのだがハンペンは

ハンペン「それが、どうしました?」

全く気がついていない。

アキ子「は、あのー。」

アキ子は前、すなわちハンペンの後ろを指差したが、ハンペンは未だ気が付かない。

ハンペン「はあ? ははは。だからどんな奴かと聞いとるんだ。」
カーマインスパイダー「つまり、こんな奴ってことだよ。」

流石にハンペンも気がつき悲鳴をあげた。
カーマインスパイダーは研一少年を拉致して外へ飛び出したがギターの音が聞こえてきた。で見ると

ジロー「ここだ。カーマインスパイダー。」

なぜ名前を知っていたのかは謎である…と思ったら第1話で主なダークロボットはシルエットでキカイダーに名前を名乗っていたね、すっかり忘れていたけど。

ジロー「スパイダー、弱い者いじめはやめろ。」

ジロー(伴大介…ではなくて金田治)は飛び降りて(伴大介が)戦闘開始。
カーマインスパイダーは抵抗したが

ジロー「チェインジ! スイッチオン! ワン、ツー、スリー。」

何故かスタジオの中に入って(?)キカイダーの姿に変身した。
でまあ色々あってカーマインスパイダーは退散した。
さてダークのアジトではダークの科学者星村ユカがギル教授に詰め寄っていた。

星村ユカ「プロフェッサーギル。あなたはいつになったら私の弟を探し出してくれるのですか?」
ギル教授「うーむ。」

逆ギレしたギル教授はアンドロボットを杖で殴り殺してしまった。ギル教授は新兵器・XR4号がいつできるのかをユカに尋ねた。でユカの答えは

ユカ「ですからそのためには無気力な子の血が必要だと言っているのです。」

子供はどんどん拐っているというギル教授にユカはこう答えた。

ユカ「今までの子供の血は使い物にはなりません。血液型がRH-でしかもスモールS型。その上、ラージQ型でなければなりません。100万人に1人しかいない血液型なのです。」

あ、あのう。すなわち確率は百万分の一である、最高で。これを聞きギル教授はプッツン! なんと言っているのかさっぱり聞き取れないほど興奮していた。そんな効率の悪すぎる作戦を実行するなど無茶であろう。

だが、なんと、その血液型を持つ少年がいたのである。研一少年だったのである。しかも研一少年はユカの生き別れの弟である可能性もあるという。それが今回の見どころ。長坂秀佳お得意のハッタリかました適当な作風全開の話が炸裂するのだが、詳細は映像で確認してください。後に長坂は「人造人間キカイダー」を伊上勝から「乗っ取った」のだが、そう本人が断言したのがよくわかる話である。
【備忘録】起動時に自動でapache2とmysqlを起動する

ファイルエクスプローラーでStartupフォルダを開く
Win+R で『ファイル名を指定して実行』を開く
shell:startup を入力してEnter
batファイル作成
XXXX.batファイルを作成する。（XXXXは任意の名前）
XXXX.batファイルは、以下の内容とする。
@echo off
wsl -d Ubuntu-20.04 -u root -- service apache2 start
wsl -d Ubuntu-20.04 -u root -- service postgresql start
[NewRelic] サブアカウント毎のInfrastructure agent バージョンをNRQLで取得する

# この記事について

NewRelicにおいて、各サブアカウントで利用しているInfrastructure agentバージョンを一括取得する方法について記載します。

# 背景

弊社ではNewRelicを利用して、多くのシステムを監視しています。
各システム毎にサブアカウントを払い出して、システム=サブアカウントという単位で分割して管理を行っています。

弊社で管理する親アカウントが１つあり、その子アカウントとして各システムごとのサブアカウントがぶら下がっているイメージです。
サブアカウントについては[こちら](https://docs.newrelic.com/docs/accounts/original-accounts-billing/original-users-roles/parent-child-account-structure/)をご参照ください。


各サブアカウントにおいて[Infrastructure agent](https://docs.newrelic.com/jp/docs/infrastructure/install-infrastructure-agent/get-started/install-infrastructure-agent/)を利用してEC2などのVMからメトリクスを収集しています。

このInfrastructure agent(以後エージェント)ですが、バージョンがリリースされてから2年間でEOLとなります。
https://docs.newrelic.com/docs/infrastructure/infrastructure-monitoring/get-started/infrastructure-agent-eol-policy/
気がついたらEOLになっているバージョンを利用しているということが起きかねません。

そのため、各サブアカウントにて利用しているエージェントのバージョンを一括取得して、EOLが近づいている(もしくは過ぎている)エージェントを利用しているサブアカウントがないかチェックできるようにしたいと思います。

NRQLを利用すればそれが可能であるため後述します。

# 取得方法

**親アカウント**のQueryBuilderからNRQLクエリを実行します。

実行するNRQLクエリは以下の通りです。

```
SELECT count(*) FROM  NrDailyUsage  FACET infrastructureAgentVersion, subAccountId, subAccountName WHERE infrastructureAgentVersion IS NOT NULL SINCE 1 day ago LIMIT MAX 
```

NrDailyUsageイベントからメトリクスを取得します。
https://docs.newrelic.com/jp/attribute-dictionary/?event=NrDailyUsage

ちなみに「LIMIT MAX」を入れないと結果が10行しか出力されないので注意しましょう。
https://qiita.com/K5K/items/085357cfd660f20f4b59


NRQLクエリを実行した直後はcountで降順ソートされるため、「Infrastructure Agent Versionの」右にあるソートボタンをクリックして、エージェントのバージョンで昇順ソートします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435280/61b6e261-78e1-17c0-eb1e-0f8331640b3f.png)

ソート後
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435280/4a819539-9ebd-0cd2-df49-a0d3267095f6.png)

出力結果はCSVにエクスポート可能です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435280/5969f1fd-5697-b3bf-cc48-dd40c76a3e44.png)
Nuxt3 / Vue3 - ID付きのページをルーティングして params を取得する

# pages

`pages/users/[id].vue` のようなページを作成する

ディレクトリを切る場合は `pages/users/[id]/index.vue` でも良い

( `_id.vue` ではないので注意 )

# params

useRoute を使う

```js
const route = useRoute()
const id = route.params.id
```


# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ


# Twitter

https://twitter.com/YumaInaura
死んでも構造化参照で重複データに連番をつける

# ※注意※
Microsoft365及びExcel2019以上のバージョンでのみ使用可能な関数を使用します

# 重複データに連番をつけたい
例えば以下のようなデータに出荷コードを付与したい
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416630/e8af1f46-0b8f-95a1-3a41-2864f443a831.png)
↓品目コードごとに連番を付与して出荷コードに……
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416630/13d6dbd4-b59c-f417-b21a-718e14376eb8.png)

## ChatGPTさんに話を聞いてみました

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416630/1b9aa9ec-0c5d-15c9-7cfa-f7015d0db880.png)
Googleで検索しても概ねこのような内容が出てくる

実装するとだいたいこんな感じ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416630/b94998d5-8edb-9e64-1f45-3c4d82a22e4f.png)


## 死んでも構造化参照したい
筆者は数式にA1とかの参照を見ると胃の中が荒れる病気を持っているためなんとか構造化参照でこれを実現する

## 先に結論
行ごとにユニークな番号を与え
自身の行が同じ品目コードのうち何番目に来るかを調べる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416630/e130989f-bb0c-ef26-d0f7-003cba2fd3d2.png)

## 詳しい説明
### ROW関数
セルのある行を返す関数
一意の値を付与するのに使用
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416630/e5a9f8e1-78f7-3a27-a4a5-b1d4f3f8b9c4.png)

### FILTER関数
> FILTER(配列, 含む, [空の場合])

Excel2019から使えるようになった関数
配列を「含む」にて指定のデータでフィルターした配列を返す
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416630/ab261f43-9419-3f2a-1ad7-9857af04ae1e.png)

### MATCH関数
> MATCH(検査値, 検査範囲, [照合の種類])

検査値のデータが検査範囲の何番目にあるかを調べる関数
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416630/d77c67c7-b7e0-e32c-5813-294181e95c3c.png)

FILTERで絞り込んだ番号のうち
自身の行番号が何番目にあるかを調べることにより
連番を付与
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416630/a68e56aa-d948-8b7b-8ac6-cd5d6efe39f2.png)


# 課題
## わざわざ列が1つ増える
今回一意な番号を振るために
列を追加してROW関数を使用したが
できれば列を増やさないようにしたい……
誰かスマートな方法おしえて……

## Excel2019以前では使用できない
FILTER関数がExcel2019以前では使用できないため
まだまだ現役なExcel2016あたりは別の方法を考えなければいけない
 ~~ちょっと想像つかないので誰かおしえて~~
フィクションなどから拾う情報処理用語 その21 業界用語 (ザ・ハングマンII)

ザ・ハングマンII 第9話「仮病の悪 大手術いびり出し作戦」(脚本：中村勝行、監督：小西通雄 (C)松竹芸能)より

時は1982年 7月30日金曜日。
元国家機関の中心的人物と想像される神島泰三ことゴッドは秘密の組織を作っていた。リーダーは紆余曲折の末、日下部孝介ことマイト(黒沢年雄)になった。メンバーには加納良次ことデジコン(名高達男)、辻雄太郎ことオショウ(植木等)、桑野多美子ことタミー(夏樹陽子)などがいた。なおゴッドの事務所は西新宿にあるビルにあった。

さて今回の標的は医者とグルになって仮病で入院した暴力団の組長の松宮(名和宏)である。看護師に化けて病院に潜入したタミーが松宮のベッドのマットに細工し、松宮がマットを持って来させた。早速マイトとデジコンが布団屋に化け、マットを持って松宮の病室に向かった。

警備員「ちょっと待った。君達、これをどこへ運ぶのですか?」
マイト「松宮様からでございます。」
警備員「松宮さん!」
マイト「はい。先程特別注文いただきまして、早く持ってかないと怒られますので失礼致します。」

マイトは後ろにいたデジコンに声をかけた．

マイト「小西君、行くよ。」

デジコンの本名は加納良次。小西と言う名前ではない。そう、これは内輪ネタもとい業界用語なのだ。今回の監督は小西通雄。マイトを演じる黒沢年雄さんがザ・ハングマンシリーズに呼び寄せた監督で黒沢さんのお気に入りだったし、黒沢さんはしょっちゅうアドリブを入れていた。更に脚本を書いた中村勝行さんはスタッフの名前を登場人物に取り込むネタが得意だった。誰(黒沢年雄、中村勝行、小西通雄)の発案かは不明だが、小西通雄監督の名前をぶっ込んだのである。まあ情報処理業界でもこういう内輪受けネタは多いが、それと似たようなものである。

さて名高達男さんことデジコンはこう答えた。

デジコン「はい，失礼します．」

警備員は怪訝な顔である。こうしてマイト達はマットを松宮のいる病室へ運び込む事に成功したのだが、続きは紙面の都合で書けないし、本題ではないので割愛する。どうなったのかは映像を見たりして確認してほしい。
HEROZはCDLEハッカソン2022にメンターとして参加

## CDLEハッカソンとは
[CDLEハッカソン2022](https://www.jdla.org/cdle-hackathon/)はG検定/E資格合格者が実際のデータを用いてモデル構築などを経験できる場です。
HEROZを含む5社がAI技術指導などのメンタリングとして参加しました。（1チームにつき1名のメンター）

## メンターとは
* 基本的には参加者の技術的なお手伝い
    * 参加者の質問に参考となるキーワードや論文を答える
    * コードを書くなど直接的なアドバイスはしない
    
## CDLEハッカソン2022の課題について
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884565/862f2ceb-68bf-4862-fb88-42a18dbe999e.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884565/2a953e2d-f182-d17f-b519-8924bd8bb6f5.png)

## HEROZチームについて
* チームの構成
    * 全員で6人構成、ビジネス側とエンジニア側が等分
    * 事前に経歴などを資料として渡され、チームを組むことがメンターの仕事
* 課題についての取り組み方
    * 初日の様子
        * 課題をもらった直後の写真
        ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884565/cefd9566-5a8f-469f-ea02-1aa971f7fd8b.png)
        * どう手を付けてよいか悩んでいる
            * テーマも幅広く解釈できる
            * データ量も膨大で見るだけでも大変
        * 後半はチーム内で自己紹介
        * 最後に現状のアイディアを全チーム発表
            * 具体的なアイディアを出したチームはなし
            * 人流データを深堀すると面白そうという意見が多かった
    * その後の取り組み
        * 週一のペースでMTG
        * 最終日には実際にメンバーが集まって深夜まで作業
## 成果物について
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884565/0c8b5ec6-2fa3-f14f-3b33-e1026c9d26ee.png)
* 概要
    * ユーザーの関心、目的、属性、時間帯に対応した行き先を提案する
    * 人流データには年齢、性別、時間、目的(食事やアウトドアなど)、移動先の緯度経度情報がある。
    * それを利用して目的に合った場所をレコメンドするシステムを構築
    * レコメンドした場所をgoogle mapで表示

## メンターとしての振り返り,感想
* 開発前の仕事
    * 参加者の選択
        * 候補者の保有資格(E,G検定)、や一日にかけられる時間、githubのリポジトリや意気込みなどを読んで選定。
        * 候補者の数が多く、全員が参加させられないのがもったいない。
* 開発期間中のサポート
    * 週一のMTGに参加
        * 参加者の都合で土曜の21:00から
        * ファシリテーターのつもり
    * 最終日に実際に会って作業の追い込み
        * プログラムの作業指示
        * 発表スライド修正
* メンターとしてはどこまで口を出すかはかなり悩む
    * 提出日は形にするために流石に具体的な指示を出した 
    * ほかのチームのメンターの方も匙加減で迷っていた
* 感想 
   * どのチームも結果の出力に力を入れていた。
       * 実験結果をただ張り付けるのではなく、WEB上で動かせたり、アプリ形式にしたりと見た目にもわかりやすくしていた。
   * 作業時間をとれるかが重要
       * HEROZチームではモデル作成の大部分の作業してくれたのは一人の大学生の参加者
       * ほかのチームを見ても毎日数時間かけてた人が多数
フィクションなどから拾う情報処理用語 その20 標的型メール (仮面ライダー)

仮面ライダー 第87話「ゲルショッカー死の配達人!」(脚本：伊上勝、監督：塚田正煕、技斗：岡田勝、(C) 石森プロ、東映)より

時は1972年の晩秋。立花レーシング倶楽部は少年仮面ライダー隊になっていた。隊長は滝和也。会長は立花藤兵衛。で何故か仮面ライダーの言っているセリフも無線で届くようになっていた。原理がよくわからないが、本郷猛が仮面ライダーであることもこの頃はユリ達にも話していたのだろう。で藤兵衛が少年仮面ライダー隊本部でまったりしていると本郷と滝が戻ってきた。藤兵衛がパイプ(実は小林昭二の私物。「ウルトラマン」でもふかしていたが、それも私物なのかもしれない。)をテーブルから取っている間、滝と本郷は同じくテーブルの上にあった手紙に気がついた。見ると

本郷「おやっさんに!」
滝「ゲルショッカーの暗殺リスト第3号は親父さんだったんだ!」
藤兵衛「なに!」

驚いた藤兵衛は立ち上がった。なぜ気づかなかったのは謎だ。

滝「今夜12時…」

すると

藤兵衛「それじゃあ、お寺に予約でもするか。」

だがこのジョークは受けなかった。

滝「親父さん、悪い冗談は言ってる場合じゃありませんよ。」
藤兵衛「そんな深刻な声出すなよ。お前達がついているじゃないか。何も恐れることなんかあるかい。」

滝が興奮したのは理由があった。

滝「しかし、あのクモライオンは油断できやしないぞ。」
藤兵衛「クモライオンだ?」
本郷「ええ。へへ。滝、今度こそクモライオンを叩き潰す絶好のチャンスだ。」
滝「ひとまず親父さんを安全な場所に移さなければ。」
本郷「いや、どこに行っても同じだ。奴の目を誤魔化すのは難しい。ここで待つのが良いだろう。」

藤兵衛は本郷と滝を両腕で抱えた。

藤兵衛「俺の命はお前達に預けるぞ。」

そして夜中の12時が近づいた。

本郷「滝、表の様子を見てくる。」

本郷は出て行った。

そして夜中の12時になった。

藤兵衛「やれやれ。これで寿命が延びたぞ。おい見ろ。誰もこやしないじゃないか。」
滝「全く人騒がせな。しかし、ゲルショッカーが予告を無視することなんてなかったはずですよ。」

実は同じような事件が多発しており、本郷と滝はクモライオンと既に応戦していた。仮面ライダーも手こずる強敵だった。

藤兵衛「通知状は確かに今夜なんだろうなあ。」
滝「ええ。確かに。ああ!」

滝は気がついた。

藤兵衛「どうしたんだ?」
滝「親父さんの名前が消えてる。」

確かに消えている。

藤兵衛「これは一体どういうことだ。」
滝「嫌がらせですよ。」

というのは早かった。別の人の名前が浮き上がったのだ。

藤兵衛「あ、本郷猛。」
滝「しまった。ゲルショッカーの本当の狙いは本郷、いや、仮面ライダーだった。」

そうとも知らず本郷は

本郷「待て!」

ゲルショッカー死の配達人を追いかけていた。
果たして本郷猛、いや、仮面ライダーの運命は如何に。
続きは映像で。
今回は短くまとめられたねえ。それでも長いが。ま、ここまで長いと誰も読まないでしょ。
[NewRelic] QueryBuilderでNRQLを実行したら結果が10行しか出力されないのだが。。

# この記事について

NRQLクエリをQueryBuilderから実行したところ、本来なら数十行は出力されるはずなのに10行しか結果が出力されませんでした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435280/6c8e6c30-4f05-49e4-f2c8-2d6859452bed.png)

NRQLクエリにパラメータを追加したところ、全て出力されるようになりました。
そのことについてこの記事に残します。

# LIMITを指定しよう

LIMITとは"FACET"クエリもしくは"SELECT * "クエリで返されるアイテムの最大数を指定するパラメータです。
https://docs.newrelic.com/jp/docs/query-your-data/nrql-new-relic-query-language/get-started/nrql-syntax-clauses-functions/#sel-limit

> リミットのデフォルト設定は、FACETクエリの場合は10、SELECT *クエリの場合は100となります。

LIMITにはデフォルト値があり、FACETクエリの場合は10です。

つまりFACETクエリにおいて、LIMITを指定しないと結果が10アイテムしか取得できません。(10行しか出力されません)
もし11個以上項目がある場合、グラフに表示されない項目が出てきてしまいます。

LIMITをMAXに指定することで解決します。
(ただしLIMITの最大値が2000なので、2000行以上は出力できません)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435280/167cf455-367d-3994-dbe8-33fc400b9b76.png)
Raspiberry Pi picoとCircuitPythonでGamepadを作る

![クリップボード1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29493/6288873f-98eb-0821-9c5d-c3d232789d62.png)
Picoを二つ買ったものの使ってなかったというのもあり、このページを見て面白そうだからやってみた。
https://qiita.com/airpocket/items/24e67922e0c0f1624ab8

CircuitPythonを入れる方法はググればいくつか出るのでそちらを参考に。
私はこの辺りを見た。
https://www.kuripapa.com/wp/raspberry-pi-pico-circuitpython/853/
Thonnyあたり使ってもいいのだけれどGUIがダサいので。コンソールはmacでscreenを使った。

Adafruit CurcuitPython HID を使う
https://github.com/adafruit/Adafruit_CircuitPython_HID
ドキュメントはこちら。
https://docs.circuitpython.org/projects/hid/en/latest/index.html

code.py
上記GitHubのsampleを使用。examples/hid_simple_gamepad.pyを流用し、PinはD4とかそのままではエラーになるので、Picoのboard.GP2~5、analogはboard.GP26などに変更。他は特に変更なし。

boot.py
以下ページの中程にあるGamepadのサンプルを使用。
https://learn.adafruit.com/customizing-usb-devices-in-circuitpython/hid-devices#custom-hid-devices-3096614-9

ビルドして、Picoに焼き、USBケーブルでPCにつなぐとWindowsではこのように認識された。
![クリップボード1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29493/d2603cf2-2b39-0cd0-c99c-7f0c4f584dec.png)

試しにPinを繋いでみて反応するかをチェック。
きちんと軸とボタンが認識されている。
![クリップボード2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29493/b5a748ef-02d8-ad5b-2d9b-3b55dd8a268d.png)
GP2を短絡させるとボタン1が反応
![クリップボード3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29493/e55c24c0-151c-4e22-df33-6dcefa0c1f50.png)
GP26を短絡させるとX軸が動いた
![クリップボード4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29493/25c5ea75-f166-f7e1-49cc-64fe5099d457.png)

ソフト的にはできた。あとはハードを用意してつなぐだけ。
ジャンク品のジョイスティックやゲームパッドを買ってきてつなぐもよし、筐体から自分で作るもよし。
Python を使用して、ユーザーが検索した単語を登録する辞書システムの例


自己学習のメモです。

まず、scikit-learn ライブラリをインストールする。
```
pip install scikit-learn
```

下記の様なシンプルな辞書を作成。

```
from sklearn.tree import DecisionTreeClassifier
from sklearn.feature_extraction.text import CountVectorizer
from collections import Counter

class Dictionary:
    def __init__(self):
        self.vectorizer = CountVectorizer()
        self.classifier = DecisionTreeClassifier()
        self.words = []
        self.counts = Counter()

    def add_word(self, word):
        self.words.append(word)
        self.counts[word] += 1
        X = self.vectorizer.fit_transform(self.words)
        y = self.vectorizer.get_feature_names()
        self.classifier.fit(X, y)

    def predict(self, word):
        return self.classifier.predict(self.vectorizer.transform([word]))
```
scikit-learnのDecisionTreeClassifierを使用して検索された単語を分類するDictionaryクラスを定義。  
add_word メソッドは、辞書に新しい単語を追加するために使用。
predict メソッドは、指定された単語の予測するために使用。
このメソッドは単語を入力として受け取り、それをCountVectorizerを使用して変換してから、それをDecisionTreeClassifierに渡し、予測された単語を取得する。

Dictionary クラスの使用例は下記の通り。
```
dictionary = Dictionary()

dictionary.add_word("apple")
dictionary.add_word("banana")
dictionary.add_word("cherry")

print(dictionary.predict("apple"))
# Output: ['apple']

print(dictionary.predict("berry"))
# Output: ['cherry']

```
フィクションなどから拾う情報処理用語 その19 なりすまし (必殺仕掛人)

必殺仕掛人 第10話 「命売りますもらいます」(脚本：國弘威雄、監督：松野宏軌 (C) 松竹)より

伊助は兄巳之吉の仕掛け(要するに殺害)を音羽屋半右衛門に依頼した。
音羽屋半右衛門から依頼があり西村左内と藤枝梅安が仕事に取り掛かる事になった。
この頃、命講(要するに生命保険)が流行っていたが、岬の千蔵や櫓の万吉の調査では命講(要するに生命保険)絡みではなさそうということが判明していた。
なお今回音羽屋半右衛門は一切登場しない。
演じる山村聰が京都へ来られなかったのだろう。

紆余曲折の末、巳之吉は藤枝梅安の針を受け、西村左内に斬られたが

伊助「ありがてえ。これで。」

驚く二人。なんと巳之吉は伊助だったのだ!
虫の息の伊助が話す。

伊助「お許しくださいませ。私にはこうする以外に。」

呆気に取られる左内と梅安。

伊助「おりん(妻)や吉太郎(息子)を助ける道は…」
梅安「伊助…」

伊助は懐から証文と書状を出した。

伊助「こ、これを、お願いします。」

梅安は厳しい顔。左内は呆然としながらも伊助から証文などを受け取った。

伊助「許してください。どうか、どうか、お許しを。」
西村左内「伊助、おい。おい。伊助。」

伊助は死んでしまった。左内と梅安は呆然と見るしかできなかった。

後日。滝の近くでボーっと寝ている西村左内の脇に伊助が残した遺書が置かれていた。

伊助の声「よんどころなくとは申しながら皆々様を欺くような仕儀となり申し訳なく存じ候。家内おりんの治療の金につまり、度重なる兄の金の無心に商いさえ行き詰まり、人に誘われ、米相場への手出しが大きく狂って200両もの借財。これもこの月末に返さねば手が後ろへ回る仕儀となり私の命と引き換えるより他になく万策尽きてのことでございます。折しも突然一月前に、風邪をこじらせて死にました兄を生きているように見せかけ、兄ともども昔かけ小屋の軽業師や芝居小屋の芸人、その時、習い覚えた含み綿で声を変え、私が兄になりすまし、音羽屋様にお願いしたが如く私が斬られ、私の命講の残金にて。」

要するに生命保険金殺人事件の片棒を仕掛人は担がされたのである。借金返済と仕掛料は自分に掛けられた生命保険の保険金で賄うのだ。そこへ藤枝梅安がやってきた。

藤枝梅安「伊助の命講500両は後藤屋清左衛門が払いましたよ。奉行所と後藤屋でだいぶうるさく調べ回っていたらしいが、へ、結局は何にもわからずじまいさあ。あ、それから女房は子供と一緒に引き取られて田舎に帰りました。伊助の残した大金でゆっくり養生できるし、これからの暮らしの心配もさらさらない。伊助はもし命講の金が入らなきゃ米相場の借金で訴えられ、女房、子供と一緒に死罪か遠島になるところだった。どうしても女房と子供を助けたかったんでしょうねえ。」

左内は起き上がって何か言おうとしたが梅安が押し留めた。

藤枝梅安「いやいや、何にも言いっこなしだ。あたし達仕掛人は頼まれた通りの仕事をする。狙った獲物を確実にね。それでいいんですよ。」

現実主義者らしい藤枝梅安の言葉である。

それを聞いても虚無感が残る左内。左内は本来は生真面目なのである。左内にも妻と息子がいるし浪人だったので仕掛人になる前は貧乏だった。伊助に共感したのかもしれない。

西村左内「しかし、梅安殿。俺達仕掛人は、因果な…はあ、無情な世の中だね。」

すると梅安は左内の真似して笹笛を吹こうとしたが、ちっとも鳴らない。3回やった後、笹の葉を放り投げてしまった。ここでふざけるのが梅安らしいところである。それを呆然とみる左内であった。
PowerVS IBM i 導入後のおすすめシステム値（ほか）設定変更

PowerVSにIBM i インスタンスを作成した際のデフォルト値は古くはAS/400時代から継承したデフォルト値が設定されていたり、最新のセキュリティ事情を鑑みて実際運用ではちょっと厳しめの設定になっていたりします。
例えばシステム値 QCTLSBSDはAS/400時代から一貫して変わらないQBASEですが大多数の環境はQCLTを使用しているはずです。QMAXSGNACN=3,QMAXSIGN=3でコンソールからQSECOFRで3回パスワード失敗するとコンソールもQSECOFRも使用不可*DISABLEDになってしまいます。実運用では可能かもしれませんが、特に初期構築時などはもうちょっと緩くしておきたいことも多いと思います。

運用の容易性やオンプレなど既存環境との共通化などを念頭に以下、個人的おススメ設定変更値をご紹介します。

    1.システム値 WRKSYSVAL/CHGSYSVALで変更
        QLMTDEVSSN  1->0　：1つのユーザーIDで複数のセッションにログインを許可（1は1ID/1セッションしかログインできない）
        QLMTSECOFR  1->0　：すべての端末で*SECOFRアクセスをデフォルト許可（1は*SECOFRクラスのユーザーIDのアクセス権を個々の*DEVDに追加しないとログインできない）
        QMAXSGNACN  3->2 (QMAXSIGN回数だけログイン失敗するとそのユーザーIDを*DISABLEDする 3はIDと*DEVDを*DISABLED)
        QMAXSIGN    3->25 or *NOMAX（ログイン再試行回数を増やす)
        QAUTOVRT    0 → *NOMAX or 十分大きい値(5250丹間の*DEVDを自動作成する個数を指定。0だとACS等からTELNET接続してもDEVD作らないので手動作成が必要)
        QCTLSBSD    QSYS/QBASE → QSYS/QCTL（制御サブシステムをQCTLに変更）
        QASTLVL     *BASIC → *INTERMED（ログイン後の5250ヘルプ画面のレベルを中間に。これが使いよいと思います）
        QALWOBJRST  デフォルト値　→ *ALL（追加のライセンスプログラムやユーザーオブジェクト復元時エラーが出る場合は変更します）
        QIMZON -> QP0900JST （タイムゾーンをJSTに変更、これは環境に応じて、必要ならば）

上記のうちQCTLSBSDの設定変更はIPLが必要です。その他は即時変更です。

    2.個人用のユーザーID *USRPRFをCRTUSRPRFで作成する　QSECOFRなどは温存し個人のIDで作業を推奨。権限もできる限り最小限に設定します

以上です。
また、PowerVSにIBM i 導入した直後の注意点・TIPSも以下に共有しますと、

    A. IBM i OS導入完了を表す INZSYSが開始された/INZSYSが完了したというメッセージをDSPMSG QSYSOPRかDSPLOGで必ず確認すること
    B. IBM CloudのIPアドレスを付与する作業は導入完了後15分以上遅くなる場合も観測されました。
      この間IBM iのIPは127.0.0.1しかありませんがじきに指定したIPが付与されます
    　どのようなロジック化わかってないのですがこの間シャットダウン等せずIPが割り当てられるまでしばらく放置しておくのがいいと思います
    C.OS導入中の注意点になりますがライセンスプログラムの使用許諾を必ずACCEPTすること（英語表示なので読み飛ばし注意）
FreeBSDのmrubyでらじる★らじる

fifoではなくパイプで処理できるようにしました。

mrubyのスクリプトはこれです。

```ruby:rajiru.rb
#!/usr/local/bin/mruby

if ARGV.size == 2
  case ARGV[0]
  when "fm" then
    stcode = "2023507/nhkradiruakfm"
  when "r1" then
    stcode = "2023229/nhkradiruakr1"
  when "r2" then
    stcode = "2023501/nhkradiruakr2"
  else
    stcode = "2023229/nhkradiruakr1"
  end
  
  url = "http://radio-stream.nhk.jp/hls/live/" + stcode + "/master48k.m3u8"
  
  #p url
  
  h = HttpRequest.new()
  
  ar = Array.new
  
  ri = url.rindex("/")
  base = url[0, ri]
  
  if ARGV[1] == "-"
    file = STDOUT
  else
    file = File.new(ARGV[1], 'w')
  end
  
  index = h.get(url)
  
  index.body.each_line {|line|
    if line[0] != "#"
      l = line.chomp
      ar << l
    end
  }
  
  i = 0
  while 1 do
    a = h.get(base + "/" + ar[i])
    t1 = a.body[9,1].ord
    t2 = a.body[t1+10+9,1].ord
    off = t1 + 10 + t2 + 10
    len = a.body.size - off
  #  p ar[i]
    file.write(a.body[off, len])
    i = i + 1
    if ar.size - 2 == i
      # update list
      index = h.get(url)
  
      index.body.each_line {|line|
        if line[0] != "#"
          l = line.chomp
          if !ar.include?(l)
            ar << l
          end
        end
      }
      ar.shift(i)
      i = 0
    end
  end
  
  # not reach here
  
  file.close
  
else
  p "usage: rajiru.rb {station] [file]"
end
```

mrubyはmruby-httprequestを入れてビルドします。

ロジックはリストを拾い中のtsを拾っては書き込んでを繰り返し、最後の2つ前でリストを更新して、リストの処理部分を消して、リストの最初から始めるような流れです。

tsのタグの処理はまったく汎用性がないので、他のストリームでは動かないと思われますし、将来動かなくなる可能性もあります。

再生は[ahplay](https://qiita.com/yamori813/items/c65a4f560362f36a62dd)を使います。

```
# ./rajiru.rb fm - | ahplay -
```

httpsだとネットアクセスが重くて途切れ途切れになりました。httpでもときどきノイズが入ります。

FreeBSD/mipsのRT3883にUSB DAC(PCM2704)をつないで試しました。

以前はsoxを使っていたので、8M Flashでもあふれていたのですが、ahplayで再生するようにして8Mで収まるようになりました。

dev.pcm.0.bitperfect=1だと正常に動作しません。
【SwiftUI】ScrollView内にViewが追加されるとき、最下部まで自動スクロールする

## 問題
ForEachを持つScrollView内で、Viewが追加されるたびに、最下部へ自動スクロールしてほしいと思いました。この記事はその備忘録として残します。

## 解決策
```swift
ScrollViewReader { proxy in
    ScrollView {
        ForEach(array, id: \.self) {string in
            Text(string)
        }
        Color.clear.id(array.count)
    }
    .onChange(of: array) { _ in
        withAnimation {
            proxy.scrollTo(array.count)
        }
    }
}
```
`ScrollViewReader`内でScrollViewを宣言し、arrayの変化に応じて`Color.clear`までスクロールさせます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/655077/5201f790-d11c-a1d9-6dd3-6d955db17f6d.gif" width="200">
動作イメージ

## 開発環境
- Xcode 14.2
- iOS 16 and later

## 参考URL
- [SwiftUI automatically scroll to bottom in ScrollView (Bottom first)](https://stackoverflow.com/questions/58376681/swiftui-automatically-scroll-to-bottom-in-scrollview-bottom-first)
- [【SwiftUI】ScrollViewReaderでScrollの移動制御](https://zenn.dev/oka_yuuji/articles/6cd8d1469d6bb0)
Unity 指定した座標を行き来する敵の作り方　Vector3.Lerp

![Timeline_1_AdobeExpress.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315874/c3a5df10-ac2e-9231-3dba-196d58a300a0.gif)


NavMeshAgent を使わずに、指定した座標をうろうろする敵のスクリプトを書きたい方はこちらが参考になるかもしれません。

これは、インスペクターで指定した配列の座標に移動してくれるスクリプトです。Vector3.Lerpを使って実装しました。詳しい説明については、コメントに記載してあるので参考にしてみてください。

```c#:EnemyMove.cs
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class EnemyMove : MonoBehaviour
    {
        [SerializeField]
        Vector3[] positions = new Vector3[4]; // 配列の要素数
    
        [SerializeField]
        float moveTime = 1.0f; // 移動にかかる時間を秒で設定
        float timer = 0.0f; // タイマーを初期化
        int index = 0; // 配列のインデックスを初期化
    
        [SerializeField]
        bool LoopSwitch = false;
    
        // Start is called before the first frame update
        void Start()
        {
            transform.position = positions[0]; // オブジェクトの位置を配列の最初の要素に設定
        }
    
        // Update is called once per frame
        void Update()
        {
            if (index < positions.Length - 1) // 配列の最後の要素に到達するまで
            {
                timer += Time.deltaTime; // タイマーを更新
                float t = timer / moveTime; // 移動の割合を計算
                transform.position = Vector3.Lerp(positions[index], positions[index + 1], t); // オブジェクトの位置を補間
                if (t >= 1.0f) // 移動が完了したら
                {
                    index++; // 配列のインデックスを増やす
                    timer = 0.0f; // タイマーをリセット
                }
            }
    
            if (index == positions.Length - 1) // 配列の要素が最後に達成した場合
            {
                if (LoopSwitch == true) // ループスイッチがオンの場合
                {
                    index = 0; // indexを0にしてループにする
                }
            }
        }
    }

```

インスペクターはこのように、指定します。Positionsに、動かしたい位置を入力してMoveTimeに移動時間、LoopSwitchで、ループするか選択することができます。
![スクリーンショット 2023-02-16 111646.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315874/5a832ff4-c4be-77ec-2aec-9d7125b5f383.png)
neosでlogix その116

# 概要
neosでlogixやってみる。
練習問題、やってみた。

# 練習問題
手順書をインポートせよ。

# 手順書
ファイルブラウザーでsample.txtをダブルクリック

# 実行結果

![2023-02-16 02.05.07.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/7d2acd1c-760e-0d86-35fc-963645613e2f.jpeg)


以上。
neosでlogix その115

# 概要
neosでlogixやってみる。
練習問題、やってみた。

# 練習問題
fbxファイルをインポートせよ。

# 手順書

- ファイルブラウザーでsample.fbxをダブルクリック
- escキーを押す。
- CADモデルをクリック
- cmをクリック
- インポート実行をクリック



# 実行結果

![2023-02-16 01.54.55.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/135dd08b-41d6-6184-7d10-ef3e42ba9cbb.jpeg)


以上。
[MacOS] 使えたコマンドまとめ

## はじめに
Macのコマンドの使い方をかんたんに分かりやすくまとめています。
勉強して試したもを、書き足していくつもりですので、温かい目で見てくださると幸いです。

## ディレクトリ作成
空のディレクトリを作成することができます。
```
mkdir -v ディレクトリ名
```


## ディレクトリまるまる削除
ディレクトリの中に入っているファイルも全て消すことができます
```
rm -rf ディレクトリ名
```
【Laravel】migrationでMySQLの外部キー制約を削除するときはインデックスも削除しよう

外部キー制約を設定したカラムがあり、
そのカラムの外部キー制約の削除をしたく下記のmigrationファイルを作成・実行した。

```php
<?php

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

return new class extends Migration
{
	/**
	 * Run the migrations.
	 *
	 * @return void
	 */
	public function up()
	{
		Schema::table('tests', function (Blueprint $table) {
			$table->dropForeign(['xxx_id']);
		});
	}

	/**
	 * Reverse the migrations.
	 *
	 * @return void
	 */
	public function down()
	{
		Schema::table('tests', function (Blueprint $table) {
			$table->foreignId('xxx_id')->constrained();
		});
	}
};
```

phpMyAdminで確認してみると、
外部キーの制約は削除されていたが、
インデックスの欄にキー名、カラムの横の鍵マークが残ったままになってしまっていて気持ち悪い:sob:
![スクリーンショット 2023-02-16 10.06.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/664075/ea93272d-ce7b-c99e-83c5-c85d069cb928.png)
![スクリーンショット 2023-02-16 10.09.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/664075/f64915c9-5576-e4bc-201c-0e2b89666641.png)


# まとめ
### キー名を指定してインデックスも一緒に削除するとよい！
```php
<?php

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

return new class extends Migration
{
	/**
	 * Run the migrations.
	 *
	 * @return void
	 */
	public function up()
	{
		Schema::table('tests', function (Blueprint $table) {
			$table->dropForeign(['xxx_id']);
			$table->dropIndex('tests_xxx_id_foreign'); // これを追加！
		});
	}

	/**
	 * Reverse the migrations.
	 *
	 * @return void
	 */
	public function down()
	{
		Schema::table('tests', function (Blueprint $table) {
			$table->foreignId('xxx_id')->constrained();
		});
	}
};
```

下記のようにカラム名を指定すると、`'tests_xxx_id_index'`という名前のインデックスを削除するSQLが作成されてエラーになってしまうので注意:no_good:
```php
$table->dropIndex(['xxx_id']);
```
paiza.ioでperl その4

# 概要
paiza.ioでperlやってみた。
湯婆婆やってみた。

# サンプルコード

```

use Encode;

my $name;
do {
    print "契約書\n";
    print "甲は油屋当主として、乙を油屋に雇用することを契約し、\n";
    print "労働に伴う対価の支払いを右の通り、約定する。\n";
    print "なお、一日の労働の対価は金百円とする。\n";
    print "甲　油屋当主　湯婆婆\n";
    print "\n";
    print "乙\n";
    print "契約書だよ。そこに名前を書きな。\n";
    $name = <STDIN>;
    chomp($name) if defined($name);
} while !defined($name) || $name eq "";
print "フーン。$nameというのかい。贅沢な名だね。\n";
my $newName = encode('utf-8', substr(decode('utf-8', $name), rand(length(decode('utf-8', $name))), 1));
print "今からお前の名は$newNameだ。いいかい、$newNameだよ。分かったら返事をするんだ、$newName!!\n";



```

# 実行結果

```
契約書
甲は油屋当主として、乙を油屋に雇用することを契約し、
労働に伴う対価の支払いを右の通り、約定する。
なお、一日の労働の対価は金百円とする。
甲　油屋当主　湯婆婆

乙
契約書だよ。そこに名前を書きな。
フーン。有働由美子というのかい。贅沢な名だね。
今からお前の名は由だ。いいかい、由だよ。分かったら返事をするんだ、由!!
```

# 成果物

https://paiza.io/projects/WOVfag8M5msqZhjdgnob1A

以上。
連想配列のソート(PHP)

**連想配列**のソートに関するサンプルプログラムを実装しました

```PHP
   $colors = ["red" => "赤","blue" => "青","yellow" => "黄"];

   // 要素をキーで昇順に並び替える
   ksort($colors);

   foreach($colors as $key => $value){
    echo "<p class='test1'> {$key}は日本語で{$value}です";
    echo "<br>";
   }

   // 要素をキーで降順に並び替える
   krsort($colors);

   foreach($colors as $key => $value){
    echo "<p class='test2'> {$key}は日本語で{$value}です";
    echo "<br>";
   }
```

Keyを昇順に並べるには***ksort***関数、降順に並べる場合は***krsort***関数を使います。
paiza.ioでperl その3

# 概要
paiza.ioでperlやってみた。
九九やってみた。

# サンプルコード

```

for($i = 1; $i <= 9; $i++)
{
    for($j = 1; $j <= 9; $j++)
    {
        printf "%d × %d = %d\t" , $j , $i , ($j * $i);
    }
    print "\n";
}

```

# 実行結果

```
1 × 1 = 1	2 × 1 = 2	3 × 1 = 3	4 × 1 = 4	5 × 1 = 5	6 × 1 = 6	7 × 1 = 7	8 × 1 = 8	9 × 1 = 9	
1 × 2 = 2	2 × 2 = 4	3 × 2 = 6	4 × 2 = 8	5 × 2 = 10	6 × 2 = 12	7 × 2 = 14	8 × 2 = 16	9 × 2 = 18	
1 × 3 = 3	2 × 3 = 6	3 × 3 = 9	4 × 3 = 12	5 × 3 = 15	6 × 3 = 18	7 × 3 = 21	8 × 3 = 24	9 × 3 = 27	
1 × 4 = 4	2 × 4 = 8	3 × 4 = 12	4 × 4 = 16	5 × 4 = 20	6 × 4 = 24	7 × 4 = 28	8 × 4 = 32	9 × 4 = 36	
1 × 5 = 5	2 × 5 = 10	3 × 5 = 15	4 × 5 = 20	5 × 5 = 25	6 × 5 = 30	7 × 5 = 35	8 × 5 = 40	9 × 5 = 45	
1 × 6 = 6	2 × 6 = 12	3 × 6 = 18	4 × 6 = 24	5 × 6 = 30	6 × 6 = 36	7 × 6 = 42	8 × 6 = 48	9 × 6 = 54	
1 × 7 = 7	2 × 7 = 14	3 × 7 = 21	4 × 7 = 28	5 × 7 = 35	6 × 7 = 42	7 × 7 = 49	8 × 7 = 56	9 × 7 = 63	
1 × 8 = 8	2 × 8 = 16	3 × 8 = 24	4 × 8 = 32	5 × 8 = 40	6 × 8 = 48	7 × 8 = 56	8 × 8 = 64	9 × 8 = 72	
1 × 9 = 9	2 × 9 = 18	3 × 9 = 27	4 × 9 = 36	5 × 9 = 45	6 × 9 = 54	7 × 9 = 63	8 × 9 = 72	9 × 9 = 81	


```

# 成果物

https://paiza.io/projects/hf2zKVXyAJ7iFgrGZnZGBQ


以上。
paiza.ioでperl その2

# 概要
paiza.ioでperlやってみた。
zundokoやってみた。

# サンプルコード

```

sub zundoko {
    my @zundoko = qw/ズン ドコ/;
    my $rand = int rand(2);
    return $zundoko[$rand];
}
my $i = 0;
while (1) 
{
    my $r = zundoko();
    print $r." ";
    if ($r eq 'ドコ') 
    {
        if ($i == 4) 
        {
            last;
        }
        $i = 0;
    }
    else
    {
        $i++;
    }
}
print "キ・ヨ・シ！\n";



```

# 実行結果

```
ズン ドコ ズン ドコ ズン ドコ ズン ドコ ドコ ドコ ドコ ドコ ズン ドコ ドコ ズン ドコ ドコ ドコ ドコ ズン ドコ ドコ ドコ ドコ ズン ドコ ズン ズン ズン ズン ズン ドコ ズン ズン ズン ズン ドコ キ・ヨ・シ！
```

# 成果物

https://paiza.io/projects/aea7GRDGV7jZUOWaoPgfnQ


以上。
Ruby if, else問題

# if, elseを使ってプログラムを作成します

条件は以下の通りです。
- 条件1:メソッドの実引数として「1以上の正の整数」を3つ用意し、それぞれを仮引数a,b,c としてnumメソッド内で使用する
- 条件2:第一引数と第二引数は足し算をし、変数abに代入する
- 条件3:第三引数が3以下の場合は変数abを第三引数の値で割り、結果を出力する
- 条件4:第三引数が4以上の場合は変数abを第三引数の値で掛け、結果を出力する
※小数点以下の出力は考慮しなくてかまいません。<br><br>

模範解答
```ruby
def num(a, b, c)
  ab = a + b
  if c <= 3
    puts ab / c
  else
    puts ab * c
  end
end

# 呼び出し例
num(1,5,3)
```

```:ターミナル
2
# ab = 1 + 5 = 6
# 6 / 3 = 2
```

## 解説
条件2に、第一引数aと第二引数bを足したものを変数abに代入するとあるので、その式を2行目に記述します。
if文には第三引数cが３以下のときの条件式を記述し、変数abを第三引数の値で割るように処理をします。
そして、それ以外（第三引数が4以上の場合）であるelseの処理には、変数abを第三引数の値で掛けて結果を出力するよう記述しました。
GaugeとWiremockを使ったテストをするとwiremock expected exactly 1 requests matching the following pattern but received とエラーが出る

# はじめに

Wiremockを使ってテストを作成したところ実行する回数によってエラーが出てしまう挙動があったのでまとめます
割とハマってしまう人が多い気もしました

# 問題

以下のテストを実行しました

```spec:example.spec
## ユーザーを取得できる
* URL"/user/1"にGETリクエストを送る

## ユーザーを取得できる
* API"mockApi"のURL"/user/1"にGETリクエストされた
```

このテストをWiremockのサーバーを立てて行うと1回目は成功するのですが、2回目以降から以下のエラーがでます

```
wiremock expected exactly 1 requests matching the following pattern but received 2
```

received Xは実行するごとに数字が増えていきました

# 解決方法

これはWiremockが受けたレスポンスを内部でカウントしてしまうことによるエラーでした

テストの実行前(各Stepごと)にWiremockを初期化する必要があります

ですので以下のファイルを作成しました

```kotlin:Setup.kt
import com.thoughtworks.gauge.Step
import com.github.tomakehurst.wiremock.client.WireMock
import com.thoughtworks.gauge.BeforeSpec

class Setup {
    @BeforeSpec
    fun prepareWireMock() {
        WireMock.reset()
    }
}
```

`@BeforeSpec`で初期化を行うようにしたところテストが通りました

# おわりに

チームの方に聞いたところ速攻で解決しました
ネットで調べていてまったくわからなかったので、適宜聞くことは必要だなと思いました
paiza.ioでperl

# 概要
paiza.ioでperlやってみた。
fizzbuzzやってみた。

# サンプルコード

```

$i = 1;
while ($i < 101) 
{
    if ($i % 15 == 0 ) 
    {
        print "fizzbuzz ";
    }
    elsif($i % 5 == 0) 
    {
        print "buzz ";
    }
    elsif($i % 3 == 0) 
    {
        print "fizz ";
    }
    else 
    {
        print "$i ";
    }
    $i = $i + 1;
}
print "\n";
foreach $i (1..100) 
{
  if ($i % 15 == 0) 
  {
    print "FizzBuzz ";
  } 
  elsif($i % 3 == 0) 
  {
    print "Fizz ";
  } 
  elsif($i % 5 == 0) 
  {
    print "Buzz ";
  } 
  else 
  {
    print "$i ";
  }
}



```

# 実行結果

```
1 2 fizz 4 buzz fizz 7 8 fizz buzz 11 fizz 13 14 fizzbuzz 16 17 fizz 19 buzz fizz 22 23 fizz buzz 26 fizz 28 29 fizzbuzz 31 32 fizz 34 buzz fizz 37 38 fizz buzz 41 fizz 43 44 fizzbuzz 46 47 fizz 49 buzz fizz 52 53 fizz buzz 56 fizz 58 59 fizzbuzz 61 62 fizz 64 buzz fizz 67 68 fizz buzz 71 fizz 73 74 fizzbuzz 76 77 fizz 79 buzz fizz 82 83 fizz buzz 86 fizz 88 89 fizzbuzz 91 92 fizz 94 buzz fizz 97 98 fizz buzz 
1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz 11 Fizz 13 14 FizzBuzz 16 17 Fizz 19 Buzz Fizz 22 23 Fizz Buzz 26 Fizz 28 29 FizzBuzz 31 32 Fizz 34 Buzz Fizz 37 38 Fizz Buzz 41 Fizz 43 44 FizzBuzz 46 47 Fizz 49 Buzz Fizz 52 53 Fizz Buzz 56 Fizz 58 59 FizzBuzz 61 62 Fizz 64 Buzz Fizz 67 68 Fizz Buzz 71 Fizz 73 74 FizzBuzz 76 77 Fizz 79 Buzz Fizz 82 83 Fizz Buzz 86 Fizz 88 89 FizzBuzz 91 92 Fizz 94 Buzz Fizz 97 98 Fizz Buzz 
```

# 成果物

https://paiza.io/projects/ALumDXOgqKpBdgo4TI9T5Q

以上。
Docker build 中に npm install で EAI_AGAIN 発生の解決策

WSL2 上で `docker build` したときに、`npm install` が `EAI_AGAIN` で失敗することがある。

```log
Sending build context to Docker daemon  16.38kB
Step 1/7 : FROM node:18.9.0-alpine3.15
 ---> ec9347a9b50f
Step 2/7 : WORKDIR /app
 ---> Using cache
 ---> 4f9b5895a691
Step 3/7 : COPY package.json ./
 ---> 2976c381a263
Step 4/7 : RUN npm i -g npm@9.1.1 &&     npm i
 ---> Running in be3cca06d4f5
npm ERR! code EAI_AGAIN
npm ERR! syscall getaddrinfo
npm ERR! errno EAI_AGAIN
npm ERR! request to https://registry.npmjs.org/npm failed, reason: getaddrinfo EAI_AGAIN registry.npmjs.org

npm ERR! A complete log of this run can be found in:
npm ERR!     /root/.npm/_logs/2023-02-16T00_38_46_463Z-debug-0.log
The command '/bin/sh -c npm i -g npm@9.1.1 &&     npm i' returned a non-zero code: 1
```

きっかけはよくわからないが、Windows アップデートで PC 再起動された翌日から発生するようになった。
Windows アップデートそのものは関係ないが、おそらくWSL再起動、Docker デーモン再起動が行われたことに起因しているものと考えられる。

# 原因と解決策

なにやら Docker が DNS 解決できないゆえに発生しているらしい。そのため、docker build 時に `--network==` オプションを付けることで回避できた。

利用可能なネットワーク確認
```bash
docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
ea8f55babc5d   bridge    bridge    local
6dbe0f879255   host      host      local
4b0be39c3e3a   none      null      local
```

networkオプションを指定してビルド

``` bash
docker build --network=host . --tag app:v1
```

## 参考

https://stackoverflow.com/questions/44215856/docker-cant-install-npm-packages

https://docs.docker.com/engine/reference/commandline/build/
GoogleFormの名前リストを自動生成し、回答済みの名前を除外する

# やること
- GoogleForm の項目に回答者の名前をプルダウンで選択してもらう枠を置く
- その選択可能なリストはスプレッドシートのリストから取得する
- 回答済みの名前はリストから除外する

# 経緯
最近学校現場で働くようになりました。
生徒へのアンケートを作ることがよくあるんですが、毎回生徒の名前を入力するのは大変なのでスプレッドシートの名簿から自動で生成するようにしました。
また、回答が済んだ生徒は除外することで重複する選択をなるべく防ぐことを目的としました。

# 注意
当初、トリガーを「フォームから - 起動時」で考えていましたが、この設定だと**GoogleFormの編集画面を開くと起動する**ため、不適切でした。
トリガーの設定は **「フォームから - 送信時」** に設定すると、誰かが回答するたびにリストの更新がされます。

# 用意するもの
- GoogleForm
    - これに紐づくGAS
    - フォームの回答リストのSpreadsheet ※
- 名前リストが載ったSpreadsheet

※ 回答リストはGoogleFormで回答すると自動で生成されるので、予めフォームに適当に回答してください。

# 流れ
1. 名前リストのシートを取得
2. 回答リストのシートを取得
3. セル範囲を指定して名前リストを取得（※1）
4. 回答リストから回答済み名前リストを取得（※1）
5. filter関数で未回答名前リストを抽出
6. フォームを取得し、リスト形式の質問を取得
7. リスト形式の質問から、指定の名前の項目かチェック
8. プルダウンの選択肢に未回答リストをセットする
9. GASのトリガーに「フォームから-起動時」でスクリプトを登録する

:::note info
※1
名前リストは縦列で記入されることが多いと思います。
その場合、取得するデータは2次元のデータとなるのでループを回すのがやりづらいため、flat()関数で1次元配列にしています。
:::

# 実装
```js:GASスクリプト
function setNameList() {

  const SS_ID = `AAAAA`; // 名前リストのスプレッドシート
  const RES_SS_ID = `BBBBB`; // Formが自動生成する回答のスプレッドシート

  // シート名
  const S_NAME = `名前リスト`; // 名前リストが載ったシート名
  const RES_S_NAME = `フォームの回答 1`; // 回答リストが載ったシート名

  // 対象となるGoogleフォームの質問項目名
  const QUESTION_NAME = "名前";

  // 1 & 2.名前リストのシートを取得
  const spreadsheet = SpreadsheetApp.openById(SS_ID);
  const sheet = spreadsheet.getSheetByName(S_NAME);

  // 3. 配列で設定されているデータを取得
  // シートから縦列のリストを取得すると2次元の配列になるので、flat()で1次元化
  const allNameList = sheet.getRange(2, 1, sheet.getLastRow() - 1).getValues().flat();

  // 4. 回答済みの名前リストを取得
  const resSS = SpreadsheetApp.openById(RES_SS_ID);
  const resSheet = resSS.getSheetByName(RES_S_NAME);
  const inputNameList = resSheet.getRange(2, 2, resSheet.getLastRow() - 1).getValues().flat();

  // 5. filter関数で未回答名前リストを抽出
  let uninputNameList = [];
  let tmpList = allNameList.filter((data) => {
    return !inputNameList.includes(data)
  });
  tmpList.forEach(data => uninputNameList.push([data]));

  // 6.フォームを取得し、リスト形式の質問を取得
  const form = FormApp.getActiveForm();
  var listItems = form.getItems(FormApp.ItemType.LIST);

  //　7. リスト形式の質問から、指定の名前の項目かチェック
  listItems.forEach(function(item) {
    if(item.getTitle() == QUESTION_NAME) {
      // 8. プルダウンの選択肢に未回答リストをセットする
      item.asListItem().setChoiceValues(uninputNameList);
    }
  });
}
````
複数のLinuxサーバに対してコマンドを実行するための方法　PSSH

# はじめに
本記事は複数のLinuxサーバに対してコマンドを実行するための方法について記載しています。

今の時代はクラウドインフラ上でコンテナを動かしているシステムが多いと思いますが、オンプレミス・クラウドに関わらずサーバにSSH接続して作業するケースはあるのではないでしょうか。

2023年2月7日に[OpenSSLに複数の脆弱性](https://jvn.jp/vu/JVNVU91213144/)が公表されました。
脆弱性対応を行うにあたり、様々な環境のサーバを確認する場合は、複数のサーバでコマンドを実行するなど迅速なオペレーションが求めれます。

以下のようなツールを手段として利用することもできますが、日頃から運用してない場合はキャッチアップ及び準備に時間がかかります。

- Ansibleなどの構成管理ツール
- [AWS Systems Manager Run Command](https://docs.aws.amazon.com/systems-manager/latest/userguide/run-command.html)

本記事では簡単なセットアップだけで、複数のLinuxサーバに対してオペレーション可能なpsshについて紹介します。

## pssh
**pssh**はparallel ssh programの略称です。

psshは複数のホストでsshを並行して実行するためのプログラムです。
入力をすべてに送信するなどの機能を提供します。

接続するLinux/UNIX/BSDのサーバ側でsshdのプログラムが起動していれば、並列でコマンドが実行できます。

### psshのインストール
MacOS/Debian/RHELなど様々なプラットフォームでインストール可能です。

MacOSの場合は、brewからインストールできます。

`$ brew install pssh`

### セットアップ
psshからホスト名を読み取るために、接続するサーバ情報を記載したテキストファイルが必要です。

ファイル名は任意の名前で大丈夫です。
またテキストファイルの中身は`[user@]host[:port]`の形式で、空白行と「#」で始まるコメント行を含めることができます。

例としてホームディレクトリ配下に、`.pssh_hosts`を作成します。

`$ vi ~/.pssh_hosts`

```text
pi@192.168.2.16
kali@192.168.2.17
```

### コマンドの実行
オプションについて`-h`は必須でhost_fileを指定し、`-i`は標準出力と標準エラーを表示します。

例えば、OpenSSLのバージョンを確認する場合は以下のようにコマンドを実行します。

`$ pssh -i -h ~/.pssh_hosts openssl version`

```console
[1] 00:48:08 [SUCCESS] kali@192.168.2.17
OpenSSL 3.0.7 1 Nov 2022 (Library: OpenSSL 3.0.7 1 Nov 2022)
[2] 00:48:08 [SUCCESS] pi@192.168.2.16
OpenSSL 1.1.0f  25 May 2017
```

上記の場合は1台、バージョンが3.0.7と出力されています。
CVE-2022-4203、CVE-2023-0216、CVE-2023-0217、CVE-2023-0401に該当するので、バージョンアップしましょう。

:::note
数にもよると思いますが、このように複数サーバに対するオペレーションを簡素化することができます。
また複数のホストにファイルをコピーするなどの操作もできます。
:::

# おわりに
昔、オンプレミスのシステム構築では、Tera Termのブロードキャスト機能を活用して、複数のターミナルから同時にコマンドを実行していました。
【Excel】新卒1年目が覚えて良かったショートカット集

# 初めに
初めまして！TKDです！
社会人になり約1年間が経つ私が、覚えてよかったExcelのショートカットについて書いていきたいと思います。
これから社会人になる人や、今後Excel等を使い始める人の参考になれば幸いです。

# ショートカット紹介
私が良く利用するショートカット8種類を紹介していきます。

#### ①Ctrl+1　［セルの書式設定］を表示する
範囲を選択し、「Ctrl+1」を押下することでセルの書式設定を表示することができます。
私は罫線を使う際によく利用しています。
リボンで罫線を選択するよりも細かな設定がしやすく、同時に塗りつぶし等も変更できるためよく活用しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2728372/bb37f55d-c1fc-99db-2caa-3433cef4f9d8.png)

#### ②Alt+H+M+M 「セルの結合」
結合したい範囲を選択し、「Alt+H+M+M」を押下することでセルを結合することができます。リボンからでも結合することができますが、キーボードだけで作業を完結させることができるため良く使用しています。
「Alt+H+M+U」を押下することで結合を解除することができます。

#### ③F4「前回と同じ動作をする」
上記のセル結合と併用することが多いショートカットです。
数か所のセル結合をしたいときや、各箇所のセルの色を変えたいとき等、同じ動作を繰り返す際に重宝します。

#### ④Ctrl+;「日付の入力」
日付を「yyyy/mm/dd」の形式で入力することができます。業務内でも日付を入力する機会は多いと思うため覚えておくと便利です。

#### ⑤Ctrl+Shift+方向キー「一連のデータを選択する」
選択した方向の入力されているセルまでを一括で選択することができます。
広い範囲を選択したい時に、効率的に選択できるため良く使用しています。

#### ⑥F2「セル内のデータを編集する」
文字を入力したいセルを選択し「F2」を押下する。
私はできるだけ作業はキーボード上で完結させてたいためこのショートカットも良く利用しています。

#### ⑦Ctrl+home「セルA1に移動する」
共有で使用しているファイル等は保存時にセルA1に移動させておくことが多く、覚えておくと良いです。

⑧Ctrl＋F、H「データの検索、置換」
ファイル内でデータを検索したいときや、文字の置換を行いときに利用します。
社会人になるとデータの数の多いファイルに触る機会も増えると思います。データの検索、置換機能を覚えてことで業務内で活躍すること間違いなしです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2728372/8d09899d-0dbc-cf31-b1e9-facc1a064258.png)

# まとめ
最後まで読んでいただきありがとうございました。
ショートカットを覚えておくことで作業を効率化し、他のことに使える時間が増えたと感じています。
先輩方が使用しているショートカットを聞いてみるのも良いと思います。私も先輩方に教えてもらいながら業務を行っています。

私は良く以下のサイトでショートカットを調べています。
自分に合ったショートカットを見つけてみてください。

https://dekiru.net/article/18619/

今回紹介したショートカット以外におすすめの物があれば是非コメントで教えてもらえると幸いです。
Filebeatのエラー Exiting: error unpacking config data: more than one namespace configured accessing 'output' 

# はじめに
FileBeatの設定をしていた時に下記のようなエラーが出て突然うごかなくなりました。

```
Exiting: error unpacking config data: more than one namespace configured accessing 'output'
```

# 原因と解説
FileBeatの出力先は、1つにしないといけないみたいです。
よく出力先をlogstashやelasticsearch本体にしていて、デバッグのつもりでoutputをconsoleにしていたら、
こうなるみたいです。

なので、下記のようにデバッグでoutput.console:を設定した場合は、
他の出力先は一時的にコメントアウトしておく必要があります。

```
output.console:
  pretty: true
```
工作効率を上げるためにプロジェクトフォルダを短いパスに移動する方法

## プロジェクトフォルダを短いパスに移動することの利点

ソフトウェア開発において、ソースコードやコンパイラの出力、ログなどを保存するために多数のフォルダとサブフォルダを作成する必要があります。しかし、これらのフォルダのパスが長い場合、不要な水平スクロールバーが表示されることがあり、コンパイルの出力やログにも混乱が生じることがあります。そこで、プロジェクトフォルダを短いパスに移動することは非常に良い方法であり、無駄な情報の混乱を減らし、作業をより効率的にします。

- 悪い例、フォルダのパスが長い、無駄や反復的な情報がたくさん。

```
2023-02-15 09:00:00 Project build started.
2023-02-15 09:00:01 Project "C:\Users\administrator\Documents\Visual Studio 2022\Projects\Demo\Demo.csproj" (Build target(s)):
2023-02-15 09:00:02 Build started.
2023-02-15 09:00:03 Demo -> C:\Users\administrator\Documents\Visual Studio 2022\Projects\Demo\bin\Debug\Demo.dll
2023-02-15 09:00:04 Creating directory "C:\Users\administrator\Documents\Visual Studio 2022\Projects\Demo\obj\Debug\".
2023-02-15 09:00:05 Demo -> C:\Users\administrator\Documents\Visual Studio 2022\Projects\Demo\obj\Debug\Demo.dll
2023-02-15 09:00:06 Build succeeded.
2023-02-15 09:00:07 "C:\Users\administrator\Documents\Visual Studio 2022\Projects\Demo\Demo.csproj" (Build target(s)) finished.
2023-02-15 09:00:08 Project build succeeded.
```

## `subst`コマンドを使用してプロジェクトパスをディスクのルートディレクトリにマップする

```powershell
subst k: "C:\Users\administrator\Documents\Visual Studio 2022\Projects\Demo"
```

このコマンドにより、`"C:\Users\administrator\Documents\Visual Studio 2022\Projects\Demo"`のパスが`K:`にマップされます。その後、`K:`を使用して、そのパスにアクセスできます。

ただし、コンピュータを再起動すると、マップされたディスクがクリアされます。そのため、このコマンドをコンピュータの起動時に自動的に実行するように設定することをお勧めします。

- これは、パスを`K:`に変更した後の出力です。

```
2023-02-15 09:00:00 Project build started.
2023-02-15 09:00:01 Project "K:\Demo.csproj" (Build target(s)):
2023-02-15 09:00:02 Build started.
2023-02-15 09:00:03 Demo -> K:\bin\Debug\Demo.dll
2023-02-15 09:00:04 Creating directory "K:\obj\Debug\".
2023-02-15 09:00:05 Demo -> K:\obj\Debug\Demo.dll
2023-02-15 09:00:06 Build succeeded.
2023-02-15 09:00:07 "K:\Demo.csproj" (Build target(s)) finished.
2023-02-15 09:00:08 Project build succeeded.
```

## まとめ

これは小さな変更であるが、作業効率を大幅に向上させることができます。特に、大量のファイルやディレクトリを処理する場合には有効です。プロジェクトフォルダを短いパスに移動することで、視覚的な混乱を減らし、コードの作成とデバッグの効率を向上させることができます。したがって、プロジェクトを開始する前に、パスの最適化を考慮することをお勧めします。
顧客分析の手順 分析フォーマットの適用例:関連性分析 利用低下顧客の傾向理解

:::note
この本書は2017年4月1日にTeradata Japanのブログに掲載された内容を、再掲載したものです。
掲載内容の正確性・完全性・信頼性・最新性を保証するものではございません。
また、修正が必要な箇所や、ご要望についてはコメントをよろしくお願いします。
:::


著者 山本 泰史 （やまもと やすし）


# 顧客分析の手順


## 第22回： 利用低下顧客の傾向理解
関連性分析を利用した分析例の 3回目。今回は「顧客リテンション」をテーマとした分析例をご紹介します。前回の分析例では、顧客全体と特定商品購入セグメントでそれぞれ関連性分析を実施して比較しましたが、今回は、上位顧客セグメントと、上位顧客の中でも離脱傾向にある顧客セグメントで比較を実施します。


### 分析の前提
今回の分析例では、旅客企業のデータを想定しています。図32 に示したように、成田発、米国4都市への渡航をそれぞれ商品として見立て、利益金額上位 30% の顧客を母集団として渡航顧客数構成比を 4渡航先毎に算出しています。

そして上位 30% の顧客ということは、比較的頻度が高く、もしかしたらさまざまな都市へ渡航しているかもしれません。この例では複数渡航先への重複を許容し、また渡航顧客数ということで、頻度に関しては無視しています。したがって 1人の顧客が同一都市へ 2回以上渡航しても、顧客数1 としかカウントされません。また 1人の顧客が 2都市に渡航した場合には、各都市に 1 とカウントされます。

<img width="700" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2768546/a9eb51e3-0d04-5d7a-4a8d-d710e031ea49.png">


### 渡航先の比較
図32 における傾向を見るに、自社の上位 30% 顧客は、サンフランシスコとロサンジェルスへの渡航をしている顧客が多いことがわかります。特にサンフランシスコへの渡航は 50%弱を占めており、上位顧客にとって重要な渡航手段として用いられていることがわかります。ただ、ここで示した値が多いのか、少ないのかは顧客全体と比較したり、特定のほかの期間と比較したりしなければ、実際に自社のビジネスボリュームを確保する上で充分な数字なのか判断できません。基礎理解としてはこれが必要ですが、改善すべき点、需要が伸びていて対応しなければならない点は、比較によって認識する必要があります。

ここでは、この上位 30% を母集団とした分析を基準にして、さらに上位 30% でかつ利益金額が低下した顧客（特定の 2期間を比較した場合に利用金額が減少した顧客）に絞り込んで、同様の分析を実施して　います。その結果が図33 ですが、これを見ると、図32 に示した傾向とは若干異なっていることがわかります。

<img width="700" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2768546/5725ef1b-d46c-ae8e-d6c4-d31192712879.png">

図33 では対象を絞り込んでいるため、若干数値自体は異なっていますが、サンフランシスコとロサンジェルス渡航に関しては渡航顧客数構成比がほぼ同等であることがわかります。違いがあるのは、シカゴ行きの便と、アトランタ行きの便です。 シカゴ行きの便に関しては、大きく落ち込んでいるのがわかります。またアトランタ行きの便に関しては、逆に増加しているのがわかります。このあたりに利益金額低下顧客の特徴がありそうです。

### アプローチの方向性
通常、分析を実施する方は価格情報や、外部の情報等も頭に入っているかと思いますが、ここではその情報が無い前提でここまでの話を進めました。明らかにシカゴ行きの便が利用される率は低下しており、これに関しては自社の価格や他社の価格との関係、新規参入便等の情報があれば、それが原因と類推できます。シカゴ行きの便に関しては、純粋に価格を下げて競合に対抗するという手段が残されていればそれを選択することも手段です。

また、シカゴ便に何か特別なサービスを追加するなどして、渡航顧客数を回復させることも考えられます。例えばこれらの顧客は上位 30% の顧客であるため、上位顧客に限った特典を追加し、価格を下げることなく上位顧客を維持できるかを検討することがまず必要です。これによって顧客を維持できれば、全体の価格を押し下げる必要がありません。これは利益金額の圧迫を防ぐことにもつながります。

そしてアトランタ便。利用顧客数が増加しているということは好ましいですが、これが利益低下顧客数に特有の傾向であるということは、価格を下げ、利益を圧迫した結果として利用顧客数の増加がもたらされているのかもしれません。もちろん価格を上げてしまうことは中々難しいですし、今現在の価格も競合との関係の中で設定されているはずですので、価格に手をつけるのは難しいかもしれませんが、これについては反対にサービスをシンプルにし、経費率を下げることが求められます。また、アトランタ便以外への利用も促していくことにより、顧客の渡航利用全体としての利益を維持していくことも必要です。もちろん、渡航需要はその場所に行かなければならないという理由に基づいて発生するため、シンプルに需要を伸ばすことは考えにくいですが、一旦これらの顧客が他の都市に渡航しなければならないとなった際に、自社便を選んでくれるように日頃からの関係維持を行なうことが重要になります。

以上、関連性分析を用いた分析例を、今回含め 3つご紹介してきました。いずれもどの商品が支持を得ていて、どの商品が支持を得ていないか明らかにすることを可能としてくれる分析です。また特定商品を購入した顧客に限定してこの分析を適用することによって、商品間の関連性の強さ、弱さを理解することが可能となります。これによって背後に存在している顧客の嗜好性や、日常的なニーズを理解することが可能となります。



#### Teradata Vantageへのお問合せ
[Teradata Vantage へのお問合せ](https://www.teradata.jp/About-Us/Contact)
libs.versions.tomlのgroupとname

GradleのVersion Catalogを使うと、依存関係の追加方法が少し変わる。

```kotlin
dependencies {
    compileOnly(libs.android.gradlePlugin)
    compileOnly(libs.kotlin.gradlePlugin)
    compileOnly(libs.ksp.gradlePlugin)
}
```

これは、**nowinandroid**の`build-logic:convention`モジュールの**build.gradle.kts**の一部の内容。

この`libs.android.gradlePlugin`や、`libs.ksp.gradlePlugin`の内容はどこで定義されているのかというと、**libs.versions.toml**にて定義されている。

```toml
[versions]
androidGradlePlugin = "7.4.1"
kotlin = "1.8.0"
ksp = "1.8.0-1.0.9"

[libraries]
# Dependencies of the included build-logic
android-gradlePlugin = { group = "com.android.tools.build", name = "gradle", version.ref = "androidGradlePlugin" }
kotlin-gradlePlugin = { group = "org.jetbrains.kotlin", name = "kotlin-gradle-plugin", version.ref = "kotlin" }
ksp-gradlePlugin = { group = "com.google.devtools.ksp", name = "com.google.devtools.ksp.gradle.plugin", version.ref = "ksp" }
```

**nowinandroid**では、**gradle**ディレクトリにて保存されている。
そして、この設定ファイルはモジュールに存在する**settings.gradle.kts**にてその読み込み先が設定される。

:::note 
基本的には、gradleディレクトリにlibs.versions.tomlを配置すると自動的に読み込んでくれる[らしい](https://star-zero.medium.com/gradle%E3%81%AEversion-catalog%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%9F%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA%E7%AE%A1%E7%90%86-eb81f8e88444)。
:::

```kotlin
dependencyResolutionManagement {
    ...
    versionCatalogs {
        create("libs") {
            from(files("../gradle/libs.versions.toml"))
        }
    }
}
```

そして、私がよくわからなかったのはTomlファイル内で使われている`group`や`name`である。

```toml
android-gradlePlugin = { group = "com.android.tools.build", name = "gradle", version.ref = "androidGradlePlugin" }
```

調べてみると、この`group`は従来の`implementation "androidx.room:room-runtime:$room_version"`の一番左端の部分を表している。
そして、`name`は真ん中を表している。

本題に戻ると、`group = "com.android.tools.build"`は[こちら](https://mvnrepository.com/artifact/com.android.tools.build)を表している。


そして`name = "gradle"`は[こちら](https://mvnrepository.com/artifact/com.android.tools.build/gradle?repo=google)を表している。

ちなみに、libs.versions.tomlで定義したプロパティ名がハイフン区切りの場合は、ドット（`.`）を使って`libs`変数を通してアクセスすることができる。
[Android] Vulkanで描画しているアプリをスリープから復帰させる手順

# 概要
Vulkanで書いたアプリケーションをAndroidで動かした際に、ホームボタンを押してアプリをスリープさせた後再度スタートしようとすると、画面が描画されなかった。
原因を調べるとVulkanのコンポーネントの内、いくつかは再度作成し直す必要があった。

# 環境
* Android 13
* NDK : 25.0

# 原因
Androidではアプリをリスタートするたびにwindowが変わっているようで、andoid_app->ANativeWindowの指すアドレスが毎回変化している。
なので、windowに依存するコンポーネントは毎回再作成する必要がある。

# 対策
windowに依存するコンポーネントは、アプリにもよるが基本的には以下が含まれると思っている。（赤色で表している部分）
![2023vulkan.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1446998/8e68af15-a815-00a4-b4af-94bb0d9a1c0e.png)
surfaceがwindowに依存して作成されるので、surfaceを作り直す必要があるが、surfaceに依存するコンポーネントもすべて作成し直す必要がある。

# 参考
https://qiita.com/syoyo/items/e3c49d06529ef7a63a70
>画面の回転や, スリープなどからの復帰 => SwapChain などの作り直し(Vulkan-glTF-PBR にはサンプルコード無いので, 自前でコード書く必要あり)

上記の記事を手掛かりに調査させていただきました。

# 感想
必要なコンポーネントを再作成せずにアプリをリスタートしても、特にwarningやerrorのログは出ずに真っ黒の画面が表示されていたので、なんとかログに出す方法はないものか。
Window Managerがwindowを変えました、みたいなログは出ているがinfoレベルなので、surfaceを再作成する必要があるとわかった上で見直してようやく気付くレベルなのではないかと思っている。

# Git Hub
何かの参考になれば。
https://github.com/kodai731/Aqoole-Engine-Android-Vulkan-Rendering-Engine-:title