OmniAICreator/Qiita-1.07M huggingface dataset:
Androidの有料アプリを無料でクローズドテストしてもらう方法


# はじめに

初めまして、ココナラでアンドロイドのクローズドテスターをしているもっとPythonです。
個人でアンドロイドアプリをリリースする条件が厳しくなり、対策として以下の「クローズドテストをお手伝い」する商品を出品しています。

https://coconala.com/services/3123009?ref=blog

https://www.lancers.jp/menu/detail/1275674


これまで、多くの方に発注していただき、非常にありがたく思っております。
おかげさまで、テスト・検証・デバッグ部門のランキングで１位になることができました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3611982/ce50f4f4-bca5-6318-5272-27429f686b94.png)

さて、今回のテーマは、有料アプリを無料でクローズドテストしてもらう方法になります。

プレイストアは仕様上、有料アプリの開発をクローズドテストする場合、なんと、テスターのプレイストア上で料金請求が発生するという仕様になっています。

友達２０人にクローズドテストを依頼して手伝ってもらっているのに、アプリ料金の請求までするのは、心苦しいものがあります。

今回の記事では、無料でオプトインしてもらう抜け道の紹介になります。

# キャンペーンを利用する

クローズドテストは、本番と同じ環境を特定のユーザーに先行して公開するという特性から、値下げなどの設定も引き継ぐことができます。

そこで、その性質を利用して、無料キャンペーンをクローズドテスト期間に設定することで、料金を支払うことなく、テストを実施することができます。

以下がキャンペーンの設定方法です。

まず、左メニューから商品＞アプリの価格設定をクリックし、販売を押します。

![スクリーンショット 2024-03-31 16.40.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3611982/5d83fe6d-f591-5491-1427-69a35338fae8.png)

次にセールを作成をクリックして、キャンペーンを作成していきます。

![スクリーンショット 2024-03-31 16.40.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3611982/e4682c2a-53f3-872d-53cd-1632201b7c59.png)


セール名は適当に設定して、セール期間は当日を含められないので、翌日から最大で１週間設定することができます。

最後に価格を０円に設定して反映させます。

![スクリーンショット 2024-03-31 16.41.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3611982/af7dd98c-2949-b5ab-3475-be1b62cf59b5.png)


以上で、翌日から無料でオプトインを開始することができます。


# キャンペーンを利用できない場合

キャンペーンは一度設定すると、一ヶ月設定ができないようなので、キャンペーン実施済みで、どうしてもクローズドテストを実施したい場合は以下の二つの方法が考えられます。

1. アプリの設定価格を最低にする
2. 一旦購入してもらい、返金する

設定方法は、価格を設定＞価格を編集をクリック

![スクリーンショット 2024-03-31 16.46.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3611982/32bb78d5-af63-4953-2739-20d8fbb65e2d.png)

次にアプリの価格を最低金額の７円に変更し、反映します。

![スクリーンショット 2024-03-31 16.47.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3611982/5e53fd4b-9402-aa92-f1aa-49153aa6bb67.png)

払戻は、注文管理から、購入情報をクリックして、払戻ボタンをクリックすることで対応できると思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3611982/d08059b0-6c97-774a-d79f-1440a9d5fb9f.png)


# さいごに

以上、Androidの有料アプリを無料でクローズドテストしてもらう方法を紹介しました。


他にも参考になりそうな記事がありますので、是非一読ください。

https://over-field.com/engineer/771

https://note.com/gomorepython/n/ndb41cef70d95

https://zenn.dev/gomorepython/articles/8dc82b39a13991


### お仕事の依頼は以下から

クローズドテストが初めての方はこちらから

https://coconala.com/blogs/1237592/409101

ココナラで依頼したい方はこちら

https://coconala.com/services/3123009

ランサーズで依頼されたい方はこちら

https://www.lancers.jp/menu/detail/1275674
Chrome Extension Manifest V3 での各機能の役割

最近社内でChrome拡張つくる人が増えたので、Chrome Extension Manifest V3での各機能の役割についてまとめておきます

## 1. Service Worker
- マニフェストで `service_worker` で指定する必要がある
- 拡張機能の中心的なイベントハンドラ
- マニフェストに記述して登録する必要がある
- 必要に応じて実行され、アイドル状態になるとアンロードされる
- 常時実行させることはできない (MV2ではできた)
- Service Workerが破棄されるとグローバル変数は失われるので、`storage`に保存するなどの対応が必要

## 2. コンテンツスクリプト
- マニフェストで `content_scripts` で指定する必要がある
- ウェブページのコンテキストで実行される
- ページのDOM要素を読み取り、変更することもできる
- 静的宣言(マニフェストに記述)、動的宣言(chrome.scripting APIでスクリプトの登録)、プログラムによる挿入(chrome.scripting.executeScript()でJSの挿入)の3つの方法でコンテンツスクリプトを挿入できる

## 3. ポップアップ
- マニフェストで `action` で指定する必要がある
- ユーザーが拡張機能を呼び出せるウィンドウ
- キーボードショートカットまたは拡張機能アイコンのクリックでトリガーされる

## 4. オプションページ
- マニフェストで `options_ui` で指定する必要がある
- 拡張機能をカスタマイズするためのページ

## 5. offscreen
- MV3で追加された
- マニフェストで `offscreen` 権限を宣言する必要がある
- MV3ではService Worker でDOMアクセスができないため、DOM APIを使う必要がある場合などに利用する
- [offscreenの用途](https://developer.chrome.com/docs/extensions/reference/api/offscreen?hl=ja#type-Reason)
- 使用時に`offscreen`を作成し、処理が終わったら破棄する必要がある
- 存在して良い`offscreen`は常に1つだけ
	- すでに`offscreen`が生成されているとエラー
	- 前回の`offscreen`が破棄されていないとエラー
	- `Failed to create offscreen document: Error: Only a single offscreen document may be created.`
- 処理が完了したら破棄しなければならないのでデバッグが難しい

## 6. Storage
- マニフェストで `storage` 権限を宣言する必要がある
- ブラウザ間で同期する`sync`ストレージ、同期を行わない`local`ストレージがある
- syncストレージ
	- ストレージへの保存上限は100KB
	- 各項目のサイズ上限は8,192Byte
	- 1時間に1800回以上書き込みが行われるとエラー
	- 1分間に120回以上書き込みが行われるとエラー
	- 書き換え頻度が低く、データ量が少ない場合は`sync`ストレージがオススメ
- localストレージ
	- ストレージへの保管上限は10MB (`unlimitedStorage`権限を宣言すれば無制限)
	- 書き換え頻度が高かったり、データ量が大きい場合は`local`ストレージがオススメ
【転職】未経験からエンジニアへ（後編）

# はじめに
前回の記事から1年以上が空いてしまいました…
内定を頂いた会社で異動があり今はエンジニアではなくなったのですが、もう一度勉強して知識を身に付けたいと思い2年ぶり?位に勉強を始めようと思っています。
この記事は当時の書きかけのものを整理がてら記録します。

前回の記事で私のスペックや就職活動などがどのようにして進められたかをお話しさせていただきました。
今回の記事では、面接で聞かれた質問や使ってきた求人媒体、就職活動の注意点などをお話していこうと思います。

## 目次
1. 利用した求人媒体
2. 面接質問集
3. 未経験転職で注意すること
4. おわりに

## 1. 利用した求人媒体
まず最初に利用した求人媒体をお話ししていこうと思います。
私が利用した求人媒体は以下の通りです。

* Wantedly
* エン転職
* Green
* リクルートエージェント
* doda
* キャリトレ

その中でも未経験におすすめなのは**Wantedly**です。
IT業界の求人媒体でおすすめと言われているWantedlyですが、実際使ってみて使い易いと感じました。
同じくIT業界の求人でよくおすすめされているGreenは、未経験では難しいと個人的には感じました。

私が面接まで進んだ求人媒体は**Wantedly**で2社と**エン転職**で1社です。


## 2. 面接質問集
次は私が面接で聞かれた質問をまとめました。
少しでも参考にして頂けると嬉しいです。

* 自己紹介
* なぜエンジニアになろうと思ったのか
* 退職理由
* 自分の長所はどんなところだと思う？
* どんなキャリアプランを描いている？3年、5年、10年後〜40年、50年後、最終的にはどうなっていたい？
* 今の自分のどんなところが会社で活かせると思う？
* お客さまと関わったりする機会があるるけど上手くやっていける？なんでそう思うの？
* プログラミングやってみてどう思った？
* 人生の成功体験
* 苦手な人はどんな人？
* ポートフォリオの説明して
* コードの説明して
* コード書く時に気をつけたことを教えて
* ○○と△△の使い分けって何か分かる？分からないなら勘でもいいから答えてみて？なんでそう思うの？
* プログラミングを仕事にするっていうことはどういうことだと思う？


## 3. 未経験転職で注意すること
3の記事はこの記事を作成していた当時の私ではなく、未来の私から伝えようと思います。
未経験転職で注意する事は、「本当にエンジニアになりたいのか?その覚悟が自分にあるのか問う」ということです。
実際未経験でエンジニアに転職した会社の仲間には覚悟が足りなかったと言って辞めていく人も多くいます。“リモートワーク”　“年収1,000万円”　これらの言葉に目が眩んで憧れる人も多くいるでしょう。実際そう簡単に叶えられるということはありません。リモートに関してはSESだとどうしてもプロジェクト先によりますし、年収も自分の技術力が上がらなければ叶えられません。エンジニアは一生勉強していく覚悟がある人、常に新しい情報を追い続けられる自走力がなければ本当に厳しい世界です。そこをよく考え、それでも自分はエンジニアになりたいという人しか続けられない世界です。

## 4. おわりに
拙い文章でしたが、ここまで読んでいただきありがとうございました。
これをみてくださった方の転職活動が上手くいくように祈っております。
Elixirの匿名関数再帰によるFizzBuzz

# Elixirの匿名関数再帰によるFizzBuzz

kazuho氏のFizzBuzzの実装例（JavaScript）[^1]を目標として、Elixirで再帰的な関数の定義を使って実現できないか試行錯誤してみた。下記が自分の実力の限界だと思った。Elixirの匿名関数はモジュール関数をオーバーロードできないという理由はある。

アリティの異なる `iterate` 関数のうち、`iterate/0` はスタート用。iexから、`FizzBuzz.iterate` とするとFizzBuzzが開始される。`@max_number` によるガード節で終了条件を決めてあり、再帰が終了する。再帰を行うのは、`iterate({n, fizz, buzz, out})` で、CRCパターンによるパイプラインの最後に自分自身 `iterate` を呼び出す。

パイプラインの中の `tap/2` は、CRCパターンで使いやすい。引き継いだデータを次のステップにそのまま渡すことができる。`tap/2` の引数の2番目に匿名関数を取り、ログ出力などに使うと便利ということで使ってみている。

`next/1`は、パターンマッチによる条件分岐。 `:fizz` という atom に対して匿名関数を `fizz/0` より返し、`:buzz` という atom に対して匿名関数を `buzz/0` より返す。匿名関数は階層化して定義されている。ドット記法 `.()` によって一段階中の関数を返す。最後の中身は `:fizz` または `:buzz` となる。 `next/1` に関数の中心となる atom が渡された時には、再度匿名関数が `fizz/0` と `buzz/0` によって初期化される。意図としては再帰。


```elixir
defmodule FizzBuzz do
  @max_number 100

  def iterate(), do: iterate({1, fizz(), buzz(), ""})

  def iterate({n, fizz, buzz, out}) when n <= @max_number do
    {n, fizz, buzz, out}
    |> tap(&print/1)
    |> next()
    |> iterate()
  end
  def iterate({n, _, _, _}) when n > @max_number, do: :end

  def fizz, do: fn -> fn -> :fizz end end
  def buzz, do: fn -> fn -> fn -> fn -> :buzz end end end end

  def next({n, :fizz, :buzz,  _}), do: {n + 1, fizz(),  buzz() , "FizzBuzz"}
  def next({n, :fizz,  buzz,  _}), do: {n + 1, fizz(),  buzz.(), "Fizz"}
  def next({n,  fizz, :buzz,  _}), do: {n + 1, fizz.(), buzz() , "Buzz"}
  def next({n,  fizz,  buzz , _}), do: {n + 1, fizz.(), buzz.(), "#{n}"}

  def print({_n, _fizz, _buzz, out}), do: IO.puts( out )
end
```

[^1]: https://gist.github.com/kazuho/3300555
Railsチュートリアルのメールプレビューを見やすくした(gem letter_opener_web)


こんにちは！学びと成長しくみデザイン研究所の斉藤です。
Railsチュートリアルの第14章が終わった段階の[リポジトリ](https://github.com/yasslab/sample_apps/tree/main/7_0/ch14)をベースにして、[letter_opener_web](https://github.com/fgrehm/letter_opener_web) を導入します。
letter_opener_web を導入することで、使い勝手の悪いデフォルトのメールプレビュー画面が改善できます。

# プレビュー画面(Before => After)

## Before

![1](https://raw.githubusercontent.com/SaitoJP/engineer_nootebook/main/images/202403/20240331_001.png)

## After

![2](https://raw.githubusercontent.com/SaitoJP/engineer_nootebook/main/images/202403/20240331_002.png)

- メリット
    - URLが `http://localhost:3000/letter_opener` でシンプルでわかりやすい
    - 複数のメールプレビューを確認できる


# 導入手順

gem追加
```ruby:Gemfile
group :development do
  gem 'letter_opener_web', '2.0.0' # <= 追加
  gem "web-console",         "4.2.0"
  gem "solargraph",          "0.50.0"
  gem "irb",                 "1.10.0"
  gem "repl_type_completor", "0.1.2"
end
```

`config/routes.rb` にmount
```ruby:routes.rb
Rails.application.routes.draw do
  mount LetterOpenerWeb::Engine, at: '/letter_opener' if Rails.env.development?

# 〜 以下省略 〜
```

`config/environments/development.rb` に設定追加
```ruby:development.rb
# 以下3行はすでに記載されている設定
host = 'localhost:3000'
config.action_mailer.default_url_options = { host:, protocol: 'http' }
config.action_mailer.perform_caching = false

config.action_mailer.delivery_method = :letter_opener_web # <= 追加
```
MobaXtermのSSHポートフォワードでRDPしてみる

今回はSSHポートフォワーディングのローカルフォワードを利用して、KVMのWindowsにリモートデスクトップ接続をしてみたいと思います。

下部図1が接続イメージになります。

図1
![プレゼンテーション1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1066166/6451b425-442e-a553-70dc-7111c266006c.png)

# 環境情報
**システム構成**
| デバイス | OS | IPアドレス |
| ---- | ---- | ---- |
| クライントPC | Windows 10 | 192.168.24.127 |
| ホストサーバ | RHEL8.9 | 192.168.24.21 |
| KVM | Windows 11 | 192.168.122.243 |

**利用ツール**
* MobaXterm v24.0

ここではMobaXtermのインストール方法は割愛します。

# MobaXtermの設定

### 1. 以下のアイコンをクリックしてMobaXtermを起動してください。
![スクリーンショット 2024-03-31 144140.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1066166/d7d36f36-9e84-1c0b-6099-c4fd973d809e.png)

### 2. Tunnelingをクリック
![スクリーンショット 2024-03-31 144345.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1066166/132d665b-3bcc-b6f4-14a6-2724fd50fc7a.png)

### 3. New SSH tunnelをクリック
![スクリーンショット 2024-03-31 150947.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1066166/6d5994da-3a53-aaa1-545d-3630208b539a.png)

### 4. SSHトンネリング設定
![スクリーンショット 2024-03-31 151226.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1066166/410ab406-5424-ff8d-637e-e55860ca5699.png)
   
### 5. Startボタンをおしてトンネリングを開始
![スクリーンショット 2024-03-31 153749.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1066166/bf3df2f0-069e-15a8-74af-5a775a5e581e.png)

### 6. ホストサーバのパスワードを入力
![スクリーンショット 2024-03-31 160437.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1066166/02c76f97-0231-bb4e-3d18-966eece9a069.png)

# MobaXtermでリモートデスクトップ
### 1. Sessionをクリック
![スクリーンショット 2024-03-31 163752.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1066166/6884aab8-53bf-04cf-224c-a6ab62f1984d.png)

### 2. RDPを選択し以下のように入力
![スクリーンショット 2024-03-31 163903.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1066166/0753a87f-7070-8cc3-1481-32147004ccf2.png)

### 3. リモート先のパスワードを入力
![スクリーンショット 2024-03-31 163936.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1066166/95852e36-d121-0cc4-f4f3-60f6c13c2d6c.png)

### 4. 以下のようにデスクトップ画面が表示されれば成功
![スクリーンショット 2024-03-31 165157.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1066166/566a8277-cf38-532a-cae5-1803972c8a10.png)

# Windows標準のリモートデスクトップを利用する場合
### 1. リモートデスクトップ接続を起動して以下のように入力
![スクリーンショット 2024-03-31 160928.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1066166/f8c31cb7-7bae-4078-9a15-b4cc8997c5d4.png)

### 2. 接続をクリック
![スクリーンショット 2024-03-31 161222.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1066166/ef4e646f-05a2-fb55-b47f-fa20844c6499.png)

### 3. はいをクリック
![スクリーンショット 2024-03-31 161244.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1066166/625a80cd-c982-9ada-0c12-ff27021451e5.png)

### 4. デスクトップ画面が表示されればRDPは成功
![スクリーンショット 2024-03-31 161321.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1066166/d39c3108-89d5-e695-673d-51936bd6a09b.png)
[小ネタ] AWS SAM を使わない方がいいかもしれないケース3選

## はじめに
AWS SAM 便利ですよねー.
テンプレートの記述量も少なく最小限の記述で、API Gateway + Lambda + DynamoDBといったようなサーバレスアーキテクチャを構築できるので私もサーバレスアーキテクチャを検証したい際には手軽に作れておすすめしたいです。

しかし、いざ使ってみるといかのケースでは、合わなかったりとユースケースを間違えると手戻りなどが発生するため、今回はStack を使ってみてイマイチだったケースを3つ紹介します。


## [ケースその１] バージョン指定の問題について
SAMを利用している際、バージョンやエイリアスを設定するには[AutoPublishAlias](https://docs.aws.amazon.com/ja_jp/serverless-application-model/latest/developerguide/sam-specification-generated-resources-function.html#sam-specification-generated-resources-function-autopublishalias)が設定されている必要があります。


しかし、だからといってバージョン管理できるるかっていったらそういうわけでもなく、AWS::Lambda::AliasとAWS::Lambda::Versionが作成されるだけになります。

これの何が問題かと言うと、以前上げた記事↓を見ていただければ幸いですが、
スタックが更新する度に「**新しいAWS::Lambda::Versionを作成 → Lambdaのエイリアスに最新バージョンを更新する → 古いAWS::Lambda::Versionを削除**」といった挙動になるのでバージョン管理できないってことなんですよね。

https://qiita.com/atw0_0w/items/1fd41907e54db0f1aef7

対処方だと、更新前に手動でバージョンを発行するとかですかね。
スタックで管理されていないバージョンをポイントごとで作成していざ問題があったら1つ前のバージョンに戻すとかはありかと。

まぁ、SAMで管理していた旧バージョンの保持方法も↑の記事でまとめてますので、よろしければ見ていただければ幸いですm(_ _)m



## [ケースその2] 複数ステージでアプリケーションを管理したい場合
[StageName](https://docs.aws.amazon.com/ja_jp/serverless-application-model/latest/developerguide/sam-resource-api.html#sam-api-stagename)も一つしか定義できないため、APIバージョン v1・v2 ... など、1つのAPIゲートウェイで複数ステージを管理するといったことも私が調べた限りではできないものとかんがえます。

もし、無理やりやる方法わかる方いましたらご教授お願いします。。m(_ _)m

また、API デプロイIDもその１と同様に新しいデプロイメントを生成 → 古いデプロイメントを削除といったこともあるのでデプロイIDのバージョン管理もできないので、1つ前に戻すといったこともできません。

## [ケースその3] 細かい設定をする場合
やはり、AWS SAMの1番の特徴は、Cloudformation などの定義を抽象化したことで、テンプレートへの記述量を最小限に、サーバレスアーキテクチャを構築することができる点だと思います。

これは、抽象化したもの全般に言えることではあるのですが、細かい設定を施すとどうしても記述量が多くなってしまったり追加のリソースなど細かくかつ独自で作るリソース数が増えていくと管理しにくくなっていくものかと思います。

したがって、アーキテクチャがシンプルな場合はAWS SAMを使って、運用方針が決まっていて細かく正確に作りたいとなるとCloudFormationで1つ1つちまちま作成していく必要があるのかなと思います。


## 終わりに
今回はAWS SAMを使わない方がいいケースを紹介しました。
一番いいケースとしては、完成系がどのようになるのか、運用どうするのか、スタックの更新頻度どれくらいになるのかといった内容についてヒアリングしたのち、ツールを選定いただければと思います。
Goのmapのキーの使用方法メモ

## 内容
Go言語のmapのキーの使用方法の確認

## mapの特徴
`map`はGo言語における非常に便利なデータ構造の一つで、他のプログラミング言語では辞書（Dictionary）、連想配列（Associative Array）、ハッシュ（Hash）などと呼ばれることがあります。`map`はキーと値のペアを格納するためのコレクションです。キーは一意でなければならず、各キーは一つの値にマッピングされます。これにより、キーを使用して迅速に値を検索、挿入、または削除することができます。

### mapのメリット

- **高速な検索**: `map`の主なメリットは、キーに基づくデータの検索が非常に高速であることです。キーを使用して値を直接参照できるため、大量のデータの中からも迅速に特定の要素を見つけ出すことが可能です。
- **柔軟性**: 任意の型のキーと値のペアを保存できるため（ただし、キーは比較可能でなければならない）、様々な種類のデータを扱うことができます。
- **簡単なデータ操作**: `map`は値の追加、更新、削除が簡単にでき、これらの操作も高速に行えます。

### mapを使用する際の考慮事項

- `map`のキーは一意である必要があり、既にキーが存在する場合にそのキーに対して新たな値をセットすると、古い値は新しい値で上書きされます。
- キーが存在しない場合、`map`からの値の取得は型のゼロ値を返します（例えば、`int`型のゼロ値は`0`、`string`型のゼロ値は空文字`""`）。
- キーの存在チェック：`map`から値を取得する際には、キーが実際に存在するかどうかを確認するオプションがあります。これにより、キーが存在しない場合にデフォルト値を使用する代わりに、特定の処理を行うことができます。

`map`はその柔軟性と効率の良さから、多くのプログラミングシナリオで役立つデータ構造です。キーを使ってデータを管理する必要がある場合に特に有用で、検索、更新、削除の操作を簡単かつ迅速に行うことができます。


## 使用例
### map使用の一般的な例
Go言語において、`map`の特定のキーに対する値が存在するかどうかを確認する一般的な方法は、`if _, ok := m[key]; ok { ... }` の形式です。これは、mapからの値の取得とそのキーが存在するかどうかの確認を同時に行う「短縮形」と見なすことができます。
、キーの存在自体を確認したい場合や、キーが存在しないときに特定の処理を行いたい場合は、第二戻り値をチェックすることが重要です。

```go
m := map[string]int{"apple": 150, "banana": 300, "lemon": 300}
if value, ok := m["orange"]; ok {
    fmt.Println(value) // キーが存在する場合のみ実行
} else {
    fmt.Println("キーが存在しません")
}
```
この例では、`"orange"`キーがmapに存在するかを確認し、存在する場合のみその値を出力します。存在しない場合は、「キーが存在しません」と出力されます。


### キー、値のチェックが不要の場合
提供されたコード例では、`"banana"`キーの存在を確認し、存在する場合はメッセージを出力しています。

<b>・値だけのチェック例</b>
```go
m := map[string]int{"apple": 150, "banana": 300, "lemon": 300}
if _, ok := m["banana"]; ok {
    fmt.Println("バナナ美味しい")
}
```
「`banana`キーがmapに存在する場合に限り、"バナナ美味しい"と出力する」ことを意味しており、とても一般的で読みやすい方法です。ここで、`_`（アンダースコア）は、mapから取得した値を明示的に無視するために使用されています。`ok`はブール値で、キーが存在する場合は`true`、存在しない場合は`false`を持ちます。


<b>・キーの存在のみのチェック例</b>
`if`文の中で`_`（アンダースコア）を使用して、mapからの値取得時にキーの存在確認（`ok`）を意図的に無視する例を示します。この場合、キーが存在しない場合でも、特にエラーハンドリングや存在確認を行わないシナリオに適しています。ただし、この方法ではキーがmapに存在しない場合、値の型のゼロ値（`int`型であれば`0`、`string`型であれば空文字`""`など）が返されます。

例えば、あるフルーツの価格を調べたいが、価格が存在しない（つまりキーがmapに存在しない）場合でもプログラムを継続させたい場合にこの方法が使えます。

```go
m := map[string]int{"apple": 150, "banana": 300, "lemon": 300}

if value, _ := m["cherry"]; value > 0 {
    fmt.Println("チェリーの価格:", value)
} else {
    fmt.Println("チェリーの価格は不明です")
}
```

この例では、`"cherry"`というキーに対する値をmapから取得しようとしますが、このキーはmapに存在しません。そのため、`value`は`int`型のゼロ値である`0`になります。`if`文の条件では`value > 0`を評価しており、この場合は偽となるため、`else`ブロックが実行され、「チェリーの価格は不明です」と出力されます。

このように、`if`文内で直接値を取得し、それを条件に使って何かしらの処理を行う場合に、キーの存在チェックをスキップすることが可能です。ただし、この方法を使用する際は、キーが存在しない場合に型のゼロ値が返されることを意識しておく必要があります。

<b>・値だけ取得</b>
キーの存在確認が不要で、単に値を取得したい場合は、次のように書くことができます。

```go
m := map[string]int{"apple": 150, "banana": 300, "lemon": 300}
value := m["banana"]
fmt.Println(value) // 300 を出力
```
この場合、`"banana"`キーに対する値`300`が`value`に代入され、その後`value`を出力します。キーが存在しない場合、`value`は型のゼロ値（この場合は`int`型で`0`）になります。



### 参考記事
https://programing-school.work/golang-map-key-exists/#google_vignette
Word アウトライン 文書の折り返し(改行)の設定方法(Mac版)

## 今回やること
Microsoft OfficeのWordには、"アウトライン"という機能が存在している。折り返し(改行)を画面サイズ(ウィンドウサイズ)に合わせる方法を紹介する。

## 仕様
Office：Office365 Word
PC：MacBook Pro (13-inch, 2020, Four Thunderbolt 3 ports)

## 設定方法
0. 初期画面
![スクリーンショット 2024-03-27 12.14.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2887299/b1a76e8c-643d-65ba-4dee-496d9ba78699.png)

自動的に改行されており、右側に大きな空白ができている状態。

1. 画面左上の「Word」をクリック→
![スクリーンショット 2024-03-27 12.14.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2887299/92c00f36-fbea-d1e8-a11d-c2d7420a4f2a.png)

2. 「環境設定」をクリック→
![スクリーンショット 2024-03-27 12.15.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2887299/35da717a-cad9-a78c-6933-91b043ee614a.png)

3. 「表示」をクリック→
![スクリーンショット 2024-03-27 12.15.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2887299/366ea105-6c6d-a2ae-760b-d509392571a8.png)

4. 「ウィンドウ幅に合わせる」にチェックを入れる→
![スクリーンショット 2024-03-27 12.15.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2887299/feb2f560-8107-3dee-d667-d2b0e3d5c744.png)

5. 「×」で閉じると画面サイズ(ウィンドウサイズ)に合わせて、改行されるようになる！
![スクリーンショット 2024-03-27 12.15.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2887299/0b18f014-56ae-c853-5fce-883dd2b1e64c.png)
Swallow-MS-7b-v0.1でのFew-Shot Promptingによる日本語品詞付与

Terra Blevins, Hila Gonen, Luke Zettlemoyer『[Prompting Language Models for Linguistic Structure](https://aclanthology.org/2023.acl-long.367/)』の手法を[Swallow-MS-7b-v0.1](https://huggingface.co/tokyotech-llm/Swallow-MS-7b-v0.1)に適用して、国語研短単位でのUPOS (Universal Part-Of-Speech)品詞付与に挑戦してみた。Few-Shot Promptingの例文は、[UD_Japanese-GSD](https://github.com/UniversalDependencies/UD_Japanese-GSD)の訓練データのうち、固有名詞を含んでいない短めの文で、Swallow-MS-7b-v0.1によるトークナイズが国語研短単位と矛盾しないものを5つ選んだ。

```
>>> class TextUPOSList(list):
...   __str__=lambda self:"\n".join("###text:"+"".join(t for t,u in s)+"\n###UPOS:"+"|".join(t+"_"+u for t,u in s) for s in self)+"\n"
...
>>> ex=TextUPOSList()
>>> ex.append([("一","NUM"),("直線","NOUN"),("に","ADP"),("伸びる","VERB"),("電撃","NOUN"),("を","ADP"),("放ち","VERB"),("、","PUNCT"),("電撃","NOUN"),("ダメージ","NOUN"),("を","ADP"),("与える","VERB"),("。","PUNCT")])
>>> ex.append([("色々","ADV"),("と","ADP"),("面白い","ADJ"),("メニュー","NOUN"),("の","ADP"),("ある","VERB"),("店","NOUN"),("。","PUNCT")])
>>> ex.append([("しかも","CCONJ"),("、","PUNCT"),("ここ","PRON"),("は","ADP"),("コース","NOUN"),("が","ADP"),("リーズナブル","ADJ"),("な","AUX"),("の","SCONJ"),("です","AUX"),("。","PUNCT")])
>>> ex.append([("彼","PRON"),("は","ADP"),("コンピュータ","NOUN"),("を","ADP"),("個人","NOUN"),("の","ADP"),("持ち物","NOUN"),("に","ADP"),("し","VERB"),("まし","AUX"),("た","AUX"),("。","PUNCT")])
>>> ex.append([("2007","NUM"),("年","NOUN"),("9","NUM"),("月","NOUN"),("現在","ADV"),("、","PUNCT"),("以下","NOUN"),("の","ADP"),("メーカー","NOUN"),("から","ADP"),("対応","NOUN"),("製品","NOUN"),("が","ADP"),("発売","VERB"),("さ","AUX"),("れ","AUX"),("て","SCONJ"),("いる","VERB"),("。","PUNCT")])
>>> from transformers import pipeline
>>> tgn=pipeline("text-generation","tokyotech-llm/Swallow-MS-7b-v0.1",max_new_tokens=128)
>>> print("\n".join(tgn(str(ex)+"###text:国境の長いトンネルを抜けると雪国であった。\n###UPOS:")[0]["generated_text"].split("\n")[len(ex)*2:len(ex)*2+2]))
###text:国境の長いトンネルを抜けると雪国であった。
###UPOS:国境_NOUN|の_ADP|長い_ADJ|トンネル_NOUN|を_ADP|抜ける_VERB|と_ADP|雪国_NOUN|で_ADP|あっ_VERB|た_AUX|。_PUNCT
```

『雪国』の冒頭文に品詞付与させてみたところ、私(安岡孝一)の手元では「で」「あっ」の品詞が間違っている(2つともAUXが正解)ものの、他はちゃんと品詞付与できた。もう一度やってみよう。

```
>>> print("\n".join(tgn(str(ex)+"###text:国境の長いトンネルを抜けると雪国であった。\n###UPOS:")[0]["generated_text"].split("\n")[len(ex)*2:len(ex)*2+2]))
###text:国境の長いトンネルを抜けると雪国であった。
###UPOS:国境_NOUN|の_ADP|長い_ADJ|トンネル_NOUN|を_ADP|抜ける_VERB|と_ADP|雪国_NOUN|で_ADP|あっ_VERB|た_AUX|。_PUNCT
```

どうやら同じ結果だ。ならば「[予想に反して品詞付与の精度がイマイチ](https://qiita.com/KoichiYasuoka/items/c458e3b81a62ea0a2607)」という文はどうだろう。

```
>>> print("\n".join(tgn(str(ex)+"###text:予想に反して品詞付与の精度がイマイチ\n###UPOS:")[0]["generated_text"].split("\n")[len(ex)*2:len(ex)*2+2]))
###text:予想に反して品詞付与の精度がイマイチ
###UPOS:予想_NOUN|に_ADP|反_ADV|して_ADP|品詞_NOUN|付与_NOUN|の_ADP|精度_NOUN|が_ADP|イマイチ_ADJ|。_PUNCT
```

やはり「`反し_VERB|て_SCONJ`」が正しくトークナイズできない上に、文末に勝手に「`。_PUNCT`」が追加されている。[一昨々日の記事](https://qiita.com/KoichiYasuoka/items/c458e3b81a62ea0a2607)の手法よりは精度が高い気もするが、それでもトークナイザの問題は残っているし、単語を勝手に追加する可能性もあるということだ。さて、どうしたらいいかな。
Kolder Creative Davinci Resolve 5 (Cut Tab)

>Cut Tab - Intro 
https://www.koldercreative.com/videos/cut-tab-intro
Cut Tabを別で使う１番の理由はタイムラインビューが2つあること。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99892/b09ac729-1329-b6a3-0247-8c1806a45f91.png)


>Cut Tab - Interface
https://www.koldercreative.com/videos/cut-tab-interface

クリップを追加すると2つのタイムラインができる。
上部の細いタイムライン : クリップ全体のタイムライン。常に全体を表示。
下部の細いタイムライン : クリップのズームされたタイムライン。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99892/f114b072-d2fb-be07-2200-ce24b10dd0d4.png)

IN・OUTポイントでクリップの中でも使いたいセクションをマークして以前のクリップの最後尾に追加すれば必要な部分だけを繋げてタイムラインを作ることができる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99892/7d3cf333-01c8-9162-2731-ef4ea1e494df.png)

実際カットタブを使う場合は全てのクリップを選択してタイムラインに突っ込む。クリップの順番もドラッグ&ドロップで挿し込むことも簡単にできる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99892/65873dd9-fd83-9f7c-3933-b2ade134f8b6.png)

下部のタイムラインのプレイヘッドを移動させたい場合はスクショのアイコンをクリックすると動かすことが可能。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99892/82438b5d-2231-8a9b-d948-12feeb529759.png)

右上の"Inspector"をクリックするとクリップを直接編集することができる。(Editタブでもできる)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99892/5f1f3f4d-64fd-be88-cdfc-34742a788665.png)

新しくタイムラインをCommand + Nで作成できる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99892/3fcd6bdf-ba86-80b8-4a10-d1b9afe267a8.png)

タイムラインを複数作成したら、New Binsで新しいファイルを作ってそこに入れると管理しやすくなる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99892/f28abe0d-b99c-9463-5901-6790656f64a1.png)
第1章 モデリングとUML-01-利益 = 需要 - 設計

第1章 モデリングとUML

1.1 利益 = 需要 - 設計
1.1.1 利益 = 需要 - 設計
利益 = 収入 - コスト。何を売るにしても、利益を得るためには2つの条件が必要です：
（1）販売価格が高いこと；
（2）コストが低いこと。
この巧みさは、価格とコストの間に固定の計算式がないことにあり、これが革新の動力源です。
ソフトウェア業界に置いてみると、私も一つの式を考え出しました：
利益 = 需要 - 設計
ソフトウェア開発において、需要の作業は「販売促進」の問題を解決することに専念し、設計の作業は「コスト削減」の問題を解決することに専念しますが、これらは相互に代替できません。あるシステムを低コストで開発・維持できるとしても、必ずしもそれがよく売れるとは限りません。システムがよく売れる場合でも、開発と維持のコストが高すぎると、最終的な利益は低くなります。
上述の「利益」、「販売」、「コスト」は広義で、金銭だけでなく名声、権力、人的リソースなども含みます。
市場で公開販売されていない、組織内システムや自分自身のために作るシステムであっても、上記の式は適用されます。
さらに重要なのは：需要と設計の間には存在しないし、存在すべきでもない硬直的な1対1のマッピングがないことです－幸いにもそうです、そうでなければ人工知能は今やそのマッピングのルーチンを容易に学習し、ソフトウェア開発者のすべての仕事を代替できるようになっていたでしょう。現在、ソフトウェア開発者が存在する価値の一つは、彼らが持つ領域知識とソフトウェア開発の知識を基に、多くの可能なマッピング案の中から最も適切なマッピング案を選び、さらに良いマッピング案を創造することです。
Laravel 学校APIから全ての大学をデータベースに保存する方法

日本の大学を取得する必要があったので、こちらのAPIを使用しました
https://api.edu-data.jp/

学校APIのサイトでユーザー登録して、トークンを発行します。
発行したトークをenvファイルに記述します。
```.env
UNIVERSITY_API_KEY="発行したトークン"
```
```app/config/services.php
  'universities' => [
        'key' => env('UNIVERSITY_API_KEY'),
    ],
```
### Guzzleのラッパーを導入
https://readouble.com/laravel/10.x/ja/http-client.html
```zsh
composer require guzzlehttp/guzzle
```

### 大学テーブル作成
```zsh
php artisan make:model University -m
```
##### マイグレーションファイル
```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.
     */
    public function up(): void
    {
        Schema::create('universities', function (Blueprint $table) {
            $table->id();
            $table->string('name');

            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('universities');
    }
};
```
##### モデル
```Universtiy.php
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class University extends Model
{
    use HasFactory;

    protected $fillable = [
        'name',
    ];
}
```


### 大学シーダー作成
```zsh
php artisan make:seeder UniversitySeeder
```

学校APIで取得される大学の`school_type_code`は`F1`なのでリクエストヘッダ内で指定します。

ヘッダーは、`withHeaders`メソッドを使用してリクエストに追加できます。この`withHeadersメソッド`は、キー／値ペアの配列を引数に取ります。

HTTP上のAPI認証方法として`Authorization` ヘッダーに `Bearer` トークンを設定し、`Accept` ヘッダーには受け取りたいレスポンスの形式として application/json を指定しています。

##### UniversitiesSeederファイル
```php
<?php

namespace Database\Seeders;

use App\Models\University;
use GuzzleHttp\Client;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;

class UniversitiesSeeder extends Seeder
{
    /**
     * 学校APIから全ての大学を取得し、データベースに保存する
     */
    public function run()
    {
        // APIリクエストのオプションを設定
        $response = Http::withHeaders([
                                            //ここでトークン指定
            'Authorization' => 'Bearer ' . config('services.universities.key'),
            'Accept' => 'application/json',
        ])->get('https://api.edu-data.jp/api/v1/school?school_type_code=F1');

        $data = json_decode($response->getBody()->getContents(), true);

        //大学名のみを取得し、データベースに保存
        if ($response->getStatusCode() == 200 && isset($data['schools'])) {
            $universities = $data['schools']['data'];
            foreach ($universities as $university) {
                University::create([
                    'name' => $university['school_name'], // 大学名
                ]);
            }
        } else {
            // レスポンスが200以外の場合、または$dataが期待する構造でない場合のエラーハンドリング
            Log::error('Failed to fetch universities data from API.', ['status' => $response->getStatusCode()]);
            return null;
        }
    }
}
```


### シーダー実行
```zsh
php artisan db:seed --class=UniversitySeeder
```
データベースにAPIで取得した大学が入ります。
【GitHub】GitHub の OAuth Tokenの取得方法

# GitHub の OAuth Token とは？
GitHub API を使って GitHub 上の情報を取得するには、GitHub上で発行されるアクセストークンが必要です。
なくても問題はないのですが、取得数が1時間に60回と制限されてしまいます。

アクセストークンには以下の3つがあります。
- OAuth Access Token
- Personal Access Token

# 手順
大まかな手順は以下の通りです。
1. OAuthの設定をする：この時、**Client ID ** と **Client Secret** を取得します
1. GitHub ログイン画面に遷移
1. 一時コードを取得する
1. POSTリクエストしてアクセストークンを取得する


# 詳細
## OAuth の設定
まず、GitHubの設定画面に移動します。
![スクリーンショット 2024-03-31 14.29.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/707293/a262ebff-eb4f-e1f8-cf47-93985056d777.png)

その中の **Developer settings** へ移動します。

![スクリーンショット 2024-03-31 14.30.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/707293/0ce3fe6e-7008-cf77-075f-669aacfcd657.png)

その中に、以下の3つがあるはずです(2024年4月現在)
- GitHub Apps
- OAuth Apps
- Personal access tokens

今回は **OAuth Apps** を選択します。

![スクリーンショット 2024-03-31 14.35.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/707293/95d01cac-5ed2-f034-33aa-bd225e04b4c8.png)

OAuth App を新規登録します。**New OAuth App** をクリックします。

![スクリーンショット 2024-03-31 14.35.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/707293/00218e00-5b27-c06f-d116-2d22679dfbf8.png)

以下に必要事項を記入していきます。
![スクリーンショット 2024-03-31 14.36.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/707293/2afb3fb0-f8d3-4e0c-02e3-0c39cc9b61fe.png)

記載したら **Register application** をクリックします。
この時に、**Client ID**と**Client secrets** を取得するので、どこかに一旦メモったほうが良いです。

これで、OAuth の設定をすることができました。

## GitHub ログイン画面に遷移
以下のアドレスで GitHub のログインページにジャンプします。

```url
https://github.com/login/oauth/authorize?client_id=XXX&scope=YYY`
```
`XXX`に先ほど取得した **Client ID**を入れます。
`YYY`は、パラメータに取得したい情報のスコープを指定します。(`repo` や `user`、`gist` など)

スコープの詳細については↓を参照ください。

https://docs.github.com/ja/apps/oauth-apps/building-oauth-apps/scopes-for-oauth-apps#available-scopes

## 一時コードを取得する
GitHubからのリダイレクト要求により、リダイレクト先のページにアクセスします。この時、URLの末尾にアクセストークン取得用の一時コードが次のような形でついてきます。

```
http://<リダイレクト先のページ>?code=ABCDEABCDEABCDE
```

このコードはアクセストークンではありません。アクセストークンは、後でHTTP POST メソッドで一時コードを送ることで取得することができます。
一時的なものなので、一定時間(5〜10分くらい？)を過ぎると更新されます。(再度、GitHubログインすると取得できます。)

## POSTリクエストしてアクセストークンを取得する
先ほど取得した一時コードを使って、以下のアドレスに POST リクエストを送ります。[Postman](https://www.postman.com) などを使うと良いでしょう。

```
https://github.com/login/oauth/access_token
```

POSTリクエストには、次のようなパラメータを含めておく必要があります。Body に以下を追加しましょう。

```
client_id:XXXX
client_secret:YYYY
code:ZZZZ
```

`client_id` は、登録した OAuth アプリに割り当てられたクライアントIDの文字列です。
`client_secret` は、登録した OAuth アプリに割り当てられたクライアントシークレットの文字列です。
`code`は、先ほどのステップで取得した一時コードです。

リクエスト時に、ヘッダーの Accept が `Accept: application/json` と指定してリクエストすると、次のような JSON 形式のレスポンスが返ってきます。

```json
{
  "access_token": "e72e16c7e42f292c6912e7710c838347ae178b4a",
  "scope": "repo, user, gist",
  "token_type": "bearer"
}
```

この `access_token` が、OAuthアクセスToken です。これを GitHub API を呼び出す時に、ヘッダに指定すると取得することができます。


## 参考文献
https://qiita.com/besmero628/items/823a7630c77318d910b0

https://maku.blog/p/ubkt3ai/
Swallow-7b-plus-hfでのFew-Shot Promptingによる日本語品詞付与

Terra Blevins, Hila Gonen, Luke Zettlemoyer『[Prompting Language Models for Linguistic Structure](https://aclanthology.org/2023.acl-long.367/)』の手法を[Swallow-7b-plus-hf](https://huggingface.co/tokyotech-llm/Swallow-7b-plus-hf)に適用して、国語研短単位でのUPOS (Universal Part-Of-Speech)品詞付与に挑戦してみた。Few-Shot Promptingの例文は、[UD_Japanese-GSD](https://github.com/UniversalDependencies/UD_Japanese-GSD)の訓練データのうち、固有名詞を含んでいない短めの文で、Swallow-7b-plus-hfによるトークナイズが国語研短単位と矛盾しないものを5つ選んだ。

```
>>> class TextUPOSList(list):
...   __str__=lambda self:"\n".join("###text:"+"".join(t for t,u in s)+"\n###UPOS:"+"|".join(t+"_"+u for t,u in s) for s in self)+"\n"
...
>>> ex=TextUPOSList()
>>> ex.append([("一","NUM"),("直線","NOUN"),("に","ADP"),("伸びる","VERB"),("電撃","NOUN"),("を","ADP"),("放ち","VERB"),("、","PUNCT"),("電撃","NOUN"),("ダメージ","NOUN"),("を","ADP"),("与える","VERB"),("。","PUNCT")])
>>> ex.append([("色々","ADV"),("と","ADP"),("面白い","ADJ"),("メニュー","NOUN"),("の","ADP"),("ある","VERB"),("店","NOUN"),("。","PUNCT")])
>>> ex.append([("しかも","CCONJ"),("、","PUNCT"),("ここ","PRON"),("は","ADP"),("コース","NOUN"),("が","ADP"),("リーズナブル","ADJ"),("な","AUX"),("の","SCONJ"),("です","AUX"),("。","PUNCT")])
>>> ex.append([("彼","PRON"),("は","ADP"),("コンピュータ","NOUN"),("を","ADP"),("個人","NOUN"),("の","ADP"),("持ち物","NOUN"),("に","ADP"),("し","VERB"),("まし","AUX"),("た","AUX"),("。","PUNCT")])
>>> ex.append([("2007","NUM"),("年","NOUN"),("9","NUM"),("月","NOUN"),("現在","ADV"),("、","PUNCT"),("以下","NOUN"),("の","ADP"),("メーカー","NOUN"),("から","ADP"),("対応","NOUN"),("製品","NOUN"),("が","ADP"),("発売","VERB"),("さ","AUX"),("れ","AUX"),("て","SCONJ"),("いる","VERB"),("。","PUNCT")])
>>> from transformers import pipeline
>>> tgn=pipeline("text-generation","tokyotech-llm/Swallow-7b-plus-hf",max_new_tokens=128)
>>> print("\n".join(tgn(str(ex)+"###text:国境の長いトンネルを抜けると雪国であった。\n###UPOS:")[0]["generated_text"].split("\n")[len(ex)*2:len(ex)*2+2]))
###text:国境の長いトンネルを抜けると雪国であった。
###UPOS:国境_NOUN|の_ADP|長い_ADJ|トンネル_NOUN|を_ADP|抜ける_VERB|と_ADP|雪国_NOUN|で_ADP|あっ_ADJ|た_ADJ|。_PUNCT
```

『雪国』の冒頭文に品詞付与させてみたところ、私(安岡孝一)の手元では「で」「あっ」「た」の品詞が間違っている(3つともAUXが正解)ものの、他はちゃんと品詞付与できた。もう一度やってみよう。

```
>>> print("\n".join(tgn(str(ex)+"###text:国境の長いトンネルを抜けると雪国であった。\n###UPOS:")[0]["generated_text"].split("\n")[len(ex)*2:len(ex)*2+2]))
###text:国境の長いトンネルを抜けると雪国であった。
###UPOS:国境_ADV|の_NOUN|長い_NOUN|トンネル_NOUN|を_ADP|抜ける_VERB|と_ADP|雪国_NOUN|で_ADP|あっ_AUX|た_AUX|。_PUNCT
```

今度は「国境」と「長い」と「で」の品詞が間違っているものの、他は正しい。よし、三度目の正直。

```
>>> print("\n".join(tgn(str(ex)+"###text:国境の長いトンネルを抜けると雪国であった。\n###UPOS:")[0]["generated_text"].split("\n")[len(ex)*2:len(ex)*2+2]))
###text:国境の長いトンネルを抜けると雪国であった。
###UPOS:国境_NOUN|の_NOUN|長い_NOUN|トンネル_NOUN|を_ADP|抜ける_VERB|と_ADP|雪国_NOUN|であっ_ADV|た_ADV|。_PUNCT
```

うーん、結果がどんどん悪くなっている気がする。まあ、とりあえずFew-Shot Promptingでも、何となく品詞付与できる気がしてきた。ただ、これ、[3月27日の記事](https://qiita.com/KoichiYasuoka/items/71c23f945b0c59db5c4a)の手法に較べて、精度の点ではどうなんだろう。
Amazon Aurora PostgreSQLのチートシート

# 背景・目的
いつも、SQLやコマンドを忘れやすいのでメモしておきます。

:::note info
PostgreSQLに特化し限定したものだけではなく、一般的なSQLも含めて記載しています。
:::

:::note info
気づいたタイミング、必要になったタイミングで更新します。
:::

# まとめ

|分類|SQLまたはコマンド |備考|
|:--|:--|:--|
|スキーマ|[スキーマを作成する](https://qiita.com/zumax/items/a82fb20471832fbe5b6b#%E3%82%B9%E3%82%AD%E3%83%BC%E3%83%9E%E3%82%92%E4%BD%9C%E6%88%90%E3%81%99%E3%82%8B)||
||[スキーマの一覧を確認する](https://qiita.com/zumax/items/a82fb20471832fbe5b6b#%E3%82%B9%E3%82%AD%E3%83%BC%E3%83%9E%E3%81%AE%E4%B8%80%E8%A6%A7%E3%82%92%E5%8F%82%E7%85%A7%E3%81%99%E3%82%8B)||
|テーブル|[テーブルを作成する](https://qiita.com/zumax/items/a82fb20471832fbe5b6b#%E3%83%86%E3%83%BC%E3%83%96%E3%83%AB%E3%82%92%E4%BD%9C%E6%88%90%E3%81%99%E3%82%8B)|
||[テーブルの一覧を確認する](https://qiita.com/zumax/items/a82fb20471832fbe5b6b#%E3%83%86%E3%83%BC%E3%83%96%E3%83%AB%E3%81%AE%E4%B8%80%E8%A6%A7%E3%82%92%E7%A2%BA%E8%AA%8D%E3%81%99%E3%82%8B)|
||[テーブルの定義を確認する](https://qiita.com/zumax/items/a82fb20471832fbe5b6b#%E3%83%86%E3%83%BC%E3%83%96%E3%83%AB%E3%81%AE%E5%AE%9A%E7%BE%A9%E3%82%92%E7%A2%BA%E8%AA%8D%E3%81%99%E3%82%8B)|
||[テーブルを削除する](https://qiita.com/zumax/items/a82fb20471832fbe5b6b#%E3%83%86%E3%83%BC%E3%83%96%E3%83%AB%E3%82%92%E5%89%8A%E9%99%A4%E3%81%99%E3%82%8B)|

# 実践
## スキーマ
### スキーマを作成する
```
CREATE SCHEMA {スキーマ名};
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/d633e483-3e8a-5dca-72ca-6390337f5364.png)


### スキーマの一覧を参照する
```
SELECT schema_name 
FROM information_schema.schemata;
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/8863cec9-0eb5-53bc-19ea-3d029d306573.png)


## テーブル
### テーブルを作成する
```
CREATE TABLE client (
    client_id SERIAL PRIMARY KEY,
    client_name VARCHAR(255) NOT NULL,
    client_address VARCHAR(255),
    client_phone VARCHAR(20),
    client_contact_person VARCHAR(255),
    client_contact_phone VARCHAR(20)
);
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/89823971-5818-2930-176e-1519c1e02834.png)

### テーブルの一覧を確認する
```
SELECT table_schema,table_name
FROM information_schema.tables
WHERE table_schema = 'client';
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/7c5ce6d3-bc31-448e-f1e4-d4ab302ce0ae.png)


### テーブルの定義を確認する
```
SELECT column_name, data_type, is_nullable, column_default
FROM information_schema.columns
WHERE table_name = 'client'
AND table_schema='client'
ORDER BY ordinal_position;
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/d0329608-c9ef-9dc0-c48f-22952105058c.png)


### テーブルを削除する
```
DROP TABLE public.clients
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/0765be4f-2e1e-62ef-fb11-7c2b3955112e.png)
Qiita始めました

# 概要

Quitaに投稿する最初の記事です。
自己紹介、今後の意気込みを述べたいと思います。

# 自己紹介

私は情報セキュリティを学んでいる大学院生です。
研究テーマはまだ未決定ですが、WAFテスト（WAFを回避するようなペイロードがないかを確かめる、いわば「WAF版脆弱性診断」）とXAI（説明可能AI）を組み合わせた研究を行いたいと考えています。
学業とは別に長期インターンシップを2社でやらせていただいています（どちらもインフラ、セキュリティエンジニアのポジションです）。
以下の分野に興味があります。
- クラウド
- サイバーセキュリティ
- AI



# これからの目標
私の現時点での目標は今日から1年間毎日投稿（毎日は難しくても、1日にまとめて複数記事を作成してカバー）を続けることです。

# 終わりに
一日も早く読んでいただく皆様に有益な記事を書けるよう頑張っていきますので応援宜しくお願いします！
（Zennのアカウントも持っています。https://zenn.dev/shahrukh0526 こちらでも記事を書いていきますので宜しくお願いします。）
Salesforceでファイルに添付されているレコード一覧を確認する方法

こんにちは。
本橋孝昭です
今回はSalesforceでファイルに添付されているレコード一覧を確認する方法をお伝えします


まず、前提としてSalesforceでは特定のレコード一覧を確認する方法として一般的にレポートでの表示ができます


しかしながら（少なくとも2024年時点では）ファイル一覧やファイルが紐づくレコード一覧をレポートで表示することはできません

※詳細はこちらのIdeaにも記載があります

https://ideas.salesforce.com/s/idea/a0B8W00000GdmPdUAJ/improve-reporting-on-files-contentdocument

Currently, reporting on Files (ContentDocument) and which records they're shared to (ContentDocumentLink) is impossible. The "File and Content Report" report type only shows files that the running user has uploaded. This report type can't be filtered based on the type of record the files are shared to. And Files (or ContentDocument) is not an available object for creating a custom report type.

※Googleに頼った翻訳文
現在、ファイル (ContentDocument) とファイルが共有されているレコード (ContentDocumentLink) についてレポートすることは不可能です。 「ファイルとコンテンツ レポート」レポート タイプには、実行中のユーザーがアップロードしたファイルのみが表示されます。このレポート タイプは、ファイルが共有されているレコードのタイプに基づいてフィルタリングすることはできません。また、ファイル (または ContentDocument) は、カスタム レポート タイプの作成に使用できるオブジェクトではありません。



そのため、今回はデータローダによるエクスポートによるレコード一覧確認方法を示します
なおデータローダをまだインストールしていない方はデータローダをインストールをしてください

https://help.salesforce.com/s/articleView?id=000383107&language=ja&type=1

## 前提　データローダログインするユーザには「すべてのファイルをクエリ」があること

まず、事前準備としてデータローダでエクスポートをするユーザは「すべてのファイルをクエリ」権限を付与してください
この権限はシステム管理者プロファイルでも保有してない権限なので見落とされがちです
![権限セット001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/59ae7730-f50e-2dd0-c463-c468f855be05.png)

では、ここからデータローダによるコンテンツドキュメントリンクオブジェクトをエクスポートしてファイル添付があるレコードのIDを確認する方法を示します

## 1  Export をクリック

![E001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/88636d1f-9ee9-a95e-ec29-5acd083ee719.png)


## 2 ContentDocumentLinkオブジェクトを選択
![E002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/dbf6b094-ceb7-d4cc-03c1-20a36c67eab7.png)

まずは「Show all Salesforce objects」をクリックしコンテンツドキュメントリンクオブジェクトを選択
Choose a target for extraction にデータローダの結果を残す場所を選択しNextをクリック


## 3 エクスポートする項目を選びFinish
エクスポートする項目を選択。特に考えが無ければSelect all fieldsをクリックし全項目選択
その後Finishをクリック


![E0031.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/df0deb86-920c-63f7-6023-25208dffd047.png)

はい（Y）をクリック


そして、
このような画面が出たら成功です

![E0033.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/66d774bd-c2f0-bd3b-7b9f-8aa9faa7ece2.png)

ステップ２　で選択したChoose a target for extraction に　エクスポートデータが出ているはずです


このエクスポートデータの「LINKEDENTITYID」に記載されているIDのレコードが、添付ファイルがあるレコードの一覧になります

![E004.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/c550d3e0-0973-4f77-009d-8c5517fa526d.png)


その他の項目の内容が気になる方はこちらをご確認してください

https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_contentdocumentlink.htm
【トリビア】Rubyで users .map(&:name) の形式で呼び出せるのはpublicメソッドだけ

## はじめに
たとえばUserクラスに`name`というprotectedメソッドがあったとします。
（protectedメソッドの登場頻度はかなり少ないと思いますが）

```ruby 
class User
  protected
  
  def name
    'Alice'
  emd
end
```

さらに、`fetch_names`というpublicメソッドも定義されていたとします。

```ruby 
class User
  def fetch_names(users)
    users.map { |u| u.name }
  end
  
  protected
  
  def name
    'Alice'
  end
end
```

では`fetch_names`メソッドを呼び出してみましょう。

```ruby 
users = [User.new, User.new, User.new]
users[0].fetch_names(users)
#=> ["Alice", "Alice", "Alice"]
```

はい、問題なく呼び出せました。
（注：Rubyのprotectedメソッドは同じクラス、またはサブクラスから呼び出せるメソッドです）

## しかし、リファクタリングすると……？

Ruby経験者であれば、`fetch_names`の実装を見て「もっと短く書きたい！」と思うはずです。
そう、経験者ならRubyのイディオム的に`users.map(&:name)`のように書くことが多いはずです。
やってみましょう。

```ruby 
class User
  def fetch_names(users)
    users.map(&:name) # リファクタリング！？
  end
  
  protected
  
  def name
    'Alice'
  end
end

users = [User.new, User.new, User.new]
users[0].fetch_names(users)
#=> protected method `name' called for an instance of User (NoMethodError)
```

おっと、リファクタリングしたつもりが NoMethodError になってしまいました！

## users.map(&:name) の形式で呼び出せるのはpublicメソッドだけ

Rubyの仕様として、`users.map(&:name)`の`&:name`の部分にあたるメソッドはpublicメソッドしか呼び出せません。
protectedメソッドは呼び出せないので、最初に示したコードのように、

```ruby 
users.map { |u| u.name }
```

通常のブロックで呼び出す必要があります。

## おまけ：Ruby 3.2以降で微妙に変わった言語仕様
ところで、`users.map(&:name)`のような呼び出し方は、以下のようなコードを書いているのとほぼ同じです。

```ruby 
# レシーバ u に対してメソッド :name を呼び出す
users.map { |u| :name.to_proc.call(u) }
```

https://docs.ruby-lang.org/ja/latest/method/Symbol/i/to_proc.html

実は `:name.to_proc.call(u)` のような呼び出し方は、Ruby 3.1までエラーなく呼び出せていました。

```ruby 
RUBY_VERSION
#=> "3.1.2"

class User
  def fetch_names(users)
    # Ruby 3.1 まではエラーなく呼び出せていた
    users.map { |u| :name.to_proc.call(u) }
    
    # ただし、これは3.1以前でもNG
    # users.map(&:name)
  end
  
  protected
  
  def name
    'Alice'
  end
end

users = [User.new, User.new, User.new]
users[0].fetch_names(users)
#=> ["Alice", "Alice", "Alice"]
```

しかし、Ruby 3.2以降ではエラーが起きます。

```ruby
RUBY_VERSION
#=> "3.2.2"

# (略)

users = [User.new, User.new, User.new]
users[0].fetch_names(users)
#=> protected method `name' called for an instance of User (NoMethodError)
```

これは下記issueでの議論の結果、シンボルをproc化したときの可視性チェックが非常に難しいため、一律で「publicメソッド以外は呼び出せないようにする」という仕様変更が入ったためです。

> In general, `a.b(&:c)` should behave exactly the same as `a.b{_1.c}`. But visibility check for `protected` methods may be too difficult for `to_proc`. So rejecting `protected` methods altogether like `private` methods is acceptable.
>
> Matz.

https://bugs.ruby-lang.org/issues/18826#note-5

https://github.com/ruby/ruby/pull/6018/

この仕様変更、僕は把握してなかったんですが、Ruby 3.2のNEWSには書いてなかったみたいです。（バグ修正扱いだったせいでしょうか？ :thinking: ）

https://github.com/ruby/ruby/blob/v3_2_0/NEWS.md

## まとめ
というわけで、この記事では `users.map(&:name)` の形式で呼び出せるのはpublicメソッドだけ、という話を書いてみました。

protectedメソッドを取り扱う機会はあまりないと思いますが、protectedメソッドは `users.map(&:name)` では呼び出せないということを頭の片隅に置いておくと、いつか役に立つときが来るかもしれません（いや、来ないかな……😅）。

### Special thanks
[ruby-jp](https://ruby-jp.github.io/)で上記issueの存在を教えてくださった @tompng さん、どうもありがとうございました！
プロの芸人が答える「エンジニア大喜利」

# はじめに
芸人の「ジンバ」と申します。ライブに出つつも、普段はIT企業でエンジニアとして働いてます。
SNSで<b>「エンジニア大喜利」</b>というのを見つけました。
やってみたくなったので、プロの芸人らしく答えます。ハードルだけが上げる企画です。
<b>(皆さんもコメントで回答したり、お題ください〜)</b>
随時更新予定

動画も出してます。
https://youtu.be/LXBOv2p3XMI
![大喜利サムネ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3574599/6e19682c-603f-1383-4437-6e74e85f1a14.png)


# 「エンジニアだらけの結婚式について教えてください」

#### SIerの人多めだったので、スマホやカメラなど外部からの端末持ち込み禁止。
何も思い出残せないですね。こんな感じでやっていきます。


#### お色直しを「仕様変更」と呼ぶ
多くの人を巻き込みそうです。


#### ブーケトスで最初はコンサルの人が取るがPMとかに渡して、最後は五次請けのテスターに渡るし、花がほとんど無い。
下請けの闇です。

#### 1番盛り上がった余興が「新郎が書いたコードを新婦の父親がコードレビュー」
コメントアウトで「娘さんを大事にします」とか書いてそう

#### 二次会がちょうど土曜の夜9時だったので「AtCoder」やる時間があった。
ビンゴやれよ。



#  「エンジニア養成小学校、どんなの？」


#### 夏休みの宿題をWBSで管理するように教えられる
それでもやらない奴はやらない

#### ゆとり教育の時「Javaとjavascriptは同じ」と教えられてたらしい。
πを3.14ではなく3にします、みたいな。

#### 避難訓練みたいに「サーバー落ちた時訓練」がある。
普通のIT企業に導入しても良さそう。

#### 急な休日授業がある
休日出勤に慣れるため

# 「この旅館、元エンジニアが経営してるな？」  なぜそう思った？

#### 女将さんが電話で「はい、お電話ありがとうございます。ただ今、満室でして。はい、null部屋はないんですよ。」 空き部屋のことをnull部屋言うてる
一発でエンジニアと分かる

#### 温泉の効能に「Expected a value of type、index out of rangeNullPointerExceptionに効きます」と書かれていた
8000円でも入りたい

#### 掛け軸に達筆な字で「客先常駐」と書かれていた。
ここは常駐先か？

# おわりに
皆さんもコメントで回答したり、お題ください〜
【Laravel】外部APIをスタブにして単体テストを実施する

外部APIに依存している機能を単体テストする場合、外部APIをスタブにしてダミーレスポンスを設定してテストをすることが一般的です。

今回、Laravelの単体テストにおいて外部APIに依存している部分があったのでLaravelの単体テストにおける外部APIのスタブ化について纏めました。

# 結論
- Http::fakeを使う事で外部APIとの通信をスタブに置き換えることができる
- 呼び出し順によって応答内容を変える場合はHttp::sequence()を使う
- Http::fakeは上書きができない

# 基本形
```php
Http::fake([
    '/signin' => Http::response([
        'status' => 'Success'
    ], 200),
    '*' => Http::response([
        'status' => 'OK'
    ], 200),
]);
```
Http::fakeにAPIのURLごとに応答内容をHttp::responseを使って設定すればよい。
ワイルドカードも使用可能。

# 同じAPIを複数回呼び出す時にそれぞれで応答を変えたい場合
```php
Http::fake([
    '/signin' => Http::sequence()
        ->push(['status' => 'Success'], 200)
        ->push(['status' => 'Fail'], 400),
    ]);
```
Http::sequenceを使うことで呼び出しの順番に応じた応答を返すようにできる。

# 同じテストの中でfakeの設定を上書きすることはできない
```php
Http::fake([
    '/signin' => Http::response([
        'status' => 'Success'
    ], 200)
]);

Http::fake([
    '/signin' => Http::response([
        'status' => 'OK'
    ], 200)
]);
```
同じAPIに対してfakeを２回呼び出しても最初に設定したレスポンス（Success）しか返ってこなかったので、上書きはできないようだ。
そのため、基本的なレスポンスはsetUpで設定しておいて、必要に応じて各テストメソッドで応答内容を上書きする、といったことはできなかった。

# 参考
https://readouble.com/laravel/8.x/ja/http-client.html
nRF9160を使ってPPP接続する実験

備忘録

NCS v2.6.0 のサンプルアプリケーション ModemShell を使用して、
Ubuntu Desktop（LTS 22.04.1）から UART 経由で PPP 接続できるか実験してみた。

 
# ModemShell
UARTが２ポート必要。

１つは ModemShell 用
１つは PPP 用


例えば、デフォルトで uart0 がコンソール用に設定されていて uart1 を ppp 用にするには、
 zephyr,ppp-uart = &uart1;
を設定してあげる。
ボーレートは 1000000 にしてみた。
115200でも大丈夫だった。
ハードウエアフロー制御の指定は外しておいた。
```
/ {
	chosen {
		zephyr,ppp-uart = &uart1;
	};
};
&uart1 {
    status = "okay";
    current-speed = <1000000>;
    pinctrl-0 = <&uart1_default>;
    pinctrl-1 = <&uart1_sleep>;
    pinctrl-names = "default", "sleep";
};

&pinctrl {
	uart1_default: uart1_default {
		group1 {
			psels = <NRF_PSEL(UART_TX, 0, 7)>,
				<NRF_PSEL(UART_RX, 0, 5)>;
		};
	};
	uart1_sleep: uart1_sleep {
		group1 {
			psels = <NRF_PSEL(UART_TX, 0, 7)>,
				<NRF_PSEL(UART_RX, 0, 5)>;
			low-power-enable;
		};
	};
};
```

prj.confに。overlay-pppを追記する。
デフォルトで uart0が ppp ようになっているので。
uart1 に変更する場合は。
```
CONFIG_UART_1_INTERRUPT_DRIVEN=n
CONFIG_UART_1_ASYNC=y
CONFIG_UART_1_NRF_HW_ASYNC=y
CONFIG_UART_1_NRF_HW_ASYNC_TIMER=1
```
のように０を１に変える必要がある。

# PPP接続
nRF9160 の PPP UART 入出力は PPPの通信フレームが生で流れるので、PPPD の Modem操作関連の設定は不要となる。

（pppのインストール＆設定の過程は省略）

nRF9160をUART接続して Ubuntuのコマンドライン上にて、pppd を起動する。

（PPP関連の詳細は他のサイトを参照してください）

接続したら、ping で疎通を確認して実験を終了。


以上、ご参考まで。
chart.JSの設定

chart.jsで見た目をカスタマイズする機会があったので備忘録としてメモします。

## 補助線の表示/非表示
gridのdisplayをtrueかfalseで表示/非表示を変更できます
```javascript

x: {
    grid: {
        display: false // x軸の補助線を非表示にする
    },

}
```

## 目盛のスタイル
```javascript
ticksの設定をいじることで変更できます。
color:文字色
font size:フォントサイズ
font wheight:太文字
x: {

    ticks: {
        color: '#0C2360',
        font: {
            size: 15,
            weight: "bold"
        }
    },
}
```

## グラデーション
```javascript

    // canvasを取得
    const ctx = document.getElementById('canvas_id').getContext('2d');

    // グラデーションの変数:gradientBlueを定義
    const gradientBlue = ctx.createLinearGradient(0, 0, 0, 300);

    //gradientBlueの調整
    gradientBlue.addColorStop(0, '#297BC4');
    gradientBlue.addColorStop(0.5, '#297BC4');
    gradientBlue.addColorStop(1, '#0C2360');



    data: {
        datasets: [{
            //ここで作成したグラデーションを設定
            backgroundColor: gradientBlue,
        }]
    },
```

## グラデーション応用

データの数に応じて、同じ系統の色で段々と色の濃淡が変わるようなグラデーションを作って見ます。
こんなイメージです。
![がrで.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3332453/1db561ac-19c6-141f-1769-5a7599d1bacd.png)


```javascript

//

const date = [23,35,・・・・・・・,67,89]

//　データ総数を取得
data_count = data.length;

// canvasを読み込み
const ctx = document.getElementById('canvas_id').getContext('2d');

// グラデーションのパターンを格納する配列を準備
var colors = [];

//iの値で透明度を変化させてデータの総数通りの背景色を生成して配列に格納
for (var i = 0; i < data_count; i++) {
    var alpha = 1.0 - (0.1 * i); // 透明度を調整する値
    colors[i] = ctx.createLinearGradient(0, 0, 0, ctx.canvas.height * 0.5);
    colors[i].addColorStop(0, 'rgba(41, 123, 196, ' + alpha + ')'); // 開始色（薄い青）
    colors[i].addColorStop(1, 'rgba(12, 35, 96, ' + alpha + ')'); // 終了色（濃い青）
}


//---省略----//


data: {
    datasets: [{
        //ここで作成したグラデーションを設定
        backgroundColor: colors,
    }]
},

//---省略----//

```
【ChatGPT＋DALL-E3】の履歴を検索しようとしたら……


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

　今回は、履歴を検索しようとしたら、の話を書きます。たいした内容ではありませんが、同じことをする人には注意喚起になればと思い、書きます。

:::note info
本記事は、ChatGPT（有料版）
＋DALL-E3で行なっております。
画像はありません。あしからず。
:::

　本題です。

　ChatGPTをやっていると
　　当然ながら、セッションは
　　　履歴として残ります。

　検索するには
　　その履歴をExportして解凍して
　　　その中のchat.htmlを
　　　　ブラウザに読み込んで
　　　　　行ないます。

　それで
　　検索しようとしましたが、
　　　引っ掛かりません。

　ちなみに
　　検索しようとしていたのは
　　　“解析”です。

　ファイルをアップロードして
　　解析してもらっているので
　　　当然引っ掛かると
　　　　思っていました。

　それなのに
　　引っ掛からない。

　そこで
　　ほかの文言で
　　　検索すると、
　　　　引っ掛かります。

　よくよく
　　“解析”のところを見ると、
　　　解析のプロンプトが
　　　　見当たりません。

　いつも解析する際は
　　セッション最初に
　　　アップロードと
　　　　プロンプト入力するのですが。

　userの部分がなく
　　ChatGPTの出力から
　　　はじまっています。

　そういえばと思い出したのは
　　Web版でも、最初の入力は
　　　ペンアイコンがなく
　　　　編集できないことでした。

　そこから考えるに、
　　アップロード時の
　　　編集があっては、
　　　　内部的に調整が
　　　　　難しいのではないか、と。

　でも
　　履歴のファイルには
　　　出力しても、バチは当たらない
　　　　と思うのですけどねぇ😅
***
　対処方法は、
　　検索キーワードを
　　　別のものにする、
　　　　この一択になりますね。

　このことが
　　みなさんの
　　　作品制作の糧に
　　　　なれば、幸いです。

　今回は、ここまで。
スイッチサイエンス nRF9160搭載 LTE-M/NB-IoT/GNSS対応 IoT開発ボード で region `FLASH' overflowed となる問題

スイッチサイエンス nRF9160搭載 LTE-M/NB-IoT/GNSS対応 IoT開発ボード で
NCS v2.6.0 の Modem Shell　サンプルアプリケーションのビルド時に
フラッシュメモリが足りているのにオーバーフローとなってビルドできなかったので
試行錯誤してみた。


ボード定義ファイルのあるフォルダにて、

pm_static_ssci_nrf9160_iot_dev_board_ns.yml
pm_static_ssci_nrf9160_iot_dev_board.yml

を無効化してみたら解決できた。


ご参考まで。