OmniAICreator/Qiita-1.07M huggingface dataset:
LaravelのEloquentでカラムを更新できなかった凡ミスの話

# はじめに
タイトルの通り、凡ミスの話なので参考になる方は少ないかもしれませんが、自戒と備忘を兼ねて記事に残しておきます。
# 何が起こったか
以下のようにLaravelのEloquentを使用してデータのupdateOrCreateを行ったところ、column1だけ更新され、column2が更新されませんでした。
```php
Table1::updateOrCreate([
	'id' => 1
], [
	'column1' => 1,
	'column2' => 2
]);
```
# 最初にやった対応（悪い例）
初動でミスってしまったのですが、column2が外部キーだったため、それが影響しているのではないかと考えてしまい、色々調べてみてもわからず（原因じゃないので当然ですね）、以下のようにEloquentを使用せずにクエリビルダで更新するようにしました。
```php
DB::table('table1')->updateOrInsert([
	'id' => 1
], [
	'column1' => 1,
	'column2' => 2
]);
```

# 正しい対応
その後、どうしても納得がいかずupdateOrCreateの処理を追っていったところ、以下のコードを発見しました。
察しのいい方は気付いたかもしれませんが、`$instance->fill($values)->save();`という処理がポイントです。
はい、**$fillableにcolumn2の定義が漏れていた**というオチでした。
```php:vendor\laravel\framework\src\Illuminate\Database\Eloquent\Builder.php
public function updateOrCreate(array $attributes, array $values = [])
{
    return tap($this->firstOrCreate($attributes, $values), function ($instance) use ($values) {
        if (! $instance->wasRecentlyCreated) {
            $instance->fill($values)->save();
        }
    });
}
```
というわけで、Modelを以下のように修正してupdateOrCreateが問題なく動くようになりました。
```php
protected $fillable = [
    'column1',
    'column2',
];
```
# おわりに
わかってしまうと間抜けな話なのですが、目星をつけていたのと全然違う原因だったというのは多くの人が経験したことがあるのではないでしょうか。
Eloquentのコードを読むいい機会だったと自分を慰めつつ、以下を教訓に丁寧なコーディングを心がけようと思います。
- カラムの追加や変更をしたら必ずModelを見直す
- 安易にクエリビルダに逃げない（Eloquentの制御が効かないので）
- 闇雲に調べるよりコードを追った方が早いことは稀によくある
Dataiku上で外部モデルを取り込みマルチプラットフォームの活用を促進する

2023年、データの世界はエコシステムである。組織は、ビジネス目標を達成するために、さまざまなシステム、製品、プラットフォームを使いこなさなければならない。
多くの企業が、説明性に欠ける、あるいはビジネスで実用的でないAIモデルに苦慮している。これらのモデルを非技術者にとって説明しやすく、使いやすいものにすることは極めて重要だ。さらに、これらのモデルを単一のリポジトリに集中させることで、管理と維持が容易になります。これらのモデルを外部で作成、デプロイしていたとしても、Dataikuを活用することで、これらの課題をすべて解決します。

[MLFlow](https://blog.dataiku.com/did-mlflow-kill-the-data-science-star)との統合をベースに、「外部モデル」機能を拡張しました。既存のAWS SageMaker、Microsoft AzureML、Google VertexのAIモデルをDataikuで活用できるようになりました。
外部モデルを統合することで、従来のDataikuモデルの利点を、外部に展開されたクラウドモデルに活用することができます。説明や評価のしやすさが向上し、ビジネスユーザーが使いやすいUIで組織のクラウドモデルに簡単にアクセスできるようになるため、より広範なAI導入が可能になります。さらに、すべてのデプロイされたモデルの包括的なビューは、組織のDataikuガバナンスモデルレジストリにあります。

![Untitled.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1196881/5408f044-ad7a-5f31-9180-4ef5748eedb9.png)
*Dataikuは、MLOpsのライフサイクルとなるコアを提供*

## 外部モデルの説明と検証
Dataikuのプラットフォームに外部モデルを接続することで、従来のクラウドモデルの可視化、モニタリング、ベンチマーキングを大幅に強化することができます。例えば、普遍的な機能の重要度やwhat-if分析などの[説明性の機能](https://www.dataiku.com/product/key-capabilities/explainability/)を活用することで、クラウドモデルの挙動をより理解し、動的に検証することができます。
![Untitled (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1196881/6ceace34-4e39-2972-8c8b-519af4c4d7e7.png)
*AWS SageMakerモデルでwhat-if分析を使用します。*

Dataikuで外部モデルを使用する場合、評価レシピを使用してクラウドモデルのパフォーマンスを簡単に監視し、Dataikuで設計されたモデルやMLFlowを使用したモデルなどの他の選択肢と比較することができます。さらに、自動化されたシナリオ、メトリクス、チェックを利用して、Dataikuとクラウドモデルのパフォーマンスのベンチマークロジックを作成することができます。

Evaluateレシピを使用して、外部モデルを検証したり、Dataikuが設計したモデルと比較したりできます。
## クラウドAIモデルをすべての人に普及させる
以前は、非技術系ユーザーがコードベースのモデルを利用する際に課題に直面していました。しかし、Dataikuの外部モデルを利用することで、ビジネスユーザーは導入済みのモデルを活用し、予測を実行して出力を得るプロセスを効率化することができます。スコアリングレシピと外部モデルを組み合わせることで、非技術系のDataikuユーザーは、コードベースのクラウドモデルから効率的に結果を得ることができます。
![Untitled (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1196881/87224fa2-5509-73cd-9e92-01bbcd0509bc.png)
*外部モデルを評価し、クラウドモデルから迅速な予測を受け取る*

## 外部でデプロイされたモデルのMLOpsを一元管理
前述したように、Dataikuは[MLOps](https://www.dataiku.com/ja/%e8%a3%bd%e5%93%81/%e3%81%ae%e4%b8%bb%e8%a6%81%e6%a9%9f%e8%83%bd/mlops/)のための組織の中心的な存在となることを目指しており、その起源に関係なく、すべてのモデルを管理・監視するためのプラットフォームを提供します。この完全な監視は、Dataiku Governのモデルレジストリで外部モデルを使用する場合、特に顕著になります。
![Untitled (4).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1196881/d5cca986-bcb7-5ed1-e181-2893c2f79f22.png)
*外部モデルは、Dataiku Governのモデルレジストリから閲覧・管理可能*

Dataikuで外部モデルを登録すると、他のネイティブモデルと同じように管理することができます。Dataikuは、MLFlowのシームレスな統合と外部モデルの取り込み機能により、AIに関連するあらゆるタスクのためのプラットフォームとして、すでにお客様の組織に包括的なAIソリューションを提供することをお約束します。間もなく、Dataikuのモデルはクラウド、Snowflake、Databricksなど、どこにでもデプロイできるようになり、外部システムとのシー ムレスな統合が可能になります。

## 一歩先へ：外部のモデルの実践
Dataikuの外部モデルに関するデモは[こちら](https://content.dataiku.com/c/external-models?x=raFR2S)からご覧ください。

原文：[Bridging the AI Divide: Revolutionizing Multi-Platform Integration With Dataiku's External Models](https://blog.dataiku.com/revolutionizing-multi-platform-integration-with-dataiku-external-models)
AWS Amplifyの超詳細解説

# はじめに
この記事はDevOps on AWS大全の一部です。
DevOps on AWS大全の一覧は[こちら](https://qiita.com/tech4anyone/items/b06f88035d27c6ef13b2)。

この記事ではAWS Amplifyはどういうサービスで何ができるのかを超詳細にまとめています。

具体的には以下流れで説明します。
- AWS Amplifyとは
- AWS Amplifyの仕組み
- AWS Amplify for Advance

AWSの区分でいう「Level 200：トピックの入門知識を持っていることを前提に、ベストプラクティス、サービス機能を解説するレベル」の内容です。

# この記事を読んでほしい人
- AWS Amplifyがどういうサービスか説明できるようになりたい人
- AWS Amplifyを採用するときのベストプラクティスを説明できるようになりたい人
- AWS Certified DevOps Engineer Professionalを目指している人

# AWS Amplifyとは
AWS AmplifyはWebアプリケーションのフロントエンドとモバイルアプリケーションを開発するためのプラットフォームです。

![](https://storage.googleapis.com/zenn-user-upload/480f2768f24c-20231110.png)

上図のように認証、ストレージ、API、CI/CDなどを構築し、接続するための仕組みがそろっています。

ただし、ElasticBeanstalk同様、手軽にサービスローンチできるメリットはあるものの、作りこみにくいというデメリットもあるためエンタープライズで採用することはあまりありません。

# AWS Amplifyの仕組み
AWS Amplifyは大きくバックエンドの構築部分とアプリケーションの実装部分の2つに分かれます。

ここではそれぞれについてを説明していきます。

## バックエンドの構築
バックエンドの構築にはAmplify CLIを利用します。
AWS SAM(AWS Serverless Application Model)を知っている人はSAMの類似だと思うと理解しやすいと思います。
なお、Amplify CLIはAWS CLIとはべつのCLIなので別途インストールが必要です。

Amplify CLIをインストール後はコマンドラインで対話的にバックエンドの設定を実施していきます。
バックエンドはカテゴリ、と呼ばれる単位に設定していきます。
具体的なカテゴリは以下になります。
![](https://storage.googleapis.com/zenn-user-upload/fce2111c8a7c-20231110.png)

注意点として2つ、覚えておいてください。

1つ目の注意点はaddコマンドで対話的に設定した後にpushコマンドを実行しないとバックエンドに反映されないということです。
updateやremoveも同様で、あくまでpushをして初めてクラウドに同期されバックエンド構築が実行されます。

現在の設定がpushまで終わっているかどうかはstatusコマンドで確認できます。

2つ目の注意点はバックエンドを構築した際に出力される設定ファイルがないとアプリケーションがバックエンドに接続できないという点です。

そのため、Amplifyを用いてサービス構築する際にはまずバックエンドから構築するようにしましょう。
また、出力された設定ファイルAmplify CLIが更新するため、直接編集しないようにしましょう。

## アプリケーションの実装
バックエンドの構築はAmplify CLIで対話的に行いましたが、アプリケーションの実装はAmplify Frameworkを利用して行います。

Amplify FrameworkはAmplifyカテゴリを使用するためのクライアントライブラリです。
このライブラリを用いることでカテゴリごとにスクラッチで開発するよりも手軽なアプリケーションが可能となります。

なお、Amplify Frameworkを利用するためにはバックエンド構築時に出力された設定ファイルを読み込む必要があります。
すでに書いた通り、先にバックエンドを構築してからアプリケーションの実装を行いましょう。

補足ですが、カスタムドメインを利用したい際にはRoute53を利用することで実現可能です。

## アプリケーションのデプロイ
アプリケーションの実装を行った後は実際のデプロイに入ります。
アプリケーションをデプロイする方法は2つあります。
1つ目はAmplify CLIを用いてS3とCloudFrontにデプロイする方法、2つ目はAmplify Consoleを用いてデプロイする方法です。

Amplify CLIを用いる場合、コマンドラインからデプロイできる反面、リポジトリとの連携やCI/CDの実装ができません。

一方、Amplify Consoleを用いるとマネジメントコンソールからの操作になる反面、リポジトリとの連携やCI/CDの実装が可能になります。

継続的なメンテナンスを考えるとAmplify Consoleがおすすめですが、初期開発でまずはデプロイして試験したい、という場合にはAmplify CLIでのデプロイでもよいでしょう。

# AWS Amplify for Advance
## AWS AmplifyのCD実装
AWS AmplifyはAmplify Consoleを用いてデプロイする場合、CodeCommitなどのリポジトリと接続してCI/CDを実現できます。

その際には1つのブランチにつき1つのデプロイメントとなるのが制約事項です。
そのため、開発環境はDevelopementブランチからデプロイ、本番環境はProducitionブランチからデプロイ、というようにデプロイメント先ごとにブランチを切るようにしましょう。

# まとめ
この記事ではAWS Amplifyはどういうサービスで何ができるのかを超詳細にまとめました。

- AWS Amplifyとは
- AWS Amplifyの仕組み
- AWS Amplify for Advance

次回から設定管理とIaCについてを順番に解説していきます。
Metabase + BigQuery で、日付型の変数のデフォルトを相対的にする

最近Metabaseを使い始めました。BigQueryに入っているデータをもとに、ダッシュボードを作りたい。

# やりたいこと

例えば「年月」「事業分類」「売上高」のカラムを持つデータセットがあるとして、これをMetabaseでグラフにしたい。(「年月」と名前が付いてますが実際は「日付」が入ってる)

このときの期間指定のデフォルトを「前月」にしたい。例えば今日が `2023-11-10` である場合 `2023-10-01` から `2023-10-31` の範囲のデータを表示させたい。

「まさにこれだろ！」と思った記事が下記。

https://qiita.com/kon_yu/items/281f1b490559473f1ad2

なのですが、こちらの記事は元データをPostgreSQLに入っているようで、BigQueryとは記法が異なっているようでうまくいきませんでした。。。

# やったこと

上記の記事を参考にしながら、ChatGPTに教えてもらいながら進めました。ChatGPTすげぇ。これ無しでは仕事したくない。

# 結論

テーブル名は適宜読み替えてください。補足として、カラム名が `scores.年月` になってますが、ここには `YYYY-MM-DD` の日付データが入ってます。

```sql
SELECT
  `scores`.`事業分類`,
  FORMAT_DATE('%Y-%m', `scores`.`年月`) as `年月`,
  SUM(`scores`.`売上`)
FROM
  `scores`
WHERE
  `年月` BETWEEN 
    [[ CAST({{from_date}} AS DATE) --]] DATE_TRUNC(DATE_SUB(CURRENT_DATE(), INTERVAL 1 MONTH), MONTH)
  AND
    [[ CAST({{to_date}} AS DATE) --]] LAST_DAY(DATE_SUB(CURRENT_DATE(), INTERVAL 1 MONTH))
GROUP BY `事業分類`, FORMAT_DATE('%Y-%m', `scores`.`年月`)

```

下記のようにMetabaseの画面で「変数」の設定をして実行しました。(値タイプを「日付」に)
本日が `2023-11-10` なので、2023年10月分だけが集計されています。

![sql.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8612/72c449a5-9494-3bd0-31ba-22f40c01304f.png)


# コード解説

こうなってくると通常のSQLでは機能しないです。特別な記法が必要なのですが、標準のSQLでいいのか、BigQueryの記法なのか、Metabaseの記法なのか、もはや良くわからないので、ChatGPTに聞きます。

## ChatGPTに教えてもらった

`WHERE` 句の中で使用されている構文は、Metabaseで動的な日付フィルタリングを実現するためのものです。具体的な動作は以下の通りです。

### WHERE 句の解説

- `年月` BETWEEN ... AND ...: 
  この部分は `年月` カラムの値が指定された2つの日付の間にある行をフィルタリングするために使用されます。

- `[[ CAST({{from_date}} AS DATE) --]]`:
  ここではMetabaseの変数機能を利用しています。`{{from_date}}` はユーザーがフィルタとして指定する日付です。
  - `CAST({{from_date}} AS DATE)`: ユーザーが入力した値を日付型に変換します。この変数が入力された場合、その値が `WHERE` 句の開始日として使用されます。
  - `--`: このダッシュは、Metabaseの変数が提供されていないときに、その後ろのコードがコメントとして扱われることを意味します。つまり、変数 `{{from_date}}` が空の場合、この部分は無視されます。

- `DATE_TRUNC(DATE_SUB(CURRENT_DATE(), INTERVAL 1 MONTH), MONTH)`:
  これは `{{from_date}}` が提供されていない場合に使用されるデフォルトの開始日です。
  - `CURRENT_DATE()`: 現在の日付を取得します。
  - `DATE_SUB(CURRENT_DATE(), INTERVAL 1 MONTH)`: 現在の日付から1ヶ月前の日付を計算します。
  - `DATE_TRUNC(..., MONTH)`: その月の最初の日（月初）に日付を切り捨てます。つまり、1ヶ月前の月の最初の日になります。

- `[[ CAST({{to_date}} AS DATE) --]]`:
  これもMetabaseの変数を利用していますが、今回は終了日に関するものです。
  - もし `{{to_date}}` がユーザーによって提供されれば、その値を終了日として使用します。

- `LAST_DAY(DATE_SUB(CURRENT_DATE(), INTERVAL 1 MONTH))`:
  これは `{{to_date}}` が提供されていない場合に使用されるデフォルトの終了日です。
  - `LAST_DAY(...)` 関数は、指定された日付の月の最後の日を返します。つまり、この場合は1ヶ月前の月の最後の日になります。

結果として、この `WHERE` 句は以下のように機能します：

- もしユーザーが `{{from_date}}` と `{{to_date}}` の両方を提供すれば、その範囲がフィルタとして使用されます。
- もしユーザーがどちらかの日付のみを提供すれば、提供された日付とデフォルトの日付の組み合わせがフィルタとして使用されます。
- もしユーザーがどちらの日付も提供しなければ、デフォルトの期間（前月の最初の日から最後の日まで）がフィルタとして使用されます。


# 次の課題

ひとまずこの「質問」(Metabaseでは一つのクエリ？を「質問」と呼ぶ) についてのデフォルト期間は設定できたのですが、一つのダッシュボードに複数のグラフ(質問をビジュアライズしたもの)があるときに、全てのグラフについてこのWHERE句を書く必要がある、、、のかな。

Metabaseに「SQLスニペット」という機能があるのですがフィルタまではスニペット化できないみたいなんですよね。。。

どなたか知見ございましたら教えてほしいです！
目的地をクリックしたら自動で連れて行ってくれる自動運転アプリを作りました

こんにちは。

タイトルの通り、アプリを自作してみました。

記事の詳細はこれから充実させていきます。

クオリティの高い記事が書けるまで公開しないスタンスだと、どんどんハードルが上がって結局公開するのを諦めてしまいそうなのでこのスタンスをとらせて頂きました。

さっそくですがアプリのリポジトリは以下になります。

https://github.com/catnap3/selfdriving-car

デプロイにあたり、Dockerを使いたかったのですが本アプリにはPythonのpygameというライブラリを使用しており、Dockerによるコンテナ化が非常に複雑とのことで、とりあえずPyInstallerを使用してGitHubにアップロードしました。

これから実装したい機能：音声認識の実装により、目的地を声で吹き込んだら該当の目的地に連れて行ってくれるようなアプリにしたいです。
AI-102試験対策のまとめ「Document Intelligenceサンプルラベル付けツールの使用」

## はじめに
Azure AI Engineer Associate(AI-102)取得に向けた勉強でまとめた内容を本記事では投稿しています。
試験範囲の内容を私が勉強していく中で、
・忘れてしまっていた内容
・他の知識と絡めて理解した方が良い内容
・Microsoft Learnの読解に苦戦した内容
などをできるだけ分かりやすく簡潔にまとめることを意識しています。
Azureの勉強を一から始め、AI-102取得を目指している方の参考になれば幸いです。
※本記事の内容が必ず試験に出るわけではないこと、ご注意ください
※勉強しながら投稿しているため、追加で学んだことがあれば随時投稿内容を更新します。

## 試験対策のまとめ
### Document Intelligenceサンプルラベル付けツールの使用
このツールはDocument Intelligenceや光学式文字認識(OCR)サービスの下記に示す最新機能をテスト可能にするオープンソースツール
| 機能 | 使用 | 抽出対象 | 抽出する内容 |
| --- | --- | --- | --- |
| ドキュメントの分析 | レイアウトAPI | ドキュメント | ・テキスト <br>・テーブル <br>・選択マーク <br>・構造 |
| ドキュメントの分析 | 事前構築済みモデル | ・請求書 <br>・領収書 <br>・IDドキュメント <br>・名刺 | データ |
| トレーニングと分析 | カスタムフォーム | ・個別のビジネスデータ <br>・ユースケース固有のドキュメント | データ |

#### **Documet Intelligenceリソースの作成**
1. Azure Portalで新しいDocument Intelligenceリソースを作成

#### **事前構築済みモデルを使用して分析**
1. [Document Intelligrnceサンプルツール](https://fott-2-1.azurewebsites.net/)に移動
1. 「事前構築済みモデルを使用してデータを取得する」を選択
1. ドロップダウンメニューから、分析する「フォームの種類」を選択
1. 「ソース」フィールドで、ドロップダウンリストから「URL」を選択
1. 分析するファイルのURLを貼り付けて、「Fetch」ボタンを選択
1. 「Form Recognizer service endpoint」にDocument Intelligenceリソースのエンドポイントを貼り付ける
1. 「キー」フィールドにDocument Intelligenceリソースのキーを貼り付ける
1. 「Run analysis」を選択すると、Analyze Prebuilt APIを呼び出してドキュメントを分析
1. 結果を表示し、下記を確認
    - 抽出されたキーと値のペア
    - 行項目
    - 抽出された強調表示テキスト
    - 検出されたテーブル
1. JSON出力ファイルをダウンロードして、詳細なレイアウト結果を表示

* 参考
    - https://learn.microsoft.com/ja-jp/azure/ai-services/document-intelligence/quickstarts/try-sample-label-tool?view=doc-intel-2.1.0


## 次の試験対策のまとめ
* **AI-102試験対策のまとめ「ビデオファイルから分析情報を取得」**

https://qiita.com/fsd-jume/items/88291181c3e61867e4ad

## 学習内容をまとめたページの一覧

https://qiita.com/fsd-jume/items/65aba5d5514e023fd66d
Nuxt 画像のパスの書き方三傑

+ 画像の置き場所
+ 書き方
複数人のプロジェクトの場合は開始前に決めたほうがよいかも。

## その1 imgタグ

assets/img/の中に画像ファイルを入れている場合
```demo.vue
<img src=“@/assets/img/画像ファイル名”>
```
static/img画像ファイルの場合
```demo.vue
<img src=“/img/画像ファイル名”>
```

## その2 cssの背景画像
assets配下の場合
```demo.css
background-image: url("~@/assets/img/画像ファイル名">
```
static配下の場合
```demo.css
background-image: url("/img/画像ファイル名">
```

## その3  v-bindで変数として使う場合
requireで囲む必要がある。

```demo.vue
data: function(){
  return {
    imgSrc: require('@assets/img/画像ファイル名’)
  }
}
```
GPTsで昼ご飯を提案するChatGPTを作成してみた

※2024/01/18 追記
本記事にて紹介している「Lunch Buddy」についてBizAI様の記事に掲載いただきました！
GPT Storeも公開されたので、この機会に是非下記の記事を閲覧して気になるGPTsがあれば利用してみてはいかがでしょうか。

https://www.kakudayoshiaki.com/gptsrecommendation/


# ChatGPTは次の時代へ
2023年11月6日、「OpenAI Dev Day」が開催されました。
今回ご紹介するGPTs以外にも多くの発表がありました。
内容については以下の記事がまとまっていましたので紹介いたします。

https://zenn.dev/umi_mori/articles/openai-dev-day-1


## 作成したChatGPT 「Lunch Buddy」
:::note warn
利用するためにはChatGPT Plusへの加入が必要です。
:::

https://chat.openai.com/g/g-7JwWLZjGF-lunch-buddy

* その日の気分、体調からメニューを提案します。
* 現在いる場所を伝えることでその場所の近辺のお店を検索して提案します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2781188/d6880523-b589-31ac-35ae-653618ae8b5a.png)


## GPTsとは
従来のChatGPTは、どのようなジャンルの質問もある程度カバーできる「汎用的なChatGPTモデル」でした。
GPTsは「特化型ChatGPTをカスタマイズできる機能」として提供されているものです。
公式が作成したサンプルとして
* 好きな食材を基にレシピを考案するChatGPT
* 数学に関する質問に答えるChatGPT
* ユーザが作成した文学作品を読み、フィードバックを提供するChatGPT

等が公開されています。

https://openai.com/chatgpt#do-more-with-gpts

## 作成方法
非常にシンプルです。
左のGPT Builderに対しコンテキストを投げながら理想どおりのChatGPTに仕上げていきます。
作成中のChatGPTは右のパネルにプレビューが都度表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2781188/f69f069b-3f5d-ca46-4e2b-12161f1f7dd2.png)


作成の流れですが
1. まずどのようなChatGPTになって欲しいかをテキストで伝える
1. アイコン画像やChatGPTのタイトルを相談して決める
1. 「コンテキスト内で情報が足りない場合の対応」「ChatGPTの性格」などを細かくカスタマイズする
1. 出来上がったドラフト版を試しながら気になる点を修正する

といった風に、基本的にはコンテキストを投げるだけで制作可能です。

## 作ってみての感想
誰でも気軽に作成が出来ることに加えて、「画像生成」「Web検索」などのChatGPT Plus(またはEnterprise)のユーザが利用可能な機能を使い分けながら回答を返してくれるため、非常にやりやすかったです。
「Confiuger」タブを開けば直接設定も可能なため、タイトルやアイコン、質問例は簡単に変更可能です。
今回は設定していませんが、アクションを定義することで作ったGPTsをAPIとして呼べることも可能なので「ChatGPTを用いたシステム開発」もかなり発展するのではないかと思っています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2781188/4277e2bd-e722-9fb1-42ac-d4148ae74e86.png)
初めてのpython cvxpy

# はじめに
これは [株式会社 RetailAI X Advent Calendar 2023](https://qiita.com/advent-calendar/2023/rai-adventurers) の 2 日目の記事です。

昨日は [@10long](https://qiita.com/10long) さんの記事でした。[RWKVをjuliaで試してみる](https://qiita.com/10long/items/dac17c82138883545ecb)

本日は、**「初めてのpython cvxpy」** です。  
今年、使う機会があったので少しだけ書きます。

# なぜcvxpy
できるだけ数式のままの表現で書けるので初心者にやさしい。

# とりあえずやってみる
実行環境は「**Google Colab**」
```
!pip install cvxpy
!pip install --upgrade cvxpy
```
[公式サイト](https://www.cvxpy.org/)のTOPページの例を参考にやってみます。
```python
import numpy as np
import cvxpy as cp

A = np.array([
    [ 1.76405235,  0.40015721,  0.97873798],
    [ 2.2408932 ,  1.86755799, -0.97727788],
    [ 0.95008842, -0.15135721, -0.10321885],
    [ 0.4105985 ,  0.14404357,  1.45427351]
])

b = np.array(
    [0.76103773, 0.12167502, 0.44386323, 0.33367433]
)


n = len(A[0]) # 用意する変数の数
x = cp.Variable(shape=(n,))

objective = cp.Minimize(cp.sum_squares(A @ x - b))
constraints = [
    0 <= x, 
    x <= 1
]
prob = cp.Problem(objective, constraints)
print(prob)

prob.solve(verbose=True)
```
xの値を見てみます
```
print(x.value)
```
`[2.35157320e-01, -5.06468160e-23,  2.61728416e-01]`

# ちょっとした気付き
いろいろポチポチやってた時の気付きになります。
```python
x = np.array([
    [1,2],
    [3,4],
    [5,6]
])
print(sum(x), np.sum(x), x.sum())
```
実行結果：`[9 12], 21, 21`です。  
numpyとcvxpyは似ている箇所もあり、復習になりました。

# 感想
ある程度決まった問題に対して、Google Colabで数値を少し変えてポチポチやってみるといい感じでした👍

明日は、[@yoshitake_tatsuhiro](https://qiita.com/yoshitake_tatsuhiro)さんです。お楽しみに！


# 参考

この記事は以下の情報を参考にして執筆しました。  
・[CVXPY](https://www.cvxpy.org/)  
・[【python cvxpy】モデリング言語cvxpyを利用して数理最適化問題を解く](https://note.com/fz5050/n/n4e3050b54ce3)
Lightning Experienceが遅い


+ [[Service Cloud] : レポートタブ（※赤枠）に戻ると、レポート結果でなく画面が真っ白になっている ](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007PvWe7)


+ 数十件のレコードを確認し、確認済みのタブを「×」で消去し、
　レポートタブ（※赤枠）に戻ると、レポート結果でなく画面が真っ白になっている

+ [F5] ボタン等で画面をリフレッシュすると、レポートは表示されるものの、
　レポート結果が一番上まで戻ってしまい、スクロールし直さなくてはならず、
　どこまで確認したのか迷子になるため不便である


 確かに使っているクライアントPCの性能によっても画面の表示速度は大きく変わると思います。

以下のヘルプを読むとパフォーマンステストが実施できるので、一度計測してみるのがいいかもしれません。

ページの読み込み時間を予測する上で最も重要な要素は、Octane 2.0 スコア、ネットワーク遅延、ダウンロード速度、および特定のページのカスタマイズ量です。

パフォーマンスは、Salesforce パフォーマンステストを実行して測定できます。テストを実行するには、speedtest.jsp を組織のドメインに追加します。

```
https://MyDomainName.lightning.force.com/speedtest.jsp
```

[Lightning Experience ページの速度とパフォーマンスの向上](https://help.salesforce.com/s/articleView?id=sf.technical_requirements_slow_load_times.htm&type=5)

 
[Lightning Experience のパフォーマンスと速度を向上させる](https://help.salesforce.com/s/articleView?id=000382793&type=1)
Laravel10の環境構築手順書(Mac, Laravel Sail)

# 対象
- 初めてmacOSでLaravelを触る方

# ゴール
- Laravelのトップページを表示できること
- phpMyAdminとの接続を確認できること

# 前提
##### Docker Desktopのインストールが完了している
以下のサイトよりDocker Desktopのイメージファイルを入手できます。
使用するPCのチップにあったものをダウンロードし、インストールを行ってください。

https://docs.docker.jp/desktop/install/mac-install.html

# 手順
### 1. Laravelパッケージのインストール

``` :CLI
curl -s "https://laravel.build/[アプリケーション名]" | bash 
```
コマンドラインを用い任意のディレクトリで上記のコマンドを実行することにより、Laravelのアプリケーションが作成されます。

アプリケーション名は自由に設定できます。
例えば```test```というアプリケーション名にしたい場合は
```curl -s "https://laravel.build/test" | bash```のように入力し実行してください。

```
Please provide your password so we can make some final adjustments to your application's permissions.

Password:
```
インストールの最後にパスワードを求められるので端末のパスワードを入力してください。

```Thank you! We hope you build something incredible. Dive in with: cd [アプリケーション名] && ./vendor/bin/sail up```と表示されればLaravelのインストールは完了です。



### ２. 設定ファイルの編集

##### 1. 作成されたフォルダ内の```config/app.php```でタイムゾーンと言語を変更する

```php:config/app.php
// 73行目付近
'timezone' => 'Asia/Tokyo',  // 'timezone' => 'UTC'から変更

// ８６行目付近
'locale' => 'ja',  // 'locale' => 'en'から変更

```
タイムゾーンと言語の設定を行います。



##### 2.フォルダ直下の```docker-compose.yml```を修正し、phpMyAdminの設定を追記する。

```yml:docker-compose.yml
services:
    laravel.test:
        build:
            context: ./vendor/laravel/sail/runtimes/8.2
#
# 中略
#

            retries: 3
            timeout: 5s
# 以下を追記
    phpmyadmin:
        image: phpmyadmin/phpmyadmin
        links:
            - mysql:mysql
        ports:
            - 8080:80
        environment:
            #PMA_USER: '${DB_USERNAME}'
            #PMA_PASSWORD: '${DB_PASSWORD}'
            PMA_HOST: mysql
        networks:
            - sail
# 追記ここまで
```
53行目付近、MySQLの設定が記載されている下に追記するのが良いかと思います。
追記の際にはインデントの深さに注意してください。（追記箇所１行目の```phpadmin:```のインデントは```laravel.test:```と同じ深さになるように記載してください）


### 3. 起動確認

```:CLI
./vendor/bin/sail up -d
```
上記のコマンドでアプリケーションを起動することができます。
起動後に```http://localhost```にアクセスすると、下のようなLaravelのトップページが表示されることを確認してください。
![スクリーンショット 2023-09-14 1.46.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3556044/f236bd77-4158-dc02-cc7c-fe05333d203a.png)

さらに```http://localhost:8080```にアクセスすることでphpMyAdminに接続できます。
![スクリーンショット 2023-09-14 1.52.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3556044/6f1ff881-013a-8103-a577-6fc309c9d66c.png)

phpMyAdminのユーザー名、パスワードはそれぞれ```.env```ファイルの```DB_USERNAME```、```DB_PASSWORD```に対応しており、デフォルトではユーザー名が```sail```、パスワードが```password```に設定されています。

ログインができればセットアップは完了です。

なおCLIで```./vendor/bin/sail stop```を実行することでアプリケーションを終了することができます。

# 参考
https://readouble.com/laravel/10.x/ja/installation.html
SwaggerUIをIISサーバーに公開してみる

# 1. はじめに
* C#で開発しているOpneAPIのエンドポイントをWebサーバに公開したい
* Visual Studioでデバッグでビルドした時に表示されるSwaggerUIは開発者のみしか参照できないので全員に公開したい

# 2. 開発環境
* Windows Server
* IIS

# 3. 事前準備
* GitHubよりSwaggerUIを一式ダウンロードする。

https://github.com/swagger-api/swagger-ui

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852081/722ac5eb-9853-cee5-7c3f-de171f81df2f.png)


# 4. IISサーバーへの配置
## 4.1. SwaggerUIのファイルをコピーする
* ダウンロードしたSwaggerUiのdistフォルダ配下を下記へコピーする。

![image 11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852081/9d64cbb1-b60f-dfb0-b202-e87f5e55604d.png)

## 4.2. アプリケーションへの変換をする
* 対象フォルダを右クリックしてアプリケーションの変換を選択する
![image 12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852081/c1114722-8670-94df-5a93-b694f1266e54.png)

* OKボタンをクリックする
![image 14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852081/d4934c28-2892-4eb2-13d6-04b9153d18f3.png)

* アプリケーションへの変換が完了する
  ![image 13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852081/42d9f497-b872-5596-a6ac-f079ae942f30.png)

## 5. 動作確認
* IISからSwagger UIが確認できるようになった。
 ![image 15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852081/e37f2dc2-1a2c-d0ac-3d35-24bb98b20616.png)

## 6. エンドポイントの修正
* swagger-initializer.jsの下記URLを変更することで任意の設定に変更できる。
![image 16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852081/73d23c3a-edd7-63c4-b86f-7bdf3baccbb9.png)

## 7. 参考文献

https://github.com/swagger-api/swagger-ui
質の高い振り返りへの近道！？シンプルだけど効果絶大なたった一つのルール

### はじめに

* スクラムイベントの一つである振り返り（レトロスペクティブ）で取り入れてみた方法がとても良いなと感じたのでご紹介します
* チームの振り返りが形骸化していると感じ、少しずつですが改善策を提案してきました
* 名ばかりスクラム、振り返りの質を上げたい、なんだか最近形骸化してきているそういった方々に読んでいただき、何か良いきっかけになれば幸いです


### ルールを追加し、振り返りをした結果・・・

チームの皆さんから、とても良い素敵なコメントをいただきました！

**『視点が変わった！！:sparkles:』**
**『いつもよりポジティブな気持ち:ok_hand:』**

こんな素敵なコメントなんて、なんぼあってもいいですからね〜


![スクリーンショット 2023-11-09 23.26.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2899739/9248740d-4e48-87cf-2dd4-ea74b46ac101.png)

我ながら個人的にも、『良い提案だったのでは？:sunglasses:』と思ってます 笑

### たった一つ、追加したルールとは

今回、何をルールとして追加したかというと・・・

:::note info
Good３：Problem 1 の割合で付箋をはっていく
:::

（※振り返りの手法としてはKPTを使っています）



**１つの問題（Problem）に対して３つの良かった点、ポジティブな点**を考えて書いていくようにしました

これは **ロサダライン** と呼ばれるもので、問題点を上げるということはネガティブな感情になってしまいがちですが、
ポジティブな面を考えることによってネガティブな感情をニュートラルな視点にするという効果をもたらすようです。

１つのネガティブに対し、３つのポジティブという比率はネガティブな感情がいかに心理的な影響を及ぼすかを物語っていますね〜:ghost:

https://www.altus5.co.jp/blog/team/productivity/2022/12/14/lozada-line/

### Goodな点を持つことが根本的な解決につながる
:::note alert
問題というのは、表面的なもの"症状"にすぎない。
:::

上記はどういうことかというと、

「鼻がつまっている」という例を用いて、話をしていきます。

「鼻がつまる」は症状です。その症状を問題として置き換えた場合

症状の対処としては「ティッシュで鼻をかむ」となります。

ですが、その時は改善されても問題は長引いてしまう、または悪化してしまう可能性があります。

この「鼻がつまっている」という根本的な原因はかぜ、免疫力の低下等があげられます。

つまり、


**根本的な原因は問題と全く別のところにある**


という点で、**問題を問題としてみるのではなく違った視点で見ることが大切**

![ポジティブな視点.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2899739/91669cc6-a29f-107d-8c33-3f57531d0203.png)


そこで、**ポジティブな視点**が必要であり、問題解決の鍵になるということです。

```
* 問題から距離を置くので、今までと違った考え方ができる

* 今まで見えてなかった根本的な原因が見える
```

※参考元

https://www.youtube.com/watch?v=Cy6lJg8d0_Y&t=138s


### 導入方法、どんなふうに提案したか


『振り返りをやる前に考え方として良いなと思ったものがあるので
ちょっとみて欲しいです』

と、提案し[参考にしたYoutubeの動画](https://www.youtube.com/watch?v=Cy6lJg8d0_Y&t=138s)を見てもらいました！

ただ、この動画は20分弱あるので全て見てもらうのは時間も負担もかかってしまうかなと思い
私が見た中でここだけ見てほしい！という部分に絞り、実際見てもらった時間は5分程度です。

たった5分、たった一つルールを追加しただけですが、気持ち的にも振り返りの内容的にも
とても良くなったなと感じました。

### さいごに

振り返り＝反省会のようになってしまいがちですが、
良い点に目を向けて改善策を考えるとさらにもっと良くしていこうという気持ちが自然と湧いてきます。

もっとGoodな視点をもつ事をポイントに振り返りを行ってみてはいかがでしょうか？:relaxed:

最後までお読みいただきありがとうございました。
Email Template Builder とPardot

[Pardotの質問と回答をまとめに戻る](https://qiita.com/Keiji_otsubo/items/a3ccd1370697dd914723)
[Pardot : メール関係のまとめに戻る](https://qiita.com/Keiji_otsubo/items/23d8d7d8a5b89b940c03)

+ [既存の機能の詳細については、ブログ記事「Pardot Lightning メールビルダーについて知っておくべきことすべて」をご覧ください。](https://thespotforpardot.com/2022/01/03/everything-to-know-about-the-pardot-lightning-email-builder/)
+ [新しいメール エクスペリエンス ビルダー　pardot](https://qiita.com/Keiji_otsubo/items/439f3766e59993903353)


# A/Bテストが機能しない

+ [Email Template Builder A/B Testing](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007PhbWs)

:::note
Looks like this is still an idea: 

https://ideas.salesforce.com/s/idea/a0B8W00000J5sbOUAR/create-ab-test-with-pardot-lightning-email-content-builder
:::

# We can’t save the record. Ensure the provided email template was created using the Email Template Builder and doesn’t contain Salesforce files.

+ [Hi, I am new to Pardot emails, I've created a email template in the builder, tried saving them on email content. I'm getting this error message. Anyone experienced the same? can you share the solution?](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000PfCVh)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/bf2a5cb4-2359-5d27-d304-ed47d600ecbf.png)


:::note
can check if below resolves your issues.
1. When creating the email template, you need to tie the template to a specific object, only then you can use those templates for specific objects. For example, if you specify related entity as contact while creating template in lightning builder, you can access the template to send emails on Contact

2. When creating template, use upload images to the CMS content and use those images. This should resolve the second issue

https://www.salesforceben.com/your-complete-guide-to-salesforce-lightning-email-templates/


以下で問題が解決するかどうかを確認してください。
1. 電子メール テンプレートを作成するときは、テンプレートを特定のオブジェクトに結び付ける必要があります。そうすることで、特定のオブジェクトに対してそれらのテンプレートを使用できるようになります。たとえば、Lightning Builder でテンプレートを作成するときに関連エンティティを取引先責任者として指定すると、テンプレートにアクセスして取引先責任者にメールを送信できます。

2. テンプレートを作成するときに、CMS コンテンツに画像をアップロードし、それらの画像を使用します。これで 2 番目の問題が解決されるはずです
:::

# メールの幅

+ [Account Engagement - Lightning template builder](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007ReUIv)

:::note
Its a responsive template but the maximum width is designed to be 600 pixels wide. Use double the resolution images for greater quality on mobile devices.  A template is not the place to preview things. Build a template and then experiment with it it in email content. 


レスポンシブなテンプレートですが、最大幅は 600 ピクセル幅になるように設計されています。モバイル デバイスでの品質を高めるには、2 倍の解像度の画像を使用します。テンプレートはプレビューする場所ではありません。テンプレートを作成し、電子メールのコンテンツでそれを試してみましょう。
:::

+ [Pardot Lightning Email Builderでセクションの背景色を変更したり、水平線を追加したりできますか？](https://trailhead.salesforce.com/en/trailblazer-community/feed/0D54S00000Fy10M)
Humhub 1.15.0 へのアップデート対応

ここ数年、社内Humhubのメンテナンスと独自機能の追加作業をしています。今回、珍しくシステムアップデートに工夫が必要になったので記録しておきます。

## 1.15.0へのアップデートで発生するかもしれない障害
・閲覧には問題がないが、投稿しようとするとエラーになる。

## 1.15.0へのアップデート
MySQL側で、
```sql
ALTER TABLE `content` ADD `was_published` BOOLEAN NOT NULL DEFAULT FALSE AFTER `state`;
```
とすると正しく動作するようになります。

## 参考
Content state flag "was published" #6626
https://github.com/humhub/humhub/pull/6626
https://github.com/humhub/humhub/commit/6376b93ace0efc90c04a0de8caee57684a256061
【JavaScript・初学者】コンポーネントの基礎となるモジュールのメリットを押さえる

# はじめに
`JavaScript`についてフワッとしている部分がよくあったので、簡単ですが今回は**モジュール**について少し調べました。

# モジュールがない場合のデメリット
まず、モジュールがない場合のデメリットを考えてみましょう。
このように、2つの`script`タグが存在し、`greet`変数の定義とコンソールに`greet`変数を表示させるとします。

```html
<body>
	<script>
		const greet = 'おはよう';
	</script>
	<script>
		console.log(greet);
	</script>
</body>
```

ここで押さえておきたいのが**JavaScriptコードが他のScriptタグで囲まれたコードも参照できてしまう**ということです。

言い換えると、**グローバルな名前空間(スコープ)になっておりどこからでもgreet変数が参照できる**ということです。

**どこからでもgreet変数呼べるなら便利じゃん！** って思いますよね？

例えばコードがどんどん多くなった場合を考えてみましょう。

例えば**Aさん**が`greet`変数を定義し、100行目で1行目に指定した`greet`変数を使うと問題なく**おはよう**が表示されます。

```html
<body>
　　　　　 　<!-- 1行目 -->
	<script>
		const greet = 'おはよう';
	</script>
 　　　　　　<!-- 100行目 -->
 　　<script>
		console.log(greet);
	</script>
</body>
```

一方で、**Bさん**が200行目付近で1行目で定義されている`greet`変数に気づかずに再定義したとします。

そうすると、既に他の`script`タグ内で`greet`変数は定義されてしまっているため、`Uncaught SyntaxError: Identifier 'greet' has already been declared`というエラーが起きてしまいます。

コードの影響範囲が大きくなることで**思わぬバグ**を生みやすいので**スコープは狭くした方がいい**というのが一般的な考えです。

```html
<body>
　　　　　　 <!-- 1行目 -->
	<script>
		const greet = 'おはよう';
	</script>
 　　　　　  <!-- 100行目 -->
  　<script>
		console.log(greet);
	</script>
           <!-- 200行目 -->
    <script>
		const greet = 'こんにちは';
	</script>
 　　<script>
		console.log(greet);
	</script>
</body>
```

# モジュール化
先程の話の続きだと、scriptタグのままだと名前空間がグローバルになるという話をしました。その問題を解決するのが`モジュール`です。

このように`type="module"`を付与することで、名前空間が`script`の中だけで収まるようになり、**同じファイルの中でも同じ変数名が衝突せずに参照する**ことができます。

```html
<body>
	<script type="module">
		const greet = 'おはよう';
        console.log(greet);
	</script>
    <script type="module">
		const greet = 'こんにちは';
		console.log(greet);
	</script>
</body>
```
[![Image from Gyazo](https://i.gyazo.com/64a465131f7dc5853a0197f7e3737213.png)](https://gyazo.com/64a465131f7dc5853a0197f7e3737213)


# まとめ
モジュール化を行うことで、**名前空間(スコープ)を狭くできる**ので変数名などの衝突を防ぐことができます。
一般的には、`type="module"`ではなく、ファイル分割によってモジュールを読み込んでいくので、今後は`Export/Import`について深掘りしていきます。
自動運転シミュレーション その7

# 概要
自動運転シミュレーションを開発している。
キャプチャーしてみた。

# 動画

ゴール、しちゃった。

<iframe width="560" height="500" src="https://www.youtube.com/embed/fp8gBz_XVBQ" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" loading="lazy" allowfullscreen></iframe>


# 説明

- livebookでserverを起動する。
- websocketでポート50002で、待つ。
- plunkerで環境を動かす。
- websocketに接続して、センサーの値をjsonで送る。
- agentがセンサーのデータを見て、actionを返す。
- 環境がハンドルをきる。
- の繰り返し。


以上。
Pythonで「文字列の中の文字が大文字か小文字かを判定する(islower, isupper, istitle)」の動作を確認してみた

# 概要

Pythonで「文字列の中の文字が大文字か小文字かを判定する(islower, isupper, istitle)」の動作を確認してみました。以下のページを参考にしました。

https://www.javadrive.jp/python/string/index13.html

# 実装

以下のファイルを作成しました。
```sample.py
print("apple".islower())
print("Hello".islower())
print("apple100".islower())
print("max値".islower())
print("ｈｅｌｌｏ".islower())
print("Ａｐｐｌｅ".islower())
print("2019".islower())
print("東京都".islower())

print("APPLE".isupper())
print("Hello".isupper())
print("ORANGE100%".isupper())
print("MAX値".isupper())
print("ＡＰＰＬＥ".isupper())
print("Ｏｒａｎｇｅ".isupper())
print("2019".isupper())
print("時計".isupper())

print("Music Video".istitle())
print("THE Movie".istitle())
print("7Color Border".istitle())
print("Best100 Songs".istitle())
print("Pixel7a Xl".istitle())
print("1000".istitle())
print("汽車".istitle())
```

以下のコマンドを実行しました。
```
$ python3 sample.py 
True
False
True
True
True
False
False
False
True
False
True
True
True
False
False
False
True
False
True
True
False
False
False
```

# まとめ

何かの役に立てばと。
PythonでWindowsの壁紙を動的に変更させる方法

PythonからWindowsのデスクトップ壁紙を変更できます。
画像を自動生成して天気用法の表示的なものが出来そうです。
ChatGPTに投げて、なんか出来たため書いときます。
```python
import ctypes
import os
import time

# 壁紙を変更する関数
def change_wallpaper(image_path):
    if os.path.isfile(image_path):
        ctypes.windll.user32.SystemParametersInfoW(20, 0, image_path, 3)
    else:
        print("指定されたパスに画像が存在しません。")

# 壁紙リスト(画像パス))パスを書き換えてください。
wallpapers = [r"C:\Users\User\Desktop\a.png",r"C:\Users\User\Desktop\b.png"]

# 壁紙を変える
while True:
    change_wallpaper(wallpapers[0])
    time.sleep(0.1)
    change_wallpaper(wallpapers[1])
    time.sleep(0.1)
```
ArchLinuxでPlaywright動かした時の備忘録

結構沼ったのでメモ

```sh
sudo pacman -Sy nss nspr libxslt opus harfbuzz openjpeg2 libwebp enchant hyphen pcre glib2 libffi x264 dbus-glib libevdev woff2 harfbuzz-icu libgudev

yay -S icu66 libwebp052 libffi7 enchant1.6

sudo ln /usr/lib/libpcre.so.1 /usr/lib/libpcre.so.3

git clone https://github.com/festvox/flite.git
cd flite
./configure --enable-shared
make
make get_voices

sudo cp build/x86_64-linux-gnu/lib/libflite.so.1 /usr/lib
sudo cp build/x86_64-linux-gnu/lib/libflite_cmu_grapheme_lang.so.1 /usr/lib
sudo cp build/x86_64-linux-gnu/lib/libflite_cmu_grapheme_lex.so.1 /usr/lib
sudo cp build/x86_64-linux-gnu/lib/libflite_cmu_indic_lang.so.1 /usr/lib
sudo cp build/x86_64-linux-gnu/lib/libflite_cmu_indic_lex.so.1 /usr/lib
sudo cp build/x86_64-linux-gnu/lib/libflite_cmu_time_awb.so.1 /usr/lib
sudo cp build/x86_64-linux-gnu/lib/libflite_cmu_us_awb.so.1 /usr/lib
sudo cp build/x86_64-linux-gnu/lib/libflite_cmu_us_kal.so.1 /usr/lib
sudo cp build/x86_64-linux-gnu/lib/libflite_cmu_us_kal16.so.1 /usr/lib
sudo cp build/x86_64-linux-gnu/lib/libflite_cmu_us_rms.so.1 /usr/lib
sudo cp build/x86_64-linux-gnu/lib/libflite_cmu_us_slt.so.1 /usr/lib
sudo cp build/x86_64-linux-gnu/lib/libflite_cmulex.so.1 /usr/lib
sudo cp build/x86_64-linux-gnu/lib/libflite_usenglish.so.1 /usr/lib

cd ../
rm -rf flite/
```

下記だけだと不足だった
https://github.com/microsoft/playwright/issues/8100#issuecomment-1709257896
提升職涯發展：如何打造引人入勝的Statement of Purpose

在現今競爭激烈的職場環境中，[海外實習](https://www.apexcharity.org/news/3/87)成為了許多學生和專業人士追求的機會。然而，要成功地獲得這樣的機會，你需要一份精心製作的[英文履歷](https://www.apexcharity.org/news/3/91)（[CV](https://www.apexcharity.org/news/3/88)）和一封引人入勝的Statement of Purpose。本文將探討如何製作一份令人印象深刻的Statement of Purpose，以幫助你實現海外實習的夢想。

首先，讓我們明確[Statement of Purpose](https://www.apexcharity.org/news/3/90)的意義。這是一封簡短但充滿深度的信函，通常用於申請海外實習機會，旨在向招聘者展示你的動機、目標和適應能力。它不僅是一個機會，讓你展示自己的專業素養，還是一個展示你的英語寫作和表達能力的機會。

在撰寫Statement of Purpose時，首先要明確你的目標和動機。你應該詳細說明為什麼想參加這個海外實習計劃，以及你期望從中獲得什麼。這可能包括對特定領域的熱愛，對跨文化體驗的渴望，或者對某個國家或地區的興趣。確保你的動機是真誠的，這將有助於讓招聘者感受到你的熱情和承諾。

接下來，你需要展示你的資格和適應能力。列舉你的教育背景、實習經驗、技能和特質，以證明你是一個合適的候選人。強調你的英語語言能力，因為這是參加海外實習計劃的關鍵。同時，請提供具體的例子來支持你的陳述，展示你在過去的經歷中取得的成就和學習。

最後，注意文筆和結構。一份引人入勝的Statement of Purpose應該清晰、簡潔，並具有一定的流暢度。確保避免拼寫和語法錯誤，並遵循正確的格式。在結尾處，再次強調你的興趣和承諾，並表達對機會的期待。

總之，成功的Statement of Purpose是獲得海外實習機會的關鍵。透過明確的動機、強調的資格和流暢的表達，你可以打造一份令人印象深刻的信函，讓你脫穎而出，實現職涯發展的夢想。不要忘記仔細檢查和編輯，確保每個字都能為你的申請增色不少。
R 基本統計量を出す/stargazerを用いた見やすい統計表/stargazerによる中央値の求め方

**R言語で基本統計量を出す**

統計解析でよく使われるアヤメirisを用いて基本統計量を出します。
これはirisと書くだけで、特にパッケージを開かなくても扱うことが出来ます。

# summary関数で出す

```r
matome<-summary(iris)
matome
```

一方でこの出力は味気なく、あまり見やすい物ではありません。


### 見やすい統計表の作成

```r
install.packages(stargazer)
library(stargazer)
stargazer(iris,median=TRUE,type="text",
          title = "タイトル",
          covariate.labels = c("A","B","C","D"))
```
こちらでmedian = TRUEを入れることで、中央値が出てくる
Pythonにおける日本（東京）時刻の取得　※Google colabでdatetimeを使用

# Pythonにおける日本時刻の取得について書く。

*このコードはGoogle colabで使用することを想定しています。*

## 目的
**Google colab上で日本時間を取得して格納すること**


まず一般的に現在の時刻を取得する方法は下記のコードである。
```python
import datetime 
now = datetime.datetime.now() 
```
しかし、これは**UTC時刻**であり、**日本時刻**とは違います。
Google Colabでは協定世界時をデフォルトにしているため、これを日本時間に直す必要があります。



## 日本時間の取得方法

```python
import datetime 
from pytz import timezone
now = datetime.datetime.now() #現在時刻生成
now = now.astimezone(timezone('Asia/Tokyo')) #タイムゾーンを東京に
```

上記を付け加えることで、**now**に現在の東京の時刻を格納することができる。
如何充實你的Statement of Purpose：融入海外實習經驗


在現今競爭激烈的求職市場中，擁有豐富的[海外實習](https://www.apexcharity.org/news/3/87)經驗是一個極具吸引力的優勢。然而，要想成功地展現這些經驗並吸引潛在雇主的關注，你需要在你的[Statement of Purpose](https://www.apexcharity.org/news/3/90)（申請動機聲明）中巧妙地整合這些寶貴的經歷。本文將探討如何在Statement of Purpose中突顯海外實習經驗，讓你的申請脫穎而出。

海外實習：開啟你的國際視野
海外實習提供了一個獨特的機會，可以擴展你的視野，增加你的跨文化經驗，並豐富你的履歷。這不僅僅是一段在異國工作的時間，更是一個寶貴的學習機會，你可以學到新的事物、結交新的朋友，並在一個不同的文化環境中挑戰自己。在Statement of Purpose中，你可以通過描述你的海外實習經歷，強調你的國際視野和跨文化交流技能。這將讓雇主看到你不僅有專業知識，還有適應多樣文化的能力。

[英文履歷](https://www.apexcharity.org/news/3/91)與[CV](https://www.apexcharity.org/news/3/88)：展現你的實力
在你的Statement of Purpose中，你可以參考你的英文履歷（Resume）或CV中的關鍵信息，以增強你的可信度。確保你的履歷清晰、簡潔，並突出強調你在海外實習中所取得的成就和貢獻。這些成就可以包括你參與的專案、解決的問題，以及你在團隊中的角色。通過將履歷中的關鍵信息與Statement of Purpose相互呼應，你可以營造出一個一致且有力的求職形象。

Statement of Purpose：闡述你的目標和動機
最重要的是，Statement of Purpose應該清晰地闡述你的目標和動機。在這份文件中，你需要說明你為什麼選擇了海外實習，以及這段經歷如何與你的職業目標相關聯。你可以提到你在海外實習中所學到的技能，以及如何打算在未來的職業生涯中應用這些技能。這樣可以讓雇主看到你不僅僅是一個有經驗的求職者，還有清晰的職業規劃和目標。

總之，海外實習是一個寶貴的經歷，可以在你的求職過程中提供重要的優勢。通過巧妙地整合海外實習經驗到你的Statement of Purpose中，你可以讓自己脫穎而出，吸引雇主的關注，並增加成功的機會。記住，清晰地表達你的動機和目標是一個成功Statement of Purpose的關鍵元素，因為這將幫助雇主了解你為什麼是他們的理想候選人。
Pythonでファイルの命名に時刻を用いる方法 ※Google colabでdatetimeを使用

# Pythonでファイルの命名に時刻を用いる方法について書く。


*このコードはGoogle colabで使用することを想定しています。*


## 目的
**Google colab上で日本時間を取得して格納すること**
**日本時間をファイル名に用いること**


コンペなどを行う際に、csvファイルの名前をどうつけるかで迷ったことがないだろうか、
その際に、**現在時刻でファイル名を自動で決められたら楽**だと思って、こちらにコードを示します。


まず現在の時刻を取得する方法は前の記事で示したように下記のコードである。

```python
import datetime 
from pytz import timezone
now = datetime.datetime.now() #現在時刻生成
now = now.astimezone(timezone('Asia/Tokyo')) #タイムゾーンを東京に
```

https://qiita.com/hinata1119/items/c21655c637702a5c7548

これによって
**now**に現在の東京の時刻を格納することができた。




# ファイルの命名

次はこちらのコードを記入して、csvファイルの命名に取得した時間を用いてみる。

```python
CSV_NAME = now.strftime('%m%d_%H%M')
sample_submit.to_csv(f'{CSV_NAME}.csv', index=False, header=False)
```

これによって

ファイル名:(現在の)***時間分.csv***というファイル名でsample_submitのようなデータフレームをCSVとして保存することができる。

また、f-stringを使うことでも時刻フォーマットを作成できます。
```python
sample_submit.to_csv(f'{now:%m%d_%H%M}.csv', index=False, header=False)
```
Rによる標準化　欠損値があるとき

# Rで標準化を実行する

## 標準化とは
標準化とはデータの平均が0、標準偏差が1になるように変換すること。
分布を変数間で似た形にすることで、回帰分析などで、偏回帰係数を比べたい時などに使われる。

## scale関数
Rには標準のscale関数があり、それを使うことで標準化を実行することができる。
```r
scale(df$列名)
```
しかし、列に欠損値があるときにはエラーとなってしまうことがある。

その時のために、確実にエラーが出ないようなコードを示す。

## scaler関数(自作関数)
```r
scaler<- function(a){
  ue<-a-mean(a,na.rm = TRUE)
  sita<- sqrt(var(a,na.rm = TRUE))
  ans<-(ue/sita)
  return(ans)
}
```

使い方はscale関数のように下記のようにすればよい。

```r
scaler(df$列名)
```
TLS1.3意外と普及してる? TLS1.0, 1.1の終焉に向けて (JPAAWG Open Round Table議事録)

# SMTPのTLSのバージョンの議論

## はじめに

11/6,7に金沢文化ホールで行われたJPAAWG 6th General MeetingのOpen Round TableでメールのSTARTTLSにおけるTLSバージョンについて議論しました。

その時紹介したデータは、後で別の記事にまとめます。
ここでは、そこで行われた議論についてまとめておきます。

あくまで、その場での意見交換の議事録なので、情報の誤りなどはあるかも知れません。

## どのバージョンが使用されているのか

- すでにTLS 1.3を採用し、TLS 1.0/1.1の使用を廃止している ==> 3,4社
- TLS1.3をちゃんと使う側としては、みんなちゃん守って良い方向に行ってほしい。

## なぜTLS1.0/1.1を廃止できないのか。
- 残したいわけではない。手が回らない
- sendmailを改造しすぎて新しいOSでbuildできない

## 1.0/1.1を廃止できたところはどうやったのか
- メールが到達しないのであれば問題であるが、平文になって送信はできるので1.0/1.1は廃止できた
- Security診断で高得点が得られる (実際には平文にFallbackされていても、診断ソフトは平文かどうかは見ず、TLSのバージョンを見る) 

## 平文で送ることは問題ではないのか?
- STARTTLSが極端に遅い環境がある
   - 1分間100通くらい。平文だと500～1000
   - 定期的にopensslでテストするけど、TLSで送ると体感的に遅いところがある
   - STARTTLS中のhandshakeが遅いと感じる。(複数人)
   - 暗号化方式がRSAか楕円曲線のかでも速度は変わると思う
- 1.0/1.1を中途半端に使うなら、平文で送る

## 平文 vs 古いTLS(1.0/1.1) どちらが良い？
- downgrade attackができるので1.0/1.1より平文のほうがまだ良い。
- セキュリティの脆弱性がある。
   - 1.0/1.1を許可すると1.3をちゃんと使いたい相手が脆弱になる可能性があるので平文が良い。
   - tls protocolの中のclinet-heloでバージョン指定出来る。

## TLS1.1が少ない理由は？
- TLS1.2が2年後に出たので、opensslでは利用できるTLSの最大のバージョンが1.1というバージョンが存在していない

## WebだとTLSは最新が当然だけど、mailの世界はなぜ違うのか
- ブラウザはすぐupdateできるるけど、mailサーバははそれができない
- ブラウザはwindosw/macのosがすぐアップデートされるから

## Webもブラウザ側は常に最新だとしても、Webサーバを最新にする大変さはメールサーバと同じなのでは?
- webサーバのTLSバージョンが古いと、ブラウザで警告がでるから。積極的にverupする
- webは新しい機能が増えたりトラフィックが増えて、新しいサーバにすることが多い。メールはそういうのがなく古い環境がそのまま残る。
- 平文へのfallbackで、配送を優先するから困らない、というかどのバージョンで通信しているか気にも留めていない。
- webはブラウザの関係者が頑張ったから。

## 危ないということを伝えられるかどうかの違い
- webブラウザでは開く前に警告が出来るけど、メールは送った後、MTAや受信た後でないと安全かどうかもわからない。
- MTAで送る前にTLSを確認する製品もあるけど、全MUA/MTAがそうではない。
- gmailでheaderにtls versionが書かれている。
- Gmailに鍵マークが表示されるようになったことでSTARTTLS対応したところもある。
- Gmailで鍵マークが出るようにしたいという動機も意外と大きい。

==> 鍵マークなど、見える化して啓蒙していくのも良いかも。



## TLSのバージョンの範囲はopensslのバージョンのみに依存するのか?
- そうではない。アプリケーションやその設定が対応している範囲とopensslの対応範囲のAND部分になる
- SSLライブラリの対応バージョン x MTAの対応バージョン x クライアントの対応バージョン

## メーラで受信するのとwebメールで受信するのは違う？
- webメールはsmtpとhttps両方の話になる。

## 今後の展望とアクションプラン
- 現状は古いバージョンでも平文でもメール届かないわけでもないので認識が低い。
- 受信側でGmail鍵マークなど表示して啓蒙していくのはバージョンアップのモチベーションアップにつながるのでは？
- osバージョンアップすると自然にあがるのでは?
- osバージョンアップしないとやばいよという認識に持って行きましょう。
- PCIDSSなど制約のある業界だとTLS1.2じゃないと受付ないというところもある。
- DANE/MTASTS使うためには1.2以上じゃないと使えない。
- **見える化を促進し、バージョンアップしないといけない機運を高める**

## さいごに
みなさんは、どのように考えますでしょうか。
コメント欄などにもぜひご意見ください。

JPAAWGではこのような議論を活発に行っています。メールに係わる人はいつでも歓迎します。
[Swift] ハーフモーダルを実装

<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3569708/0f919d7d-cc84-be79-85a9-4bdcf5dfbda3.png width=30%>
<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3569708/5fc3de37-fc8b-14f4-b344-fe4d91af5854.png width=30%>

Show Modalボタンを押下すると2枚目のようにハーフモーダルが表示され、cancelボタンクリックかモーダルを下にドラッグすると１つ目の画面に戻るような処理の実装。

### 全体のコード

```ViewController.swift
import UIKit

class ViewController: UIViewController {
    
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        let next = segue.destination
        if let sheet = next.sheetPresentationController {
            sheet.detents = [.medium()]
            sheet.largestUndimmedDetentIdentifier = .medium
            sheet.preferredCornerRadius = 40.0
            sheet.prefersGrabberVisible = true
        }
    }
    @IBAction func exit(segue: UIStoryboardSegue) {
        
    }
}
```
```ModalViewController.swift
import UIKit
class ModalViewController: UIViewController {
  
}
```

### 手順
MainのViewController画面にUIButtonを設置。Show ModalとTitleを変更
<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3569708/b7300f57-ec5c-5414-35ad-5ccfec128d1b.png width=30%>

UIViewControllerを追加し、UIButtonからcontrolを押しながらUIViewControllerにドラッグ。present modallyを選択し、追加したUIViewControllerの背景色をgrayカラーに。
モーダルの右上にcancelボタンをUIButtonで程よい制約で設置しておく。
![スクリーンショット 2023-11-10 0.33.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3569708/8f981010-c171-7a3e-26ea-9a9b362c68ef.png)

New FileからCocoa Touch ClassでSubclass of: UIViewControllerに設定し、ModalViewControllerを作成。
作成後、Mainストーリーボードで追加したViewControllerのClass名をModalViewControllerに設定。
![スクリーンショット 2023-11-10 0.39.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3569708/8b551202-8b3d-6292-c74c-29171556a811.png)

ここでViewControllerにハーフモーダルと右上のcancelボタンに対しての挙動を記述
```ViewController.swift
import UIKit

class ViewController: UIViewController {
    
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        let next = segue.destination
        if let sheet = next.sheetPresentationController {
            //モーダルを画面の半分まで表示
            sheet.detents = [.medium()]
            sheet.largestUndimmedDetentIdentifier = .medium
            sheet.preferredCornerRadius = 40.0
            sheet.prefersGrabberVisible = true
        }
    }

    //cancelボタンで１つ目の画面に戻るための処理
    @IBAction func exit(segue: UIStoryboardSegue) {
        
    }
}
```

ここでcancelボタンが挙動するように、controlを押しながらドラッグでExitボタンと紐付け。
exitWithSegue:を選択。
<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3569708/b75fc6e5-78c4-8d50-218e-260b4561fb94.png width=30%> <img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3569708/3f5df320-c552-b940-cbfb-b5f7f39817fb.png width=30%>

これで実行すると、Show Modalを押下するとハーフモーダルが出現し、ドラッグとcancelボタンで１つ目の画面に戻ることができます。
【Kotlin】開発しているプロジェクトで100スターを獲得した話

この記事は`OSS`アドベントカレンダーの2日目の記事です。

https://qiita.com/advent-calendar/2023/open_source_software

# プロジェクトについて
この記事で紹介するのは`jackson-module-kogera`というリポジトリです。
勿論今現在もスター募集中です！

https://github.com/ProjectMapK/jackson-module-kogera

このリポジトリでは、`Java`で最も有名な`JSON`ライブラリの1つである[Jackson](https://github.com/FasterXML/jackson)の`Kotlin`向けサポートライブラリである[jackson-module-kotlin](https://github.com/FasterXML/jackson-module-kotlin)に関する実験的な開発を行っています。
初回コミットは2022年4月ですが、オープンにした上で主要な開発を行ったのは今年に入ってからでした。

特徴としては、低レベルAPI（`kotlinx-metadata-jvm`）利用による高速性、ライブラリサイズの削減や、機能の先行サポートが有ります。
特に[デシリアライズのスループット性能は、`2.15.3`時点では本家の数倍となっています](https://github.com/ProjectMapK/kogera-benchmark)[^seinou]。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280230/cb523571-b09d-b4ea-2b66-3c569869c14c.png)

[^seinou]: 性能改善は順次本家に反映している為、今後この差はどんどん小さくなっていきます。

`kogera`という名前は、日本語のコゲラから取りました。
`Kotlin`の名前に似ている小鳥で、プロジェクトのウリである高速性・ライブラリサイズの小ささに、日本で一番小さなキツツキであるコゲラをかけています。

## 開発のきっかけ
自分は今年から本家リポジトリである`jackson-module-kotlin`のメンテナになりました。
メンテナンスをやっていく上では、新しい機能の作成や既存機能の改善を試してみたい・試して欲しい場面が多々有ります。
一方、このリポジトリは長い歴史を持ち、多くのユーザーから利用されているため、破壊的変更前提で好き放題弄ることは憚られます。

そこで、「ぼくの考えた最強の`jackson-module-kotlin`」をやるための場としてリポジトリをスタート[^start]しました。

[^start]: 正確には、掘り出して復活させました。

# スター獲得のためにやったこと
## 身近な人・日本語コミュニティへの宣伝
まずは社内`Slack`の自チャンネル、自分の`X`（旧`Twitter`）や`FaceBook`といった所から宣伝を始めました。

加えて、`Server-Side Kotlin Meetup`や`Kotlin愛好会`のようなコミュニティでの登壇、[`Swift`/`Kotlin`愛好会](https://aikoukai.slack.com)や[kotlinlang-jp](https://kotlinlang-jp.slack.com)といった`Slack`チャンネルでの宣伝も行いました。

https://server-side-kotlin-meetup.connpass.com/event/269443/

https://love-kotlin.connpass.com/event/272253/

## 英語コミュニティへの宣伝
英語コミュニティへの宣伝は、主に[kotlinlang](http://kotlinlang.slack.com/)の`Slack`チャンネルから始めました。
こちらのチャンネルには、新しい機能のサポート追加のようなことが有る度に宣伝を投げています。
この中では、`Kotlin`の開発元である`JetBrains`の社員さん（以前より尊敬していた方）からもスターを頂けて非常に嬉しかったです。

また、`jackson-module-kotlin`リポジトリ内のイシューに関する解決を`kogera`で試作し、当該イシューへリポジトリを宣伝するようなこともしました[^kaiketsu]。

[^kaiketsu]: 当然ですが、これは`jackson-module-kotlin`本家では簡単に解決できないイシューに関してのみ行っています。

100スター達成前最後に宣伝を投げたのが`Reddit`でした。
ここでは投稿から1日程度で20スターほど頂くことができ、一気に100スターを達成することができました。
100スターギリギリでしばらく伸びが止まっていましたが、`Reddit`に宣伝を投げたのは良かったです。

100スター達成後に`Hacker News`にも宣伝を投げてみましたが、こちらは残念ながら殆ど見て貰えませんでした。
`Kotlin`に関しては`Reddit`に投げる方がいい気がします。

## 宣伝を通して感じたこと
やはり英語圏のコミュニティへ宣伝した場合の伸びが良かったです。
特にこのプロジェクトに興味を持つユーザーは限られると思われるため、絶対的なエンジニア数の多い英語圏のコミュニティへ宣伝を投げるのが一番良いですね。

また、宣伝を投げない間はほぼスターが伸びなかったので、必要に応じて宣伝する重要さを強く感じました。

# 終わりに
かなり力を入れて開発してきたプロジェクトだったため、100スターを獲得できたことが非常に嬉しいです。
以前やっていたプロジェクトは、宣伝不足のままスターが集まらず、モチベーションを失って開発を辞めてしまったので、繰り返さずに済んで良かったと感じます。

100スターというのは大したことの無い数字に見えるかもしれませんが、`jackson-module-kotlin`本家でも獲得しているスター数は1,000強で、その実験的プロジェクトで100スターというのは結構多いのではないかと思っています。

このプロジェクトで得られた成果は順次`jackson-module-kotlin`へ反映していくため、差はどんどん無くなっていきます。
ニッチな需要しか無いため、これ以降スターが爆伸びするようなことは期待できないと思いますが、プロジェクトが不要になるその時までは細々と続けていきたいと思います。
勿論、本家`jackson-module-kotlin`のメンテナンスも頑張っていきます。

最後に、スター頂けると励みになります！

https://github.com/ProjectMapK/jackson-module-kogera
【Day 24】k8s環境を構築する - 準備

## はじめに

![スライド25.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985550/52e3a72a-7d3e-3353-695a-6ba06b076987.png)
---

**2023年アドベントカレンダー24日目**です。

https://qiita.com/advent-calendar/2023/life-sync-app

今日と明日で、k8sの環境をskaffoldで作っていきます。

本日は環境立ち上げのためのツールのインストールをしていきます

## ツールのインストール

> gitやcurlなどの一般的なものは入っている前提で進めます。

gcloud CLIをインストールすると、今回使いたいツール系がaptでインストールできるようになるので、バージョン管理しやすくなるため、今回はgcloudをインストールしてから、minikube, kubectl, skaffoldをインストールします。

### gcloudのインストール

https://cloud.google.com/sdk/docs/install?hl=ja

↑の通りにインストールします。

### minikubeのインストール

先程の通りにgcloudをインストールしていたら、aptでminikubeがインストールできるようになっているはずなので、

```bash
sudo apt install google-cloud-sdk-minikube
```

でインストールします。

:::note info
パッケージを検索するには
apt search {package}
で検索します。

例) apt search minikube
:::

### kubectlのインストール

こちらもgcloudをインストールしていたら、

```bash
sudo apt install kubectl
```

### skaffoldのインストール

こちらもgcloudを(以下略)

```bash
sudo apt install google-cloud-sdk-skaffold
```

:::note warn
minikubeと、skaffoldは
google-cloud-cli-minikube
google-cloud-sdk-minikube

のようにcli/sdkの2つが出てきますが、sdkの方で動作確認をしています。
:::

## minikube 起動

* 前提
dockerをsudo無しで実行できること
もしできないようであれば、[こちら](https://qiita.com/katoyu_try1/items/1bdaaad9f64af86bbfb7)の通りに設定してください。

```bash
minikube start
```

:::note info
k8sでの開発をすることの方が多いのであれば、
minikubeの起動はdockerの起動と一緒に.bashrcなどに書いておいてもいいかも...?

そこはお好みで
:::

次回はskaffoldの設定と、各サービスのDockerfileを作成し、起動します！
C#でもSourcetrail

したい人向けにSourcetrailCSharpIndexerをご紹介。

https://github.com/packdat/SourcetrailCSharpIndexer

:::note
注意その1
releaseのバイナリを動かすためには .net5 が必要。
ソースをビルドするためには C# 8.0 以降が必要。
:::

SourceTrailはC++/C/Java/Pythonについてはソースを解析してDBを作るのはご存じの通り。
一方、SourcetrailCSharpIndexerはRoslynでC#のアセンブリを解析してDBを作成。

使い方
コマンドラインで
sourcetrailcsharpindexer.exe オプション
を実行

オプションは
* -i ソースがあるフォルダ(極力絶対パスで指定)
* -o 拡張子が.srctrldbのファイル名(パスを指定しないとカレントフォルダに生成)
* -r アセンブリが置いてあるフォルダ(極力絶対パスで指定)
* -fp 適用する.Netフレームワークのパス(省略すると.net5が使われる模様)
* -ox 外部参照を省略

な感じ。

:::note
注意その2
パスに日本語が含まれるとSourceTrailが嫌がるので要注意。
部品名とかに日本語を使ってるとSourcetrailCSharpIndexerが嫌がるので要注意。
:::

DB(拡張子が.srctrldb)が生成されたら、同じフォルダにあるプロジェクトファイル(拡張子が.srctrlprj)をSourceTrailから開くだけ。

とりあえずこんなとこで。
【CSS】特定の要素より前の要素を指定する方法

## 「以前」

以下のように`:not()`を使用することで特定の要素(.targetの要素)以前の要素が指定できます。

```css
ul li:not(.target ~ li) {
	color: red;
}
```

## 「より前」

`:not(.target)`を追加することで特定の要素(.targetの要素)を含まないようにできます。

```css
ul li:not(.target ~ li):not(.target) {
	color: red;
}
```

## 「直前」

`:has()`を使用して以下のように記述すると直前の要素を指定することができます。

```css
ul li:has(+ .target) {
	color: red;
}
```
JSのように簡潔にレコードからデータを取り出す方法

# モチベーション

Javascriptでは destructuring assignment 記法で簡潔にデータが取り出せる。
Haskellにも似たような方法があるけど、もっと使い勝手をJSに近づけたい。

```javascript
const obj = {
    foo: "FOO",
    bar: "BAR",
    baz: "BAZ",
    qux: "QUX",
};
```

↑のデータから `bar` と `baz` だけを簡単に取り出したい場合は↓のようにできる。

```javascript
const { bar, baz } = obj;
```


# 方法

`NamedFieldPuns` 言語拡張を使う。

# 例

```haskell
data Options = Options
    { optionsFoo :: Natural
    , optionsSrcFilePath :: !Text
    , optionsDestFilePath :: !Text
    , optionsBar :: Maybe Int
    }
```

この言語拡張を有効にすると、↑のような型があったとすれば、例えば↓のような感じで特定のデータを取り出せる。


```haskell
Options { optionsSrcFilePath, optionsDestFilePath } <- view optionsL
```

# 参考文献

https://ghc.gitlab.haskell.org/ghc/doc/users_guide/exts/record_puns.html