OmniAICreator/Qiita-1.07M huggingface dataset:
【Rails】rails generate controllerで生成されるファイルを制限する【Railsアプリ全体のジェネレータ設定変更】

※この記録は、プログラミング初学者である私が、行き詰まったり難しいと思ったりしたものを復習できる様にとして残している自分メモです。同じ様なところでつまずいている方のお役に立つことができれば尚よし。間違った記載等あれば教えていただければありがたいです。

## はじめに
いろんなファイルを自動作成してくれるgenerateコマンド。しかし初期段階では何から何まで自動生成されると煩わしさを感じるものもあるからRailsにはジェネレーター実行時にファイルを生成しない為の設定も用意されている。
今回は、config/application.rb内の設定によって、generate コマンドで生成されるファイルに制限をかけようかと。

## rails generation時の挙動を確認
ターミナルでrails generation(またはrails g)を実行。
下記の様な色々なファイルが自動生成される。

```
$ bin/rails g controller boards
Running via Spring preloader in process 26592
[+] Running 2/0
 ⠿ Container v3_basic_rails_basic-chrome-1  Running
 ⠿ Container v3_basic_rails_basic-db-1      Running
      create  app/controllers/boards_controller.rb
      invoke  erb
      create    app/views/boards
      invoke  rspec
      create    spec/requests/boards_spec.rb
      invoke  helper
      create    app/helpers/boards_helper.rb
      invoke    rspec
      create      spec/helpers/boards_helper_spec.rb
```
ほら、いっぱい。
便利だけど、必要ないファイルがあれば、それだけ生成されないようにしたい。
(ちなみに自動生成したファイルについては、rails destroyコマンドで元に戻せる)

今回は、
・helperファイル
・testファイル
・ルーティング
のファイルの自動生成を無効にしてみる。

## 生成ファイルの制限をかけるには
config/application.rbのクラス内に、以下のようにコードを記述する。

```
   config.generators do |g|
     g.skip_routes true
     g.test_framework nill
     g.helper false
   end
```

上記の設定によって、生成されたのはこの２つのファイルだけに。
![2023-12-26 14.02の画像.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3535226/b51f8702-b24b-0b76-2e8b-9b627e5d5cb2.jpeg)
生成ファイルの制限成功！

ちなみにターミナルで操作するにあたって
```migrate
bin/rails g controller boards
```
でファイルを生成できる（migrate）のに対して
```　destroy
bin/rails d controller boards
```
で先ほどの生成ファイルを削除できる（destroy）。
数理経済　～目次～

# はじめに

数理経済を中心に良記事と思われるURLを記載しました。
補足的な事項を記事として書いていこうと思います。

# 不動点定理
数理経済でよく出てくる不動点定理をまとめました。
ブラウワーの不動点定理と角谷の不動点定理は、おさえておいたほうがよさそうです。

https://mathlog.info/articles/cThPNPgij54b8SB0kNnu

https://mathlog.info/articles/lOFXuVRt3aC6IbRhUSAm

# ゲーム理論

高校数学の美しい物語で、ゲーム理論が簡単に紹介されています。

https://manabitimes.jp/math/2123

ブラウワーの不動点定理を用いて、ナッシュ均衡が存在することを証明しています。

https://tsujimotter.hatenablog.com/entry/the-proof-of-the-existence-of-nash-equilibria

角谷の不動点定理を用いて、ナッシュ均衡が存在することを証明しています。

https://github.com/Hideki105/mathematical-engineering/blob/main/%E6%95%B0%E7%90%86%E7%B5%8C%E6%B8%88/hdk/%E3%82%B2%E3%83%BC%E3%83%A0%E7%90%86%E8%AB%96/Game_Theory.pdf
New Relic Browserを活用してフロントエンドのGraphQLのパフォーマンス分析やトラブルシューティングを効率化！

# はじめに
　APIを使用してコンテンツを動的に更新し、快適なユーザー体験を実現しているアプリケーションも多く、そのAPIのエラーやパフォーマンスを分析することはユーザー体験の改善に大変重要です。　
 
 　New Relic Browser(以下、Browser) を活用することでウェブアプリケーションのパフォーマンスに影響を与える問題を特定し、解決することが可能です。Browser は、アプリケーションからコールされたAPIのパフォーマンスやエラーの情報を収集、分析を実現しています。

  　しかし、発生したAPIのリクエストをグループ化する方法が、リクエストURLや呼び出し元のページ等に限られていたため、URLなどの識別子が存在しない**GraphQL**の場合は、参照、更新など異なるリクエストを判別するのが困難な状態でした。

　Browser agent v1.245.0 のアップデートにより GraphQL の Operator Type, Operator Name を使ったグループ化が可能になったので、本記事で紹介します。

https://docs.newrelic.com/jp/docs/release-notes/new-relic-browser-release-notes/browser-agent-release-notes/browser-agent-v1.245.0/

:::note info
主要なアップデートの詳細はこちら。
[New Relic アップデート一覧](https://newrelic.com/jp/blog/nerdlog/new-relic-update "New Relic アップデート一覧")
:::
:::note info
[New Relic株式会社のQiita Organization](https://qiita.com/organizations/newrelic)では、新機能を含む活用方法を公開していますので、ぜひフォローをお願いします。
:::

 
# GraphQL の Operator Type, Operator Name でグループ化が可能に
　発生したAPIのリクエストは、Browserの AJAX ページから参照できます。下記の例ではリクエストURL毎にグループ化されており、URLが処理毎に異なるためそれぞれのパフォーマンスやリクエスト回数を確認可能です。
![webportal.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3043202/53639a2f-93d3-0b35-25dc-2a567a7423f9.png)

　GraphQLの場合は、URLなどの識別子が存在しないため、下記のように異なる処理がまとめて表示されている状態でした。
![GraphQL_old.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3043202/58bea728-cb79-4f01-c8c0-ef0acecb3c41.png)

　今回のアップデートでは下記のように GraphQL の Operator Type, Operator Name でグループ化できるようになりました。
![type-name.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3043202/25c1ab96-2000-6656-f9de-85dc8d8048d4.png)

また、グループ化されたGraphQLの処理毎にパフォーマンスデータを分析することが可能です。
![スクリーンショット 2023-12-28 12.32.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3043202/b723f6ce-4f74-21f4-93b5-3836fd4f9a69.png)

 :::note warn
　この変更はエージェントのアップデートにより収集する情報が増えたことで実現されています。同じアプリケーションであってもエージェントのバージョンが古ければ下記のように **Group By** のリストに **Operator Type**, **Operator Name** は表示されません。
![old-new.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3043202/90b08b61-e5b2-57f5-4b85-fa4e2809fe29.png)
　使用する場合は、Browser エージェントのバージョンにご注意ください。

:::
# Operator Type, Operator Name が追加されているデータを確認
　**Operator Type**, **Operator Name** は、New Relicのデータベースに **AjaxRequest** イベントの情報として保存されています。
![Data Expo.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3043202/0532480e-5099-2d98-550b-08731e0e9b88.png)

　NRQLを使ってデータを取得することが可能なので重要なリクエストやよく確認するリクエストはクエリをカスタマイズしてダッシュボードに表示しておくこともできます。

 ```:NRQL
FROM AjaxRequest SELECT count(*) 
FACET operationFramework, operationType, operationName TIMESERIES
```

# まとめ
　今回のアップデートで GraphQL を使用しているウェブアプリケーションのパフォーマンス分析やトラブルの調査が以前よりも簡単にできるようになりました！フロントエンドのパフォーマンス改善をしたい、エラーの原因調査をしたいけどGraphQLを使っているからうまく活用できていなかったという方はこの機会にぜひチャレンジしてください。

 :::note info
[New Relic株式会社のQiita Organization](https://qiita.com/organizations/newrelic)では、新機能を含む活用方法を公開していますので、ぜひフォローをお願いします。
:::
「スクラムチーム用セルフチェックリスト」を実施してみた

## はじめに

発端は下記Xの投稿を見て、やってみたいなと思いました。実際に、私の受け持つチームで実施してみました。

https://twitter.com/ryuzee/status/1732177135606083768?s=46&t=JnUFc46pH3gAg3jN09yqDg

https://www.ryuzee.com/contents/blog/14561

## スクラム開発の形骸化と悩み

元々、3年程度チームとしてRPAプロダクトのスクラム開発を行っていたのですが、メンバーの入れ替えもかなりあったため、現在は形骸化が進んでしまいました。(ちなみに私がマネジメントをし始めてからは大体1年くらいです。それまではテックリードをしていました)

現チームメンバーの中には問題視くれている方もいたのですが、「現状で回っているんだから問題ない」といった考え方をもっている方も多い状況でした。(スクラムガイドに書かれている内容もあまり覚えていないようなメンバーが増えてしまいました)
また、そういった状況下で開発をしているため、年々自身で考えてチーム貢献してくれるメンバーが減ってきたことがチーム内で取っているアンケートからも可視化できており、それに伴いマネージャーの管理する内容が過多になっていることが悩みでした。

## 在るべきスクラム開発を目指そう

そのような中、転機としてチーム再編があり、10名超のチームから7名のチームにスリム化しました。私としては、チャンスだと思ったので改めて在るべきスクラム開発を目指そうと発起しました。

早速、抜本的な開発プロセスの見直しをしようと思ったのですが、説明した通りスクラムへの関心がメンバーから消えつつあり、やってもいいけどあまり良く分からないから勝手にやってくれみたいな雰囲気でした。
どうしたらチームメンバーに自分ごと化してもらえるのか、かなり苦慮していたのですが、そこでこの「スクラムチーム用セルフチェックリスト」を見つけました。

チームメンバーには、「今のチーム内のスクラム開発が一般的なスクラム開発とどの程度乖離しているか知りたくないですか？」といった形で少し興味を持ってもらってからチームで話しながらチェックを付ける会を用意しました。
事前にメンバーには下記のスクラムガイドを一読してもらってから実施しました。
(2017年度版は全員読んでいたはずなので、それの最新版だよとそそのかしました)

https://scrumguides.org/docs/scrumguide/v2020/2020-Scrum-Guide-Japanese.pdf

## 実施してみた

結果はこんな感じでした。合計は67ポイントでした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/544280/b85f8499-ccb4-bd92-1cc2-046c60e70d8e.png)

### 所感

スクラムイベントの遵守や開発タスクの管理等はチーム文化として根付いており、上手く回っているのかなと思いました。
一方で、インクリメントの意識やスプリントゴールへの意識がかなり低い事がわかりました。(これが漠然と形骸化していると感じていた原因だったのかと思いました)
また、認識はしていましたが明確にSMとPOを立てていなかった(直近は全部私が無理やり受け持って対応してました…)ことがかなり良くない方向に作用してそうだなと思いました。

### 良くできていた点

- スプリントの予測が正確(ベロシティが比較的安定している)
- デイリースクラムの意識が高い(問題の共有・解決が非常に早い)
- レトロスペクティブでの分析->アクションのサイクルが回っている
- プロダクトバックログのメンテナンスが行き届いている

### 良くできていなかった点

- スプリントゴールが曖昧
- プロダクトオーナーの不在に伴い、完成定義が不明瞭
- スクラムマスターの不在に伴い、スクラムの考え方が浸透していない
- 完成の定義が不明瞭(インクリメントを作成していない)

## この結果を踏まえて

下記のアクションを実際に来年度から実施します。

- PO, SMのロールを明示的に立てる(POは私が。SMはやりたいメンバーに移譲しました)
- スプリントプランニングやプランニングポーカーでのスプリントゴールの定義策定・共有
- プロダクトバックログリファインメントの実施(ポイントの整理だけでなく、ゴールの見直しも)

実施したいことはもっとありますが、まずチームメンバーの意識改善からできればと思っています。特にゴール・完成の定義はチーム再編に伴い、ミッションそのものから変えていく必要があるため、チームメンバーと相談しながらスクラムチームで達成すべき目標も含めて見直していく想定です。

## さいごに

これを読んでいる主にうちのスクラムマスターとチームメンバーへ、まずは下記を読んどいてくれると助かります。(僕はマネジメント本たくさん読みます)

### チームメンバー

https://www.shoeisha.co.jp/book/detail/9784798167282

### スクラムマスター

https://www.shoeisha.co.jp/book/detail/9784798166858

https://www.oreilly.co.jp/books/9784873116303/

https://tatsu-zine.com/books/clean-agile
SageMakerのリアルタイム推論エンドポイントで使用しているPythonパッケージの一覧を取得する

# はじめに
 SageMaker のリアルタイム推論エンドポイントで使用している（モデルコンテナにインストールされている）全ての Python パッケージの、パッケージ名とバージョンの一覧を取得したいというタイミングがありました。
 
その際にやったことをまとめます。

# やったこと
リアルタイム推論エンドポイントの推論コード（カスタムスクリプト）内に、以下の Python コードを仕込んで推論を実行すると、ログ（CloudWatch Logs）に``pip freeze``の形式で結果が出力されます。

```Python
import subprocess
result = subprocess.run(['pip', 'list', '--format', 'freeze'], stdout=subprocess.PIPE, text=True).stdout
print(result)
```

また、エンドポイントから S3 へアクセス可能な場合、以下のように S3 へテキストファイルを出力することもできます。
```Python
import boto3
import subprocess

result = subprocess.run(['pip', 'list', '--format', 'freeze'], stdout=subprocess.PIPE, text=True).stdout

s3_client = boto3.client('s3')
bucket_name = '<S3バケット名>'
file_name = 'pip_freeze_output.txt'
s3_client.put_object(Bucket=bucket_name, Key=file_name, Body=result)
```

# お行儀が悪くないか？
本来、推論エンドポイントのモデルコンテナ内部に直接アクセスしたい場合は、[AWS Systems Manager (SSM) を使用する](https://docs.aws.amazon.com/sagemaker/latest/dg/ssm-access.html)ように公式ドキュメントで言及されています。

この AWS Systems Manager (SSM) を使用するには、カスタマーサポートに連絡してアカウントをホワイトリストに登録してもらうという手順を踏む必要があります。

この辺りの公式ドキュメントの記載を全無視して、モデルコンテナ内部で、Python の``subprocess``でコマンド実行しちゃっていいの？という疑問はありました。

# AWSサポートに問い合わせてみた
AWSサポートに問い合わせてみたところ、Python の``subprocess``でコマンド実行しても問題ないとのことでした。

むしろ、AWSサポートのエンジニアからも「Python の``subprocess``でコマンド実行する方が手っ取り早いよ」と提案されました。

聞いてみるもんですね。
2023の施策をKPTで振り返る

2023年もあっという間でした。
今年できたこと、できなかったことたくさんあります。
書けないこともありますが、振り返ってみましょう。
雑にしか書いてないので、気になるトピックがあれば、教えてください。こっそりお話します。


## PHPアプリケーションエラーの検知
今まで把握できていなかったエラーも全て取得できるようにした。
### Keep
- クライアントより先に検知できる体制に貢献
- ミスが起きやすいポイントが把握できる
### Problem
- 解決せずスルーしている検知がある
### Try
- 検知→即解消できる状態に持っていく
- Datadogとかそういうの入れる


## AWS代理店の選定
後述のAWS移管に際し、改めてゼロベースで選定した。
### Keep
- コストカット
- サポート体制強化
- 合わせて、GCP、Azureも検討し学びが深まった
### Problem
- 選定、条件交渉に悩んだ
### Try
- 活用していく


## PHPstan導入
言わずとしれたPHPの静的解析ツール。
ついに導入・運用開始しています。
### Keep
- 導入した、運用した、しれっと引き継いでくれた
- 毎週、差分で追っていけるように、baselineを毎週更新するようにした 
### Problem
- 全体で実行すると実行時間が長すぎて、モジュールごとに分割して実行できるようにした
- PHPのバージョンの問題で、どのサーバで実行すれば良いのか迷った
- 一部実行できない処理があった
### Try
- CIに組み込む
- 開発者自ら気づき、修正する体制に
- レベルを上げてみる


## 過去のHPサービスのクローズ
今までありがとう。
### Keep
- 運用コスト減、インフラコスト減
### Problem
- クローズまでに数年は要した
### Try
- 他サービスをクローズすることがあれば、経験を活かしていく


## インフラのAWS移管
今年の目玉。詳細は下記記事見てください！
[不動産事業者向けSaaS「いえらぶCLOUD」のクラウドリフト＆シフト](https://enterprisezine.jp/article/detail/18435 "1時間に100万超のアクセスで「オンプレ基盤に限界」二人三脚で挑んだSaaSのAWS移行")
### Keep
- 耐障害性の大幅向上
- AWSサービスの活用可能性が増えた
### Problem
- 移管に伴う障害発生
- 円安含めてコスト増大
### Try
- AWSサービスの活用
- コスト削減
- さらなるクラウドネイティブ


## アップデートフローの変更
AWS移管に続き、今年の目玉②。
詳細は下記記事見てください！（2回目）
[不動産事業者向けSaaS「いえらぶCLOUD」のクラウドリフト＆シフト](https://enterprisezine.jp/article/detail/18435 "1時間に100万超のアクセスで「オンプレ基盤に限界」二人三脚で挑んだSaaSのAWS移行")
### Keep
- クライアント満足度向上
- 社員負担軽減
- テスト効率開発効率増加
- AWS側の事例としても使ってもらった
### Problem
- 不慣れな開発手順による不具合発生
- テーブル定義の変更
### Try
- ブルーグリーンデプロイを生かしたテスト手法の確立


## PHPバージョンアップ用のDocker開発環境構築
PHPのバージョンアップに向けて、簡単に確認・修正できるように仕組み化。
### Keep
- こういった用途ではぴったりだった。
- WSL2とDockerを組み合わせることで、Windows環境で効率的な開発環境構築ができた
### Problem
- ソースコードをどこに置くか。権限をどうするかが絶妙な所
### Try
- 他アプリケーションへの適用


## AWSセキュリティ系サービスの導入
守りを固める。AWSの方々にはお世話になりました。
### Keep
- GuardDuty、Security Hub、Control Tower、CloudTrail等の導入
- 使用リージョンの制限を設定
- 検知をSlack通知する所まで設定
### Problem
- 対処していない検知がある
### Try
- 検知と対処体制の確立


## WAFのレートベースルールステートメントの追加
守りを固める②。
勉強不足で、レートべースルールやったことなかった。自由度そこまで高くないが、必要十分という感じ。
### Keep
- 不正なクローラーやBotを弾けるように
### Problem
- 閾値の調整に時間がかかった
### Try
- 最適化の運用


## マイクロサービス設計に活用するDDDとEvent-Stormingを実施
CLOUD2に向けて。
### Keep
- AWSの方々ご協力の元、実際にやってみることができ学びが深まった
### Problem
- 時間を取った
### Try
- 実践に適用、活用していく
- ドメインの分割を見極めて、まずはDB移管から。その後アプリケーションの最適化



思いつく感じでざっくり書きました。
来年もよろしくお願いします！
CloudBerry Explorer：お気に入り削除方法

# はじめに
CloudBerry ExplorerはAmazon S3などのクラウドストレージ用のファイルマネージャーです。
よく使うパスをお気に入りに設定できるのですが、何らかの理由でパスへアクセスできなくなったときに、お気に入りを削除できなくなります。
その場合の削除方法です。

# お気に入りが削除できない現象
通常であればお気に入りをしているパスで「★マーク」をクリック→「Remove」でお気に入りを削除できます。
![2023-12-28-12-00-02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230850/7c81452d-e39f-155f-0d21-05370ba3e451.png)

しかし、パスにアクセスできない場合、エラー画面が出てしまいお気に入りが削除できません。
![2023-12-28-11-56-55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230850/fcebc3c6-cfe5-00a7-2f88-e79d39d8d9c5.png)

![2023-12-28-11-57-15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230850/e78ba79a-ad88-0195-3898-4dc62177ed0a.png)

設定画面などにもお気に入りを管理する項目がないため、アクセスできないお気に入りが残り続けてしまいます。

# 手順
アクセスできないお気に入りを削除する方法です。

1. `File`→`Export Settings`で設定ファイルをエクスポートする
	![2023-12-28-12-08-46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230850/9280cbf7-56f6-1839-dcf3-300d96a51c36.png)

1. エクスポートしたファイルをテキストエディターで開き、該当のお気に入りを削除する

1. `File`→`Import Settings`で先ほど加工した設定ファイルを選択する
	![2023-12-28-12-10-05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230850/49c40d8e-fa31-71df-f5f2-ea9e80382fad.png)

1. `Accounts`のチェックをはずし、`Favorites`は「Replace」を選択してインポートする
	![2023-12-28-12-11-55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230850/e9f86f5c-7999-a5d7-43c5-0a23228e2c9a.png)
【配列に対しての複雑な処理】集団行動

https://paiza.jp/works/mondai/array_utilization_primer/array_utilization_primer__group_move


```py
N,Q = map(int,input().split())
A = [a for a in range(1,N+1)]
for i in range(1,Q+1):
    tmp = []
    tmp = input().split()
    if tmp[0] == 'reverse':
        A.reverse()
    elif tmp[0] == 'swap':
        num = A[tmp[1]+1]
        A[tmp[1]+1] = A[tmp[2]+1]
        A[tmp[2]+1] = num
    elif tmp[0] == 'resize':
        c = int(tmp[1])
        A = A[:c]
print(*A,sep="\n")

```
足もとに流れるGitコマンド

## 二つのことが明らかだった。
1. 人の作ったGitコマンド集は過剰であるか欠乏しているか、自分にとってそのどちらかだということ。
2. Gitコマンドは完成されたプロンプトであり、そこにはもう真の変化が起こりえないということ。

**つまり自分好みのコマンドだけをまとめて、俺的恒久なGitコマンド集を作る時期なのだということ。**

それが以下のコマンドたちである。

---

### 新規git環境作成（ローカルリポジトリ作成）
```shell
$ git init
```
---

### ブランチを作成
```shell
$ git checkout -b 作成するブランチ名
```
---

### ブランチの一覧を見る
```shell
$ git branch -a
```
---

### ブランチをリモートに登録
```shell
$ git push -u origin 作成したブランチ名
```
---

### マスターにマージ
```shell
$ git checkout master  //マスターに移動
```
↓
```shell
$ git merge XXXXX  // マージしたいブランチ名
```
↓
```shell
$ git push
```


---

### ローカルファイルをgithubにアップ

ローカルのディレクトリに移動して
```shell
$ git init
```
↓
```shell
$ git add .
```
↓
```shell
$ git commit -m "コミット名”
```
↓
```shell
$ git remote add origin url名
```
↓
```shell
$ git push origin main
```
---

### 退避（スタッシュ）
```shell
$ git stash -uk  退避
```
```shell
$ git stash list  スタッシュしたもののリスト
```
```shell
$ git stash apply stash@{0}  指定してスタッシュを元に戻す
```
```shell
$ git stash pop stash@{0}  指定してスタッシュを元に戻してスタッシュを削除
```
```shell
$ git stash drop stash@{0} 指定してスタッシュを削除
```
---

### 直前のコミットを取り消す（修正内容はそのまま）
```shell
$ git reset --soft HEAD^
```
---

### 直前のコミットでやり残したことが出てきた or コメントを修正したい場合
```shell
$ git commit --amend
```
---

### 間違ってmainにpushしてしまった場合
ローカルのリポジトリで直前のコミットを取り消す
```shell
$ git reset --soft HEAD^
```
↓

強制的にPushする
```shell
$ git push -f origin main
```

歴史の書き替えなので、あまりよくない。

---


### ブランチの削除
ローカルのブランチを削除する場合
```shell
$ git branch -d localBranchName
```
リモートのブランチを削除する場合
```shell
$ git push origin --delete remoteBranchName
```
----

### 直前のマージを取り消ししたい
```shell
$ git merge —abort
```
※コンフリクト対応していない場合のみ

---
レイモンド・カーヴァーに敬意をこめて。
grid使ったらheight:autoのトランジションのアコーディオンできんで。

# はじめに
いつもお世話になってるコリスさんのこの記事みて、
久しぶりにテンションが上がったので早速やってみた。

[Web制作者の念願がついに叶った！ height: 0;からheight: auto;へのトランジションをJavaScriptは無し、CSSで実装する方法](https://coliss.com/articles/build-websites/operation/css/css-transition-from-height-0-to-auto.html)

ひと昔前は表示要素が可変な場合、min-heightを使ってしのいでたから懐かしみ。
（できるだけjs使わない派のワイ）



# 結論からいうとgrid使って`0fr → 1fr`する。

```html:main.html
<div class="box">
  <div>Hover me!</div>
  <div class="body">
    <div>
      <p></p>
    </div>
  </div>
</div>
```


```css:index.css
.body {
  display: grid; 
  grid-template-rows: 0fr;
  transition: 250ms grid-template-rows ease;
  > div {
    overflow: hidden;
  }
}
 
.box:hover .body {
  grid-template-rows: 1fr;
} 
```

# 仕組み
`.body`を`gird`にして、`.box`をホバーした時に`.body`が閉じたり開いたりする感じ。

# 気づいたこと。

#### .boxいらないんじゃね？
`.body`にhoverつけたら要素の高さが0になるのでhoverしにくい。

#### ホバーじゃなくてボタンにしたい！
ボタンにしたい場合は`checkbox`と `+`（兄弟要素） 使えばできる。
※`details`でやってみたけど`display`の表示・非表示には対応してなかった。

# ポイント
みそは`.body`直下の`div`に`overflow: hidden`いれてるところ。
`.body`に直接入れたいところやけど、後々デザイン入れる過程で`padding`とか入れたりする。
`padding`入れると　`padding`分の高さ出ちゃうねん。（高さ0にならない）

# 最後に
管理画面設計していると、ユーザが入力する可変な値をどう表示させるか、、、
当時は結構頭悩ませた。
例えば100文字〜2000文字入力を許容してて、
特に重要なものではないので普段は隠しておきたいみたいな時ね。（ツールチップ）。

今はvue使ってるので特にそこまで苦労はしてないけど、
とりあえず忘れないために忘備録。
富岳のPyTorch-1.7.0でJGLUEのJCommonSenseQAを動かすには

[昨日の記事](https://qiita.com/KoichiYasuoka/items/73c1f0bc69101dd03386)の続きだが、スーパーコンピュータ「富岳」のPyTorch-1.7.0上で、[JGLUE](https://github.com/yahoojapan/JGLUE)を動かしてみることにした。

```
#! /bin/bash
#PJM -L rscgrp=small
#PJM -L elapse=4:00:00
#PJM -L node=1
#PJM -j
#PJM -S

G=`id | sed 's/^.*gid=[0-9]*(\([^)]*\)).*$/\1/'`
set `ls -d /vol*/$G /vol*/data/$G` $HOME
export PYTHONUSERBASE=$1/jglue
export PATH=/home/apps/oss/PyTorch-1.7.0/bin:$PYTHONUSERBASE/bin:$PATH
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/home/apps/oss/PyTorch-1.7.0/lib64
export HF_HOME=$PYTHONUSERBASE
export TMPDIR=$PYTHONUSERBASE/tmp
mkdir -p $TMPDIR
T=$TMPDIR/transformers-4.28.1
if [ ! -d $T ]
then git clone -b v4.28.1 --depth=1 https://github.com/huggingface/transformers $T
fi
J=$TMPDIR/JGLUE
if [ ! -d $J ]
then git clone --depth=1 https://github.com/yahoojapan/JGLUE $J
     cat $J/fine-tuning/patch/transformers-4.9.2_jglue-1.1.0.patch | ( cd $T && patch -p1 )
     pip3.8 install tokenizers==0.13.3 protobuf==3.20.3 accelerate==0.20.3 --user
     ( cd $T && pip3.8 install . --user )
     pip3.8 install -r $T/examples/pytorch/text-classification/requirements.txt --user
     pip3.8 install -U tqdm packaging typing_extensions --user
fi

python3.8 $T/examples/pytorch/multiple-choice/run_swag.py --model_name_or_path KoichiYasuoka/deberta-base-japanese-wikipedia --do_train --do_eval --do_predict --max_seq_length 64 --per_device_train_batch_size 16 --learning_rate 5e-05 --num_train_epochs 4 --output_dir $TMPDIR/output.${PJM_JOBID-$$} --overwrite_output_dir --train_file $J/datasets/jcommonsenseqa-v1.1/train-v1.1.json --validation_file $J/datasets/jcommonsenseqa-v1.1/valid-v1.1.json --test_file $J/datasets/jcommonsenseqa-v1.1/valid-v1.1.json --use_fast_tokenizer True --evaluation_strategy epoch --warmup_ratio 0.1
```

富岳のログインノードから`pjsub`して、[deberta-base-japanese-wikipedia](https://huggingface.co/KoichiYasuoka/deberta-base-japanese-wikipedia)のJCommonSenseQAを測ってみたところ、ファインチューニングに3時間を要した後に、以下の「eval metrics」が出力された。

```
***** eval metrics *****
  epoch                   =        4.0
  eval_accuracy           =      0.639
  eval_loss               =     2.1449
  eval_runtime            = 0:01:54.73
  eval_samples            =       1119
  eval_samples_per_second =      9.752
  eval_steps_per_second   =       1.22
```

私(安岡孝一)の[2022年6月25日の日記](https://srad.jp/~yasuoka/journal/655222/)とほぼ同じ結果だが、ファインチューニングに9倍もの時間を要している。やっぱり、複数ノードに挑戦しなきゃダメかな。
【ChatGPT有＋DALL-E3】に画風を変えて描画を頼んだ。


　どうも、カーブミラーです。

　今回は、DALL-E3に、画風を変えての描画をお願いしました。

:::note info
本記事は、ChatGPT（有料版）
＋DALL-E3で行なっております。
あしからず。
:::
　みなさんは、
　　仕事納めしましたか？

　私はおかげさまで
　　今年の仕事を終えました。

　それでも
　　毎日の投稿を
　　　続ける所存です。

　予定もありませんし(泣)
***
　それはさておき（流すw）

　Google Bardを
　　お使いの方は
　　　いらっしゃいますか？

　BardのExtensionsは
　　お使いでしょうか？

　拡張機能ですね。
　　以前に記事をアップしたので、
　　　……と思ったら、
　　　　もしかして、
　　　　　記事にニュースとして
　　　　　　埋め込んじゃった？

　あっ、やっぱり。
　　下記を参照してください。
[【ChatGPT無&有】に新機能。その名も“Archive”。ほかにもあり。](https://qiita.com/kabumira/items/8623325f0aedceff6cda)

　アクセスしたら、
　　プロンプトを
　　　打ち込むわけですが、
　　　　ここでワンポイント。

　入力の際に、
　　“@”を入れてみてください。

　Googleのサービス名が
　　リストされて出てきます。

　そこから用のあるサービスを
　　選択して、プロンプトを
　　　入力すれば、
　　　　Bardへの明確な指示に
　　　　　なります。

　ちょっと
　　変な回答を
　　　するかもしれませんが、
　　　　まぁ、許容して
　　　　　やってください。
***
　今回は、
　　画風を指定して
　　　描画してもらいます。

 「男性を描画。画風は◯◯」
　　というプロンプトで
　　　描画してもらいます。

　◯◯に、
　　下記を入れて
　　　実行してみました。
　・油絵
　・水彩画
　・モザイク画
　・水墨画
　・日本画
　・フレスコ画

　以下が
　　その出力になります。
![DALL·E 2023-12-28 10.23.27 - A realistic oil painting of a male figure. The man is portrayed in a classical style, with a focus on intricate details and realistic shading. The bac.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457238/f36e9d85-317e-808f-5ed5-1833127b0938.png)
![DALL·E 2023-12-28 10.23.34 - A watercolor painting of a male figure. The painting showcases a soft, fluid style typical of watercolors, with gentle color gradients and light washe.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457238/21028bd1-0b71-06eb-e6d4-acbdfb43aeba.png)
![DALL·E 2023-12-28 10.23.40 - A mosaic artwork depicting a male figure. The image is composed of small, colorful tiles arranged to form the figure, showcasing the intricate and pix.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457238/09f3471d-b44e-528a-dba0-a89f695b961b.png)
![DALL·E 2023-12-28 10.23.46 - A sumi-e (Japanese ink wash painting) of a male figure. The painting features the distinct style of sumi-e, characterized by the use of black ink grad.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457238/d4b09e5f-9f31-cf68-ec95-27eb44900cfa.png)
![DALL·E 2023-12-28 10.23.51 - A traditional Japanese-style painting (Nihonga) of a male figure. This painting showcases the unique qualities of Nihonga, including the use of natura.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457238/7d2da348-1c9c-4e3c-7161-2941012affe9.png)
![DALL·E 2023-12-28 10.23.57 - A fresco painting of a male figure. The artwork captures the unique characteristics of fresco painting, known for its rich colors and durability. The .png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457238/bd247f67-f213-708d-a3bf-1cead44896c7.png)
***
　画風が変わるだけで
　　ずいぶんと変わりますね。

　もちろん、
　　ほかにも
　　　たくさんの画風が
　　　　ありますから、
　　　　　ぜひ、お試しください。

　また、
　　何かを使って
　　　描くことも可能です。

　例えば、
　　チェリービーンズで
　　　描くこともできます。

　あるいは、
　　新聞紙なんかですね。
　　　ほとんど文字は
　　　　読めませんけどw

　さぁ、みなさん、
　　チャレンジしてみて
　　　ください。

　今回は、ここまで。
LeetCode備忘録_その5_Arrays & Hashing_Group Anagrams

# 概要
- [LeetCode](https://leetcode.com/) を始めてみた。
  せっかくなので１テーマごとに解法と学びをアウトプットしてみる。
# 取り組む内容
- こちらの[ロードマップ](https://neetcode.io/roadmap) に沿って実施する。
- 言語は Python
  ![スクリーンショット 2023-12-11 1.31.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3636949/294af7ca-d769-b5ca-51d2-1a05b58036d5.png)
- 今回テーマは「Arrays & Hashing の Group Anagrams」

# テーマ詳細

### 原文

Given an array of strings strs, group the anagrams together. You can return the answer in any order.

An Anagram is a word or phrase formed by rearranging the letters of a different word or phrase, typically using all the original letters exactly once.

Example 1:

Input: strs = ["eat","tea","tan","ate","nat","bat"]
Output: [["bat"],["nat","tan"],["ate","eat","tea"]]
Example 2:

Input: strs = [""]
Output: [[""]]
Example 3:

Input: strs = ["a"]
Output: [["a"]]

### 日本語訳

※G 翻訳
文字列 strs の配列を指定して、アナグラムをグループ化します。 回答は任意の順序で返すことができます。 アナグラムは、通常は元の文字をすべて 1 回だけ使用して、別の単語またはフレーズの文字を再配置することによって形成された単語またはフレーズです。

# 解法

```
class Solution(object):
    def groupAnagrams(self, strs):
        """
        strs: List(str)
        return: List(List(str))
        """
        h = {}
        for word in strs:
            sorted_word = "".join(sorted(word))
            if sorted_word not in h:
                h[sorted_word] = [word]
            else:
                h[sorted_word].append(word)
            
        answer = []
        for i in h.keys():
            answer.append(h[i])
        
        return answer
```

[Solutionへのリンク](https://leetcode.com/problems/group-anagrams/solutions/4468819/python-solution-easy-to-understand-solution-faster-than-87-25/)

# 結果
- Runtime:63ms
- Beats 87.25% of users with Python 　※投稿日時点

# 思想
- 所見では解けなかったので、先人のSolutionを参考にさせていただきました
- アナグラムはソートすると同じ文字列になる性質があるのでそれを利用する
- ソート後の文字列と、ソート前の文字列が対応するように管理する。管理方法は辞書で実施することに
- 辞書のkeyにソート後、valueにソート前の文字列を持たせる。後者はリスト型にする。Dict(str:List(str))

# 学び
- 「アナグラムはソートすると同じ文字列になる性質がある」ということを先人Solutionで見かけて目からウロコだった
- for文の中で以前に出てきた値を記憶しておきたい場面は頻繁にあると思おうが、その際には辞書型が有用な解決策となる。個人的に辞書はあまり使用する
- sorted("tea")で ["a", "e", "t"]というリストで返ってくる。これを["aet"]に変形するには"".join(sorted("tea"))とjoinを使用するとできる
- str in {辞書}とすると　辞書のkeyの中にstrが含まれるかどうかが判定される

# 感想
- 初めてのmediumレベルだった。その通りで難しく所見では解けなかった
- アナグラムの見分け方として、「アナグラムはソートすると同じ文字列になる性質がある」この考え方はとても効率的だし、コードに落としても分かりやすいので良い学びになった
Plotlyで作成したグラフをMarkdownに埋め込み【備忘録】

# はじめに
　報告書の作成って手間ですよね。私は研究職という職業上（？）報告書を書くことが多いのですが、普段Markdownでザザっと書いてHTMLにして上長にぶん投げています。
とある報告書でPlotlyで作成したグリグリ動くグラフをMarkdownに貼り付けたいなぁと思い、作業したことを備忘録として残しておきます。
　手法としては、plotlyで作成したfigをHTMLで出力し、Markdownに＜iframe＞タグで埋め込みます。

# 埋め込みたいグラフ
以下のようなマウスでグリグリ動かせる感じのグラフを埋め込みます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3493004/3d459fb9-a32e-a0b9-b797-aabd8bc193cf.png)

# コード
まずは普通に散布図を作成します（別に散布図でなくてもいいです）

```python:figの作成
import pandas as pd
import plotly.express as px
import plotly.graph_objects as go

df = pd.read_excel('test_data.xlsx')

x = df['Yield']
y = df['Temp']
z = df['Solv_mL']

#三次元散布図の作成
fig = px.scatter_3d(df, x=x, y=y, z=z) 

#ラベル作成
for i, j, k in zip(x, y, z):
    label = '({:.2f}, {:.1f}, {:.1f})'.format(i, j, k)
    fig.add_trace(
        go.Scatter3d(x=[i], y=[j], z=[k], mode='text', text=[label])
    )
    
fig
```

これで先のような図が出来上がりましたね！
あとは一行追加するだけです。

```python:HTMLに書き出し
fig.write_html("fig_output.html", full_html=False, include_plotlyjs='cdn')
```

fig.write_htmlの引数ですが、
・full_html
　True（デフォルト）の場合＜html＞タグで始まる完全なHTMLドキュメントを含む文字列を生成します。False の場合、単一の＜div＞要素を含む文字列を生成します。
 ・include_plotlyjs
 　True（デフォルト）の場合、plotly.jsのソースコードがファイルに出力され、オフラインでも使用できます。ただしサイズが大きくなる（～3MB）。
 　cdnの場合、ウェブから読み込みます。サイズは小さくなりますが、インターネット接続が必要になります。

 詳細は公式githubを参照してください。

 https://plotly.github.io/plotly.py-docs/generated/plotly.io.write_html.html

 # Markdownへの埋め込み
 　それでは、出力したHTMLをMarkdownに埋め込みましょう。以下のように埋め込めば終わりです。

  ```markdown:埋め込み
  ### これはテスト

<iframe src="fig_output.html" width="600" height="600"></iframe>

```

はい、完成しました。お疲れ様です。
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3493004/251af3b7-b42f-719e-6430-072583a36b8b.png)

# おわりに
図の枠があるのはなんかダサい気がするので何とかならんかなと思いますが、ひとまずこれで許してください。

それでは次の記事でお会いしましょう。
EC2でk8s構築時に、Too Many Open Filesエラーの対応(忘備録)

# 前編
https://qiita.com/wk0012345/items/83385bd99d837bc79cdd

# 経緯
1. Fluent Bitを起動した後、開発者のための環境を増やしたときに、ログを収集するインスタンスが多くなり、一部のPODが起動してなかった
   ```
   ...エラー...
   2023/12/27 12:09:25 too many open files
   ...エラー...
   ```

# 対応
下記の二つのファイルを確認し、制限されている数値を増やすことで解決

1. max_user_watchesを確認
   ```
   $ cat /proc/sys/fs/inotify/max_user_watches
   ```


1.  max_user_instancesを確認

    ```
    $ cat /proc/sys/fs/inotify/max_user_instances
    ```
   
1. 自分の場合、二つのファイルの中で、`max_user_instances`が 128になっており、これを増やすことで問題解決した
   ```
   # 制限されている instanceの数を増やす
   $ sudo sysctl fs.inotify.max_user_instances=1024
   $ sudo sysctl -p
   ```

4. 永久適応する場合
   `/etc/sysctl.conf`で`fs.inotify.max_user_instances`を修正

   ## 例）
   ```
   $ cat  /etc/sysctl.conf
   # sysctl settings are defined through files in
   # /usr/lib/sysctl.d/, /run/sysctl.d/, and /etc/sysctl.d/.
   #
   # Vendors settings live in /usr/lib/sysctl.d/.
   # To override a whole file, create a new file with the same in
   # /etc/sysctl.d/ and put new settings there. To override
   # only specific settings, add a file with a lexically later
   # name in /etc/sysctl.d/ and put new settings there.
   #
   # For more information, see sysctl.conf(5) and sysctl.d(5).
   fs.inotify.max_user_watches=99524288
   fs.file-max = 992097152
   fs.inotify.max_user_instances=9999999
   $
   ```
Math.random()を使ってみた

# はじめに
`Math.random()`の基本的な使い方や活用方法などの基礎的な知識についてまとめました。

# Math.random()とは
`Math.random()`関数は、0 以上 1 未満 (0 は含むが、 1 は含まない) の範囲で
浮動小数点の擬似乱数を返してくれます。

例えば．．．
```JavaScript:Math.random()実行例
//0以上1未満の値の取得
console.log(Math.random());
//0.38639513326188446
```
このように`0.38639513326188446`という値を返してくれます。

ですが、`Math.random()`のみでは**0以上1未満**の範囲の乱数しか返してくれません。

そこで、、

***
### `Math.random()`に掛け算をしてみましょう。

`Math.random()`の値に掛け算をすることで、範囲の拡大をすることができます。
例えば..　**0以上10未満**の値を取得するには...
```JavaScript:Math.random()実行例
//0以上10未満の値の取得
console.log(Math.random() * 10);
// 1回目　7.4598107037841155
// 2回目　9.661357458837156
// 3回目　2.5801459117464254
```
これで、**0以上10未満**の値を返してくれるようになりました。
> `Math.random()`の値に掛け算をすることで、範囲の拡大をすることができます。

つまり、かける値により自由に乱数の範囲を拡大できるということになります。

ただ、長々と羅列された少数が気になりますね...

そこで、、
***

### 整数を取得するには`Math.floor()`を使ってみましょう。

`Math.floor`を使うことで、小数点以下を切り捨てることが可能になります。
では、先ほどの**0以上10未満**の値を取得していたコードに使ってみましょう。
```JavaScript:Math.random()実行例
//0以上10未満の値の取得
console.log(Math.floor(Math.random() * 10));
// 1回目　9
// 2回目　4
// 3回目　7
```
小数点以下を切り捨てることができました。

:::note warn
**10をかけても10は取得できない**
`Math.random`に×10をした場合
0.99999..にいくら10をかけても10にはならないので
`Math.floor`を使用しても整数の10を取得することはできません。
:::
:::note info
**知っておこう**
0～10の整数を取得する場合(**11をかける**)
console.log(Math.floor(Math.random() * **11**));
1～10の整数を取得する場合(**10をかけて+1する**)
console.log(Math.floor(Math.random() * **10** **+1**));
:::
***

## おまけ
**`Math.random`でさいころ**
```JavaScript:Math.random()実行例
//さいころの出目である1～6の値を取得
console.log(Math.floor(Math.random() * 6) + 1);
```

## おまけ２
**`Math.random`でチンチロ**
```JavaScript: コード
//1～6の整数を取得するコード3つを別々の変数に保存
let die1 = Math.floor(Math.random() * 6) + 1;
let die2 = Math.floor(Math.random() * 6) + 1;
let die3 = Math.floor(Math.random() * 6) + 1;
//tintiro()という関数に保存
function tintiro() {
   let die1 = Math.floor(Math.random() * 6) + 1;
   let die2 = Math.floor(Math.random() * 6) + 1;
   let die3 = Math.floor(Math.random() * 6) + 1;
}
//console.logで出目の結果を表示させる
function tintiro() {
   let die1 = Math.floor(Math.random() * 6) + 1;
   let die2 = Math.floor(Math.random() * 6) + 1;
   let die3 = Math.floor(Math.random() * 6) + 1;
   console.log(`(${die1} ,${die2}, ${die3})`);
}
```
### 実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3632613/f0ba67b9-b874-6127-73af-bc74e9a1c5d7.png "実行結果")
見事にピンゾロもでました^^
***





# 参考

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Math/random
***

# 終わりに
最後まで読んでいただきありがとうございました。
Google Cloud Professional Cloud Developer を取得しました

# Google Cloud Professional Cloud Developer を取得しました

2023/12 に Professional Cloud Developer 認定資格を取得したので、そのときの学習方法をまとめます。

https://cloud.google.com/learn/certification/cloud-developer?hl=ja

## 前提
Google Cloud 認定資格は、以下4つを取得済みです。

- Professional Cloud Architect
- Professional Data Engineer
- Professional Cloud Security Engineer
- Professional Cloud Network Engineer

https://qiita.com/ysmmb12/items/5327480781f28416685f

https://qiita.com/ysmmb12/items/a041a499106ad0df2754

https://qiita.com/ysmmb12/items/ef0031b2567c1a32f763

https://qiita.com/ysmmb12/items/fc9b2a71270822f2aebc

## 学習方法
### Coursera
資格対策用のコースが用意されています。

https://www.coursera.org/professional-certificates/google-cloud-developer

一つ目の `Google Cloud Fundamentals: Core Infrastructure` がすでに受講していたので、今回はそのほかのコースを受講しました。
`Application Development with Cloud Run` 以外は日本語のコースが用意されています。

### 模擬試験
公式が公開している模擬試験を受験しました。

また、Udemy の模擬問題集も解き、自信がない問題の解説は参考URL含め読み込みました。
実際の試験でこの模擬問題が出題されていた設問もあったので、ここに時間をかけてよかったです。

https://www.udemy.com/course/full-practice-exams-google-professional-cloud-developer/

### ドキュメント
前回もお世話になった  G-gen 様の試験対策ブログ記事を読み、自分の習熟度を確認しました。
記事内で紹介されている Google 公式ドキュメントや G-gen 様の技術記事も読みました。

https://blog.g-gen.co.jp/entry/professional-cloud-developer

## 受験
テストセンターで受験しました。
試験→アンケートのあと仮合格が表示され、次の日に正式な合格通知がきました。

## 受験した感想
難しかったですが、問題文は素直なので対策すれば合格する試験だと思います。
Google Cloud サービス特有の問題だけでなく、何かしらの開発経験があれば経験則で選択肢を絞れる問題もあったので、エンジニアが受けやすい試験だと思いました。

以上です。
どなたかの参考になれば幸いです。
React で複数行テキストを画面に表示する

Web フロントエンドを書いていたら誰もが一度は作る「改行文字を `<br/>` に変換するやつ (いわゆる nl2br)」を懲りずにまた再発明してしまったのでメモしておく。

``` typescript
import { createElement, type ReactNode } from 'react'

const nl2br = (text: string): ReactNode[] =>
  text
    .split('\n')
    .map((line, index) => [line, createElement('br', { key: index })])
    .flat()
    .slice(0, -1)
```

使い方

``` tsx
const text = "複数行の\nテキスト"

return <p>{nl2br(text)}</p>
```
Livebook でリアルタイムにCPU使用率・メモリ 使用量を表示する

## はじめに

機械学習系で重い処理を実行しているとき、明らかに画面が固まっていたり、マシンが激しくシューシュー音を立てだしたり、逆に全くの無音すぎたりで不安になることがある

そういう時は「ちゃんと動いているか」「CPUやメモリがパンパンになっていないか」を確認することになります

CLI なら `top` や `htop` コマンド、 GUI ならアクティブティモニタやタスクマネージャーを開くことで CPU 利用率とメモリ使用量が確認可能です

しかし、 Livebook で作業中であれば、いちいち別のウィンドウを開くよりも、もちろん Livebook の中でそのまま確認したいですよね

当然、リアルタイムに変化する様子を見たいです

実は Livebook だとそれができます

## セットアップ

KinoUtil をインストールします

https://github.com/mvkvc/kino_util

```elixir
Mix.install([
  {:kino_util, "~> 0.1.1"},
  {:nx, "~> 0.6"}
])
```

:::note info
Nx は手軽に負荷をかけるために使うので、 CPU使用率・メモリ使用量取得には不要です

https://github.com/elixir-nx/nx
:::

## スマートセルの追加

KinoUtil　をインストールしていると System utilization （システム使用量）のスマートセルが追加できます

![スクリーンショット 2023-12-28 10.56.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/7b20b20c-1b10-d30b-3efa-07b1e8829ef8.png)

追加すると以下のようにCPU使用率とメモリ使用量がグラフと数値で表示されます

![スクリーンショット 2023-12-28 10.57.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/b963120b-c662-2cdb-0a95-608c587353ba.png)

## CPU使用率・メモリ使用量のリアルタイム表示

System utilization のスマートセルでは、グラフと数値がリアルタイムに変化します

　負荷をかけるために以下の処理を実行しましょう

 ```elixir
Nx.dot(
  Nx.iota({250, 250}),
  Nx.iota({250, 250})
)
```

`250 * 250` のテンソル同士の内積を計算するため、それなりの負荷がかかります

CPU が 17 % まで増加した後、計算中は 10 %代をうろちょろしているのが分かります

![util.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/a6befe0a-67d4-f2b3-b63c-e1a64826c0bb.gif)

## まとめ

「実行時点の値を表示する」のではなく「リアルタイムに現在の値を表示する」ところが Livebook らしくて素敵ですね
【PHP/Slim4】２．軽量フレームワーク(Slim4-skeleton) GET/POSTアクセス設定

## やりたいこと
Slim4でのGET、POSTのアクセス制御を行いたい
ただそれだけだが、調べるのに時間がかかった記憶があるので、備忘録に残しておく


## Step1．サンプル環境の構築
[前回の記事を参照](https://qiita.com/miyaken3381/items/a63f70b65a01c8b77225)

## Step2．GET通信の設定
サンプル環境の初期設定は、GET通信でアクセスできるようになっている

#### app/routes.php
~~~php
    $app->group('/users', function (Group $group) {
        $group->get('', ListUsersAction::class);
        $group->get('/{id}', ViewUserAction::class);
    });
~~~

この例のURL（http://localhost/[プロジェクト名]/public/users/1 ）でアクセスすると、以下の実行結果が表示される
#### 実行結果
~~~html
{
    "statusCode": 200,
    "data": {
        "id": 1,
        "username": "bill.gates",
        "firstName": "Bill",
        "lastName": "Gates"
    }
}
~~~

## Step3．POST通信の設定
サンプル環境の初期設定を変更し、POST通信が行えるようにする
#### app/routes.php
~~~php
    $app->group('/users', function (Group $group) {
        $group->get('', ListUsersAction::class);
        $group->post('/[{id}]', ViewUserAction::class);
    });
~~~

#### src/Application/Actions/User/ViewUserAction.php
~~~php
protected function action(): Response
{
//  $userId = (int) $this->resolveArg('id');
    $userId = (int) $this->getArg('id');
        ：
}

private function getArg(string $key) {
	$retVal = null;
	// GET通信
	if (isset($this->args[$key])) {
		$retVal = $this->args[$key];
	}
	// POST通信
	else {
		$postForm = $this->getFormData();
		if (isset($postForm[$key])) {
			$retVal = $postForm[$key];
		}
	}
	return $retVal;
}
~~~

以下のようなHTMLを作成し、POST通信を行うとStep2と同様の結果が得られる
~~~html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link rel="icon" href="data:,">
</head>
<body>
<div>
	<H3>POST通信テスト</h3>
	<form action="http://localhost/[プロジェクト名]/public/users/" method="post"> 
		<input name="id" value="1">
		<input type="submit" value="post" />
	</form>
</div>
<body>
</html>
~~~

### 解説
1. routes.php：GET通信の場合はgroup->get()、POST通信の場合はgroup->post()を指定する
1. routes.php：（複数のパラメータ）GET通信の場合は、group->get('/test/{id}/{name}', xxxx::class)と{}で引数を増やす。
 1. routes.php：（複数のパラメータ）POST通信の場合は、group->get('/test[/{id}/{name}]', xxxx::class)と[]の中でGETと同様の引数を設定する。
 1. ViewUserAction.php：GET通信とPOST通信で渡された引数は、取得方法がことなるため、getArg()メソッドを追加し値の取得を共通化している。Baseクラスを作成/各Actionクラスで継承し、共通で使用するメソッドを定義して使いまわすのが良いと思われる
【JavScript】Objectの扱い方

# はじめに
プロパティへのアクセス方法が色々あって、あれ？ってなったので整理してみます。

# オブジェクトとは
Javascriptにおけるオブジェクトとは、プロパティの集まりである。
プロパティは名前（キー）と値との関連付けで成り立っている。
中括弧`{}`で定義することができる。

    var myCar = {
        make: "mini",
        model: "clubman"
        year: "1995",
    }

オブジェクトに割り当てられていないプロパティは`undefined`になる。nullではないので注意。（条件分岐でnullだけを指定していたらバグの温床になりそうですね。知らなかった。`undefined`と`null`の違いもよくわからんので後ほど調べますか。）
        
# プロパティへのアクセス方法
ドット演算子とブラケット記述法でアクセスできる。

    myCar.make    // mini
    myCar["make"] // mini

#### ドット演算子での注意点
プロパティ名に以下は指定できない。ブラケット記述法であれば指定可能。
- 空白
- 頭が数字

      myCar.1  // SyntaxError

#### ブラケット記述法の活用方法
プロパティ名を動的に決める場合に有効。

        const dayOfWeek = {
            0 : "月曜日"
            1 : "火曜日"
            2 : "水曜日"
        }
    
        dayOfWeek[0] // 月曜日

連想配列を扱うような感覚で使用することができますね。

# まとめ
簡単な内容ですが、オブジェクトの扱い方についてまとめてみました。
エンジニアになって約半年。なんとなくで実装してしまっている部分が多く、知識が曖昧な状態で放置してしまっているように感じています。
アウトプットを通して知識の深掘り・定着を行っていきたいと思います。

# 参考
https://developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Working_with_objects
AWS EC2でNode.jsを自動起動

# はじめに
Node.jsで作成したWebRTCのSignaling ServerをAWS EC2(Amazon Linux 2023)で自動実行する際に課題に直面しました。
その解決手順を以下にまとめました。
読んでいただいた方が少しでも参考になれば幸いです。

# こんな人に読んでほしい
- EC2＋Node.jsを使った環境を構築したい方
- AWSを学びたい方

# 前提条件
- EC2+Node.js環境が作成済であること

# やりたいこと
~~~php:Node.jsの手動実行の例
$ node signaling_server.js
~~~
これをEC2インスタンス起動時に自動実行する。

# EC2のユーザーデータ作成手順
①EC2インスタンスを停止する。

②EC2インスタンスから「アクション」-「インスタンスの設定」-「ユーザーデータを編集」を実行する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3659381/2283633d-e7f1-b235-bc6c-379bc35e7b04.png)

③下記画面からユーザーデータを入力する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3659381/65944b24-0401-f834-cbd6-f0433371dd6a.png)

# ユーザーデータ入力内容
ユーザーデータはデフォルトでは初回起動時のみ実行されるので、再起動時にも実行されるように以下のコマンドを入力します。
~~~
Content-Type: multipart/mixed; boundary="//"
MIME-Version: 1.0

--//
Content-Type: text/cloud-config; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="cloud-config.txt"

#cloud-config
cloud_final_modules:
- [scripts-user, always]

--//
Content-Type: text/x-shellscript; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="userdata.txt"

#!/bin/bash
ここにユーザーコマンドを記入
--//--
~~~

ユーザーコマンドは次の通りです。
~~~
runuser -l ec2-user -c "node /home/ec2-user/hogehoge/signaling_server.js"
~~~
これで、rootユーザーで実行されるユーザーデータがec2-userユーザーで実行されます。

# ご参考
この手順に進む前に、foreverを使用してNode.jsをデーモン化する方法も検討しました。
詳細は[foreverメモ](https://qiita.com/naga3/items/2b069bbf12087ba75bac)をご覧ください。
しかし、現在のNode.jsのバージョンにはforeverが対応していないようです。
Node.jsのバージョンを`v13.13.0`に下げるとエラーがなくなるようですが、現在のバージョンは次の通りです。
~~~
$ node --version
v20.10.0
~~~
このため、現状では諦めることにしました。
Livebook で通知音を鳴らす

## はじめに

　Livebook で大量のデータ解析など重い処理を実行しているとき、「ひたすら待つ時間」ができます

その間は大抵別のことをやっていて、時々 Livebook をチラ見しては状況を確認する、ということいなります

「視覚」だと意識的に「目」を向けないといけないので、意外と面倒です

少し席を離れている間にいつの間にかエラーが発生していて、ログは遥か彼方に過ぎ去っていたり、実行したことをすっかり忘れるなんてことも

そんなとき、「聴覚」なら意識せずとも「耳」に音が飛び込んでくるのですぐに反応できます

と言うわけで、 Livebook に通知音を追加します

実装したノートブックはこちら

https://github.com/RyoWakabayashi/elixir-learning/blob/main/livebooks/kino/kino_sound.livemd

## セットアップ

KinoSound をインストールします

https://github.com/einariii/kino_sound

```elixir
Mix.install([
  {:kino_sound, "~> 0.1.2"}
])
```

## スマートセルで音を確認する

KinoSound をインストールすると、 SmartSounds のスマートセルが追加できます

![スクリーンショット 2023-12-28 10.21.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/344e4801-9cea-2fc5-49c3-3d35f263fa51.png)

SmartSounds　のスマートセルでは、 KinoSound で鳴らすことができる音をボタンで確認できます

<iframe width="560" height="315" src="https://www.youtube.com/embed/zOzD546JC6g?si=2KPZyqMZYXkQBgX6" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>

## KinoSound の利用例

以下のようなコードを実行します

```elixir
IO.inspect("Start!!")

result =
  0..5
  |> Enum.reduce(:ok, fn _, acc ->
    Process.sleep(3000)
    IO.inspect("Hello!!")
    KinoSound.print()
    acc
  end)

case result do
  :ok ->
    KinoSound.success()
  _ ->
    KinoSound.error()
end
```

3秒待って `"Hello"` と出力するのを 6 回繰り返し、最後に実行結果（この例では `:ok` 固定ですが）を返します

「ループが 1 回終わったよ」と言う通知のために `KinoSound.print()` で音を鳴らし、最後に成功したかどうかも `KinoSound.success()` と `KinoSound.error()` を使ってお知らせします

<iframe width="560" height="315" src="https://www.youtube.com/embed/nb7XIUaa6FY?si=_Z0aYvbjYOT4_udi" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>

## まとめ

特に AI　のトレーニング中など、通知音を活かせる場面は多そうですね
jq：コマンドでJSONを操作する

# はじめに
APIなどを使用した際、データやログなどがJSON形式でやりとりされることが多いです。
JSONを整形したり抽出できるjqコマンドを紹介します。

# インストール方法
1. サイトからexeをダウンロードする
	* https://stedolan.github.io/jq/
1. exeファイル名を「jq.exe」にリネームする
1. exeファイルを任意のフォルダーに配置する
	* 例：`C:\Program Files\jq`
1. パスを通す
	1. 「Win」マークを押し検索窓に「Path」などと入力し、「システム環境変数の編集」をクリックする
	1. 「環境変数」をクリックする
	1. 「〇〇のユーザー環境変数」もしくは「システム環境変数」から「Path」を選択し、「編集」をクリックする
		* システム環境変数とユーザー環境変数の違いは以下
			* システム環境変数：PC上のユーザー全員に適応する
			* ユーザー環境変数：今ログイン中のユーザーのみに適応する

	1. 「新規」をクリックし、先ほど解凍したファイルのexeファイルが格納されているパスを記入し「OK」をクリックする
1. 環境設定が完了すれば、PowerShellなどでjqコマンドが使えるようになる

# コマンド例
* version確認
```console
jq -V
```

* ヘルプ
```console
jq --help
```

* curlコマンドにjqをパイプでつなげるだけで、整形されて出力される
```console
cat "ファイルのパス" | jq
```

* フィルターを使えば必要な情報を取得できる
```console
curl -s "ファイルのパス" | jq '.response.location[] | [.xxx, .xxx, .xxx]'
```

* 特定の要素を取得したい場合
```console
cat "ファイルのパス" | jq '.特定の要素名'
```

* マニュアルはこちら
	* [jq Manual (development version)](https://stedolan.github.io/jq/manual/)


# 参考にしたサイト
* [Windowsでjqコマンドを導入してJSONレスポンスを整形・抽出する](https://zenn.dev/unsoluble_sugar/articles/e47b37b04dd1153d5b29)
* [jqコマンドでJSONを操作・分析する](https://zenn.dev/oreo2990/articles/49a20a09517d90)
* [jqを使って少し複雑な条件式でフィルタリングする方法をまとめてみた - Qiita](https://qiita.com/ttiger55/items/150e9a18313a55841a32)
【AWS】VPCエンドポイントについて


## 【背景】

普通の人は当たり前に理解して、使用しているVPCエンドポイントについて、
私は、「エンドポイントってなんのエンドやねん」とあほみたいな詰まり方をしてしまったので、調べた内容を記載する。

:::note info
※あくまで用語理解のためのメモです。
　設定方法には触れてません。
:::

## 【VPCとは】

AWSのVirtual Private Cloud（VPC）は、クラウド内でユーザー定義の仮想ネットワークを提供するサービスである。

VPCを利用することで、AWSリソースを自分の仮想ネットワークに配置し、IPアドレス範囲の選択、サブネットの作成、ルートテーブルやネットワークゲートウェイの設定が可能となる。

これにより、セキュリティや接続性の高いネットワーク環境が構築できる。VPCは、クラウド上のプライベートなセグメントを作成し、安全なクラウドコンピューティング環境を提供するために重要な役割を果たす。

## 【VPCエンドポイントとは】


VPCエンドポイントとは、AWS固有の用語で、VPC内のリソースがAWSサービスやVPC外のサービスにプライベートに接続するための方法を提供するものである。

VPCエンドポイントを利用することで、VPC内のリソースは、パブリックなネットワークを経由せずにAWSのサービスにアクセスすることができる。

これにより、セキュリティが強化され、ネットワークトラフィックがAWSのプライベートネットワーク内に留まるため、安全性と効率性が向上するというサービスである。

## 【エンドポイントってなんのエンドなポイントなの？】


エンドポイントとは、なんの終着点を指しているのだろうか？

VPCはリージョン単位で閉じたネットワークを構築するもので、その中にES2やS3を構築する。

何も設定しなかった場合、ネットワーク接続の仕組みとして、AWSの外にアドレスを確認するために接続することになる。

**＜何も設定しなかった場合＞**

｛ EC2 => AWS ｝ => public network => domain名確認 => public network => ｛ AWS => S3 ｝
※｛AWSのネットワーク内｝

```
1. EC2からのリクエスト
	 VPC内のEC2インスタンスからS3サービスへのリクエストが発生する。

2. AWSの外部ネットワークへ
 	このリクエストは、最初にAWSの内部ネットワークを経て、
 	その後公共のインターネットにルーティングされる。

3. ドメイン名の解決
 	リクエストは、DNS（ドメインネームシステム）によって、対応するサービスの実際の
 	IPアドレスに解決される。
 	このプロセスでは通常、インターネット上のDNSサービスが利用される。

4. 公共のインターネットを経由
 	DNSによって解決されたアドレスに基づき、リクエストは再度公共のインターネットを
 	通じてAWSのインフラストラクチャに送信される。

5. AWSサービス（S3）へのアクセス
 	公共のインターネットを経由した後、リクエストは最終的にAmazon S3に到達する。

6. レスポンスの受信
 	EC2インスタンスは同じ経路を通じてS3からのレスポンスを受け取る。
```

しかし、VPCエンドポイントを作成することでAWS内部のみで通信を行う事が可能となる。

**＜VPCエンドポイントを作成した場合＞**

｛ EC2 => VPC endpoint => S3 ｝
※｛AWSのネットワーク内｝

```
1. EC2からのリクエスト
	VPC内のEC2インスタンスがデータをAmazon S3に送信するリクエストを生成する。

2. VPCエンドポイントへのルーティング
	このリクエストは、VPC内に設定されたVPCエンドポイント
	（例えばS3へのVPCエンドポイント）に直接ルーティングされる。

3. S3へのアクセス
	VPCエンドポイントを通じて、リクエストはプライベートかつセキュアに
	Amazon S3へ転送される。
```

このようにVPCエンドポイントは、VPC内のネットワークの終着点となり、VPC内のAWSサービスに接続する際の折り返し地点というイメージになる。

そのため、
**VPCの内側から見た時の”エンドなポイント”**
ということになる。
Github CopilotでiOS / Androidの開発を行うまとめ

# github copilopとは
copilotとは、pilotを補佐するcopilotです。副操縦士という位置づけですね

## 　ChatGptとの関係は？
copilotのAI部分は、ChatGPTです。copilotの役目は言語解析がメインのChatGPTに対して作業をフォローするように振る舞う部分です。開発においては、プロジェクト全体をchatGPTのinputとしてすでに渡してくれているようなイメージですかね

# iOS / Androidの開発で利用できる
copilotはMicrosoftの製品ということもあってMicrosoft製品にはいち早く取り込まれてきています。とくに[VS Code](https://azure.microsoft.com/ja-jp/products/visual-studio-code)では、使いやすくなっています。

## iOSでの利用方法
Microsoft公式にリリースはありません（２０２３/12/28現在）
なので以下の***Copilot for Xcode***を使います。

https://github.com/intitni/CopilotForXcode/tags

２週間に１度程度、tagが更新されているので確認を。（0.28.3を利用）
ちなみにライセンスはGPLv3

### Homebrew 経由でインストール
色々記事がありますが、brewを使ったほうが色々依存関係も見てくれるので良いです。

``` shell
brew install --cask copilot-for-xcode
```
Copilot for Xcodeというアプリがインストールされます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84965/5dfa5390-7fa4-cb61-4dd5-f79500b6451a.png)

### Githubとの連携設定
以下の記事を参考に設定してください。使い方も参考になるかとおもいます。
※githubのアカウントでcopilotを使えることが前提です

https://qiita.com/SNQ-2001/items/3777c50e8c3a1aa894f0

ポイントは、
「設定」の「プライバシーとセキュリティ」ー「拡張機能」にXcode for copilotの項目があります

## Androidでの利用方法
Androidは、Pluginsに検索すると出てきます。それをインストールするだけです。
※githubのアカウントでcopilotを使えることが前提です

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84965/c895b3ae-55fe-a418-c289-c9bf255af97b.png)

### github Copilotの設定
pluginをインストール後、IDEの再起動を促されるので再起動します。初回起動時のWelcomeメッセージが表示されます。
「Sign in to GitHub」のリンクをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84965/2b8c4c41-7a9d-9f65-7ac2-665553b6ca6c.png)


:::note alert
GitHub Copilotのライセンスがない場合は、エラーとなります。
<img width="500" align="right" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84965/05f0e490-841e-2e61-33f7-127ac6fde922.png">
:::



android studioにGitHubにSign inするときの情報が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84965/0c85c070-a026-3f45-b872-4ec10605e1c4.png)

「Copy and Open」ボタンでをクリックすると、GitHub websiteを開き、Device codeの入力画面が表示されるので、貼り付けます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84965/9b6d038a-7bb3-df1c-6d14-66b3564fa30a.png)

「Authorize GitHub Copilot Plugin」のボタンをクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84965/773cd492-e0d4-129c-719f-261e2c52cf49.png)

Congratulations, you're all set!
と表示されればOKです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84965/97c6ac7d-0f67-6b14-9187-3dd9439f5f0a.png)
Adobe MAX Japan 2023 に参加してきたのでレポート

## はじめに
こんにちは、日本リック エンジニア採用チームです。

今回は、現在Webデザインを勉強中の女性テストエンジニアのAさんが、11月16日に開催された Adobe MAX Japan 2023 に参加してきましたのでレポートしてもらいました。


## Adobe MAX Japanとは
![IMG_2503_q.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1545301/89f20f4d-202b-0839-d1ae-87ee2cbe5d80.jpeg)

以下、公式ページからの引用です。

> Adobe MAX Japanはグラフィックデザイン、写真、Web制作、UI/UXデザイン、映像制作、3D制作などに携わるクリエイターの方、およびそれらを目指す方が楽しめる「クリエイターの祭典」。
> 
> クリエイティブのトレンド、第一線で活躍するクリエイターのアイデアやテクニック、Adobe Creative Cloudの最新機能やワークフロー、クリエイターの方々と交流してインスピレーションを得ることができる日本最大級のクリエイティブイベントです。

## Adobe MAX Japanに参加して・・・
私は学生時代に Photoshop や Illustrator を使用しており今でもたまーに使用していたのですが、知っている機能しか使用しておらず・・・

今回参加して機能がとんでもなく進化していることに驚きの連続でした。

気になった機能を中心に振り返ります！

## 生成AI
何かと話題の生成AIですが、Adobeではお馴染みの制作ツールを補完する形で[Adobe Firefly](https://www.adobe.com/jp/products/firefly.html)という生成AIアプリケーションの機能を使用して、プロンプトからテキストを入力して画像やオブジェクトの追加や削除、テキストの変形などを生成することができます。

例えば Photoshop で写真を編集する際、変に見切れてしまった背景などを生成AIが予測して描き足すことができちゃいます！

今までサイズの変更などで伸ばしたい場合、言うのは簡単ですが実際にやるとなると結構面倒でした。

しかし、生成AIだとパッと簡単にできてしまうのです！便利ですね。

画像生成の精度については他のAIと同様、テキストを具体的に書くほど精度が増します。

また、Fireflyは商用利用も可能です。ですが、生成AIは法整備がまだ整っていない分野になるので注意が必要そうです。

## その他、気になった機能
簡単に気になったものをまとめてみました。

### Illustrator
* 生成再配色
  * 生成AI。プロンプトから配色
  * いろんなパターンを見ることができて便利
* Retype
  * アウトライン化(図形化)されたテキストを編集可能なテキストに戻す

### Adobe Express
* 簡単に画像編集ができる
* 商用利用OKの素材・テンプレート
    * SNS用・印刷物用など
* 非デザイナーにオススメ
    * 非デザイナーとデザイナーで共同編集できる
    * 制作物にピン留めでコメントができる
* 無料プランあり

下記アーカイブの一部セッションやキーノートなどで詳しく解説されています。

* [Adobe MAX japan 2023　アーカイブ](https://www.youtube.com/playlist?list=PLF_lcvNhVWn_rDK1VP4wsSZIMIa3pGZjD)


## 実際に参加してみた感想
普段の業務では中々関われないデザインについての話を聞くことができて良かったです。

展示会場ではクリエイターさんたちがオリジナルグッズを展示・販売していて、私も久々に作ってみようかなと創作意欲を刺激されました。

また、今回はメインセッションを中心に聞いていたのですが展示会場ではサブセッションも行われており、そちらも聴いてみたかったです・・・

次回も機会があればぜひ参加したいと思います！
なんちゃってバイオインフォマティクス

## バイオインフォマティクスっぽいことをしてみる

誰か、pythonを使って、バイオインフォマティクスを説明している人がいないかなと思って、いろいろ調べてみましたが、実際に分析などを載せておられる方はいないものの、オープンデータをダウンロードしてこういう準備をするといいでしょう、というようなごく入門的、入門以前の情報を載せておられる方はいます。

情報量が大きいので、扱いが難しいですが、研究者向けにデータを提供しているサイトがあるので記しておきます。

ensembl.org というヨーロッパのサイトです。
英語で書いてあるので、wikipedia を読んでもよくわかりませんでしたが、日本からアクセスすると、https://asia.ensembl.org に飛ばされるので、世界的に結構有名なサイトであるような気がします。

例示に示したファイルは、
gz で 840MBぐらいあり、
解凍すると、3.3GBくらいあるので、普通のテキストエディタでは開けません。
それなりのツール選びが必要になってくると思います。

gzで11MB程度の者もあります。
ヒトゲノムのある部分的な部分のものであると予想されます。

chatGPTに要約させると、

Ensemblゲノムデータベースプロジェクトは、生命科学研究者や遺伝学者向けの重要なリソースとして知られています。Ensemblは、遺伝子、ゲノム構造、およびその他の生物学的データを包括的に収集し、それを使いやすい形式で提供することを目的としています。

とのことです。

ftp://ftp.ensembl.org/pub/ の覗くと、いろいろデータが置いてあるので、いろいろ試すのにはいいと思います。

```bash:データのダウンロード
 curl -O ftp://ftp.ensembl.org/pub/current_fasta/homo_sapiens/dna/Homo_sapiens.GRCh38.dna.toplevel.fa.gz
```
pythonで、ある特定の行を読みだすスクリプトを書いてみました。

python3 loadLine.py 400000

などと、引数をつけて実行するとその該当の行が表示されるというものです。
実用的ではありませんが、ファイルサイズの大きいデータを見るのに、少しばかり使えるのではないかと思います。

```python:loadLine.py
#!/usr/bin/python3

import sys


def main() -> None:

    args = sys.argv

    path = 'Homo_sapiens.txt'

    with open(path) as f:
        i = 0
        while i < int(args[1]):
            a = f.readline()
            i += 1

        b = f.readline()
        print(b)


if __name__ == '__main__':
    main()
```

```bash:実行
python3 loadLine.py 400000
```