OmniAICreator/Qiita-1.07M huggingface dataset:
vueプロジェクトをherokuへデプロイする

## はじめに
vueプロジェクトをherokuへデプロイする手順を備忘録として残します。

## 手順
1. vueプロジェクト作成
1. herokuプロジェクト作成
1. express追加
1. server.js追加
1. git push heroku main

## プロジェクト作成
vueプロジェクトはvue-cliを使って作成しました。
```terminal
vue create xxx
```
herokuのプロジェクトも作成します。
https://dashboard.heroku.com/new-app

## express追加
vueプロジェクトをサーブするためにexpressをプロジェクトに追加します。
```terminal
npm install express
```

## server.js
expressをインストールしたらvueプロジェクトをサーブするためのjsを記述します。

```js:server.js
const express = require('express');
const serveStatic = require('serve-static');

const app = express();
app.use(serveStatic(__dirname + "/dist"));
app.get(/.*/, (_, res) => {
  res.sendFile(__dirname + "/dist/index.html")
})

const port = process.env.PORT || 5001;
app.listen(port);
console.log('server started '+ port);
```

最後は下記コマンドを実行することでherokuへのデプロイが完了します。
```terminal
git push heroku main
```


## 参考記事
https://medium.com/netscape/deploying-a-vue-js-2-x-app-to-heroku-in-5-steps-tutorial-a69845ace489
初めて大き目システムのAWS化を担当して学んだこと

## 初めに
 　今年初めておじいちゃんな大規模システムでシステム更改PJ（AWS化）の
 　インフラ担当（発注側・インフラチームリーダ）を経験したので、
 　その際に学んだことを共有します。
 　　※学んだ＝私が失敗したなと感じたことがほとんど
 
:::note info
発注側目線の戒めとして作成したので技術要素は無茶苦茶に排除しました。
:::

## どんなシステム？？
　詳細書けないので概要と規模間だけさらっと

### 提供サービス
 　メイン
 　　各種お客様応対機能の提供（利用者は社内）
 　サブ
 　　周辺システムへのAPI提供

### プロジェクト方針
 　・お客様応対システムが乱立しているので統合（5システム⇒1システム）
 　・機能としてはリフトだが、UIは使いやすいよう刷新
 　・維持管理コストは今より下げたい
 　・安全第一。3フェーズでリリースする。（トータル3か年計画）
 　・Managedサービスは積極的に使う（EKS、RDS、Elasticache、API-GW　等々）

 
### 規模感
 　・サーバリソース：EC2、コンテナPOD含め100+
 　・DBリソース：10TB＋
 　・対向システム数：90+

## 学び

### 学び① PJ中のバージョンアップ計画は考慮すべし
 AWSあるあるですがサービスの更新やパッチ提供頻度が多いです。
 **1年以上のPJならまず間違いなく最新パッチは更新されている**ので、
 リリース前にアップデートする計画を盛り込んでおくべきでした。
 私はリリース前がドタバタで隙が無く、
 **リリース後すぐアップデートをしなければならない事態に(´;ω;｀)**

### 学び② リリース後のサイジングは発生するので計画しておくべし
AWSのメリットはリソース増強しやすい点があります。
これは商用設備でもある程度気軽に増強出るので大変ありがたいのですが、
**リリース直後で盲点となるのがリソース縮小の可能性**です。
ものによっては**増強は活性でできるけど、縮小は停止/断を伴うもの**が
意外とあります。
リリース後にトランザクションが少なくリソース無駄なので減らしたい、
って要件がある際は、**小さく作ってすぐ増強できるようにしておく**か
**縮小時の影響と縮小対応日の合意**をしておくと
調整に奔走することが無くなります。
またそういうもんだという周囲への刷り込みも結構大事。

私はelasticacheのダウンサイズの調整で苦労してます。（23年12月現在、現在進行形）


:::note warn
小さく作るはパブクラで良くある格言ですが、影響の大きさ（お客様への影響度合い）では選びにくい選択です。
ムリの無い選択をおススメします
:::

### 学び③ 皆人間。発注側は驕るべからず
（何より大事。唯一自信をもって、出来た！と思うことｗ
　というよりAWS関係なくいつでもやるべきだしやってます）

受注・発注関係があるとどうしても発注側が指示とか依頼する形になりますが、
**上下関係では無い**のでそこを間違えないようにしましょう。
命令すること・出来てないことを怒ることに快感を覚えている人を見ますが、
自分が**それをされ、嫌になって適当に済ませたことはあっても、
効率が上がった経験は一度も無い**です。
発注をしている＝自社がやるより依頼の方が良いと判断して発注しているはず。
自分では能力/コスト面で出来ないことをやってくれているという、
**感謝の気持ちで接しましょう。**
嫌な現場より気安い現場の方が報連想や相談もすぐもらえます。（経験談）
 　①やって当然ではなく、やってくれてありがとう
 　②何でミスしたんだではなく、どうリカバリしようかと一緒に考える。

:::note alert
なぁなぁを良しとするわけでは無いので、私の関係者の方見ていたら
勘違いしないようにしてくださいm(__)m
というわけで以下続き
:::

とは言ってもどうしても踏ん張りどころでは無理強いします。。
そんな時にも節度ある態度を
　①急ぎの対応については何故急ぎなのか？を説明する。
 　　いいからやれと上司やお客様に言えますか？の精神で
　②受けるうえで発注側にしてほしいことが無いかを確認する。
 　　私くらいペーペー相手でも言いづらいという方も多いと思います。
 　 　急ぎお願いする以上最大限誠意を示すのがあるべき姿。
　③やってもらったら最大限の御礼を。
　　私はやってもらった方の上司がいる場やいるチャットでどれだけ助けられたかを
　　伝えるようにしてます。（私が出せない分、社内で評価とボーナスもらってほしい）
EMとしてまずはオンボーディングを頑張ってみた

この記事は[Engineering Manager Advent Calendar 2023](https://qiita.com/advent-calendar/2023/em)の14日目の投稿です。

こんにちは！私は、HafHを運営するKabuk Styleで今年2月にエンジニアリングマネージャー（EM）として参加したばかりの新米です。主にフロントエンドチームの管理を担当していますが、エンジニア組織全体の改善、開発フローの最適化、チームの組み立て、そして技術選定など、幅広い分野で活動しています。

今日は、私が最初に取り組んだ最初のプロジェクト、オンボーディングプロセスの改善についてお話しします。

### なぜオンボーディングに注力したのか？
私がオンボーディングに注力したのは、その重要性を痛感していたからです。実際、良いオンボーディングを受けた従業員の69%は、会社に3年以上在籍するというデータがあります。さらに、私自身の経験からも、オンボーディングの有無は、新入社員が会社に対して抱く印象に大きな影響を及ぼすと感じていました。

### 当時のオンボーディングの課題
当時のオンボーディングプロセスには、いくつかの課題がありました。教えた内容が定着せず、短期間で大量の情報をインプットする方式が採用されていました。
さらに、実践的なハンズオンが不足していたり、多様なバックグラウンドを持つメンバーへの配慮が足りない状況でした。

### 具体的な改善策
改善の主な目的は、コストを抑えつつ、エンジニアが迅速に高いパフォーマンスを発揮し、チームに早く馴染めるようにすることでした。
これを実現するために、ハンズオンを増やし、より日々の開発フロー重点を置きました。また、サービス全体を実際に触ってもらい、オンボーディングタスクをより実践的で有意義なものにしました。
Buddyシステムの導入により、EMだけでなくチーム全体で新人のサポートが可能になり、効率的な学習と早期の貢献が実現しました。

### 改善後の成果と反応
改善の結果、オンボーディングのプロセスは常に成長しており、毎月のフィードバックに基づいて改善が行われています。特に、実践的な学習の機会の増加により、教えた内容が定着しやすくなりました。
このフィードバックがもらえる環境にできている一つの理由としては、「オンボーディングはまだまだ成長途中で、改善することが一番最初の貢献になるので、今後来るエンジニアのためにフィードバックをどしどしください！」とスタートしているからなんですけどね（笑）
しかし、全ての施策が成功したわけではなく、グループミーティングの参加率が低く、新人に対してネガティブな印象を与えることもありました。

### 今後の展望
今後は、さらに多くのフィードバックを取り入れ、グローバルメンバーにも満足してもらえる世界クラスのオンボーディングを目指しています。
エンジニアの習熟度や理解度に合わせたコンテンツの提供や、フィードバックに基づく継続的な改善を通じて、いつの日かこの経験に基づく本を書けたらと思っています。

### さいごに
この記事は当日に気づき自分がかけることを殴りかいたものにもなっているので今後更新される可能性が高いです。
もう少し流れや一つ一つのアクションに対してなぜやったのかなど記載していきたいと思っています。


参考資料
- https://www.zavvy.io/blog/onboarding-new-engineers-developers
- https://engineering.visional.inc/blog/296/onboarding-practices/
Go と TinyGo の cgo 呼び出しオーバーヘッドの比較

cgo はビルドも遅くなるし、クロスコンパイルに問題が出ることもあるし、呼び出しオーバーヘッドも大きいです。
ただ、それでも既存の C 言語資産を使いたい場合など、使いどころは多数あります。

以下の記事では、 cgo 使用に対して次のように書かれています。

https://dave.cheney.net/2016/01/18/cgo-is-not-go

* Slower build times
* Complicated builds
* You lose access to all your tools
* Performance will always be an issue
* C calls the shots, not your code
* Deployment gets more complicated

Go では散々な言われようですが、 TinyGo ではどうでしょうか？

なお、、、 TinyGo については以下の書籍や記事などを参照してください。

https://www.amazon.co.jp/dp/4863544006

https://qiita.com/sago35/items/92b22e8cbbf99d0cd3ef


## cgo 呼び出しオーバーヘッドを測定する

以下のようなコードを書いてみます。

```go
package main

/*
int max(int x, int y) {
    return x < y ? y : x;
}
*/
import "C"

import (
	"flag"
	"fmt"
	"log"
)

func main() {
	x := flag.Int("max", 1000000, "max")
	flag.Parse()

	err := run(*x)
	if err != nil {
		log.Fatal(err)
	}
}

func run(x int) error {

	xx := C.int(x)
	sum := C.int(0)
	for i := C.int(0); i < xx; i++ {
		sum += C.max(i, i+1)
	}

	fmt.Printf("sum %d\n", sum)

	return nil
}

```

このコードを Go と TinyGo の両方でビルド && 実行してみます。
cgo で書かれた関数は処理時間がほとんどかからないため、 x で指定されるループ回数が十分に大きい時、 cgo の呼び出しオーバーヘッドが支配的になります。

実際に動かして測ってみましょう。
Go でのビルド + 実行ログはこちら。
実行環境は、 Ubuntu 22.04 + Core i5-5200U / 8GB です。

```
$ go build && time ./main --max 100000000
sum 987459712

real	0m8.700s
user	0m8.706s
sys	0m0.016s
```

TinyGo はこちら。

```
$ tinygo build -o tmain && time ./tmain --max 100000000
sum 987459712

real	0m0.001s
user	0m0.001s
sys	0m0.000s
```

どちらも 100,000,000 回実行しています。
処理時間に注目すると以下。
Go はたったこれだけの処理で 8.7 秒かかっています。

| Go (cgo) | TinyGo |
| -- | -- |
| 8.700s | 0.001s |


ちなみに Go で cgo を使わずに以下の関数定義をしてみます。

```go
func maxGo(x, y C.int) C.int {
	if x < y {
		return y
	}
	return x
}
```

この場合は Go でも十分に早いです。

```
$ go build && time ./main --max 100000000
sum 987459712

real	0m0.061s
user	0m0.058s
sys	0m0.004s
```

まとめると以下。
Go も cgo を使わなければ十分高速です。

| Go | Go (cgo) | TinyGo |
| -- | -- | -- |
| 0.061s | 8.700s | 0.001s |

さて、 TinyGo は cgo を使っているにも関わらず、なぜこんなに高速なのでしょうか？


## TinyGo の cgo 呼び出しオーバーヘッドが小さい理由

TinyGo でも cgo はサポートされています。
TinyGo は LLVM を内包していて、 C 言語で書かれている部分も内包している LLVM clang で処理します。
外部でコンパイラを用意する必要がありません。

更に、 TinyGo は Go で書かれたソースコードを Go SSA を経て LLVM IR に変換します。
同様に C で書かれたコードは LLVM clang を用いて LLVM IR に変換します。
この時点で、 Go とは異なりすべて LLVM IR となります。
そして、このあと最適化などを実施します。

ここで大事なのは、 Go のコードも C のコードも両方 LLVM IR になっている、ということです。
これにより cgo 呼び出しではなく、単に LLMV IR 内での関数コールという扱いになります。

Go の場合は、

* goroutine stack の情報の退避
* C 呼び出し規約に合わせた変換
* 結果を goroutine stack に下記戻し

といった処理が必要となります。
一方で TinyGo の場合は LLVM IR 同士の計算のなるため上記のようなオーバーヘッドがありません。

以上により非常に高速に C 言語関数をコールすることができる、ということです。

# まとめ

TinyGo の cgo 呼び出しオーバーヘッドは非常に小さいです。


## リンク

https://aykevl.nl/2021/11/cgo-tinygo/
有志活動であるchallenge_club（技術チャレンジ部）の歌詞を作ってみた

## 背景

- 最近、音楽生成AI『Suno AI』がにわかに注目を集めている。日本語の歌を生成可能らしい。
- これまで、音楽生成AIとして『[SongR](https://www.songr.ai)』などもあったが英語のみ対応であった（はず）
- 元々、chatGPTで歌を作りたいと思っていたので、これを機に試してみた



https://www.suno.ai

https://zenn.dev/kanasugi/articles/650319999552fd

## challenge_club（技術チャレンジ部）とは

以下をご参照ください

https://challenge-club.connpass.com


以下のアドベントカレンダーも実施中です

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

## 歌詞を作ります

- step0. 歌詞生成の入力を作成する
- step1. chatGPTに歌詞生成していただく
- step2. sunoAIに歌を生成していただく

## step0. 歌詞生成の入力を作成する

今回はchallenge_club（技術チャレンジ部）が対象なので、概要欄の文章＋αを入力とします

> https://challenge-club.connpass.com
> 謎の有志団体であるchallenge_club（技術チャレンジ部）です
> - 新しいことにチャレンジしてみたい！
> - 技術をさらに深めたい！
> - いろんな人と知り合いたい！
> - 一人だと心折れちゃう！一緒に取り組む仲間が欲しい！
> 
> そんなモチベーションで集まったメンバーの遊び場です。

個性があると出力に良い影響がありそうなので、いくつか特徴も加えます

> 尚、歌詞には以下の文言を加えてOKです、韻を踏んで頂いてもOKです。
> - 技術チャレンジ力が高い
> - python星人
> - unity職人
> - VR星人
> - docker芸人
> - 圧倒的感謝


## step1. chatGPTに歌詞生成していただく

歌詞生成していただきます
> https://chat.openai.com

```
Q:
謎の有志団体であるchallenge_club（技術チャレンジ部）の歌を作ってください

challenge_club（技術チャレンジ部）とは、
新しいことにチャレンジしてみたい！
技術をさらに深めたい！
いろんな人と知り合いたい！
一人だと心折れちゃう！一緒に取り組む仲間が欲しい！
そんなモチベーションで集まったメンバーの遊び場です。

尚、歌詞には以下の文言を加えてOKです、韻を踏んで頂いてもOKです。
- 技術チャレンジ力が高い
- python星人
- unity職人
- VR星人
- docker芸人
- 圧倒的感謝
```


```
A:
Yeah, challenge_club、技術チャレンジ部
新しい未来、踏み込んでいこう

新しいことに挑む　風を感じながら
技術の頂点　目指して走ろう　
知識の扉を開けよう　広がる世界に
challenge_club　仲間と共に　未来を描こう

技術チャレンジ力が高い　その闘志
python星人　Unity職人　VR星人　揃い踏み
docker芸人　舞台裏で輝く
一緒に挑む仲間に　心から感謝

challenge_club、夢を追いかけよう
新たな挑戦、魅せてくれ　
一人じゃない、仲間がいる
心強さと誇り、共に育てよう

新しいアイデア　編み出すように
技術を磨く　日々の積み重ね
いろんな人と交わり　学びを深め
一人ぼっちじゃない　共に歩む未来

技術チャレンジ力が高い　その情熱
python星人　Unity職人　VR星人　共鳴
docker芸人　舞台裏で笑顔
一緒に築く未来に　圧倒的感謝

challenge_club、夢を追いかけよう
新たな挑戦、魅せてくれ
一人じゃない、仲間がいる
心強さと誇り、共に育てよう

challenge_club、技術の舞台
一緒に歩む仲間に　感謝の意をこめて
新しい未来へ　共に進もう
```

素晴らしいです

## step2. sunoAIに歌を生成していただく

せっかくなので曲調を`soul music`調に設定して歌詞生成していただきます
> https://www.suno.ai

出力

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">challenge_clubの歌（仮）<a href="https://t.co/sMgyG6C8lV">https://t.co/sMgyG6C8lV</a> <a href="https://t.co/Vd9n8bPMr2">pic.twitter.com/Vd9n8bPMr2</a></p>&mdash; seigot (@st17890027) <a href="https://twitter.com/st17890027/status/1735264383797014758?ref_src=twsrc%5Etfw">December 14, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

すごいです

## 感想

- 結構と自然に聞ける。思ったよりも違和感が少ない、気がする。
- 歌詞や曲調をもう少し調整するとさらにバリエーションが豊かになる可能性を感じる。
- 正しい活用方法はよくわからない。。

## 参考

https://www.suno.ai

https://zenn.dev/kanasugi/articles/650319999552fd

https://chat.openai.com

https://challenge-club.connpass.com

https://www.songr.ai
デバイスやセンサー類の推し100均収納ボックス紹介

# やべえサイトがあった

100均の収納グッズを横断的にまとめ、外寸・内寸を製品ごとに事細かに記載している神サイトを発見…！
興奮のあまり本記事を書きました。



# MONO SIZE

https://monosizecatalog.com/

ショップごとだったり、外寸や内寸ごとにフィルタできます。
たとえばM5Stack用にぴったりな内寸5cmの箱を探したいときは↓のリンクにアクセス！

https://monosizecatalog.com/inside-dimensions-width-5cm-100yen-storage-goods/

さっそくM5Stackをディスプレイするのに良さげな木製仕切りボックスがみつかりました。

![image](https://user-images.githubusercontent.com/22117028/290503347-7a5bbe7d-fe35-41df-81d2-f321a848e85e.png)

https://monosizecatalog.com/item-4562353730042/



# 推しボックスのご紹介

せっかくなので私のM5Stackライフでの推しボックスをいくつかご紹介したいと思います。



## SIKIRIシリーズ

みんな大好きSIKIRIです。

https://monosizecatalog.com/?s=sikiri&x=0&y=0

中でも特に推しなのが以下の3つです。



### SIKIRI 30

細かいパーツの一括管理に最適です。

![image](https://user-images.githubusercontent.com/22117028/290503403-77e9744a-a00b-439e-9d85-4813e8632260.png)

https://monosizecatalog.com/item-4965534134613/

### SIKIRI HALF 3

ハーフサイズがいい感じに扱いやすいです。

![image](https://user-images.githubusercontent.com/22117028/290502872-7fb98309-da3f-4b18-8641-64b1ace2633f.png)

https://monosizecatalog.com/item-4965534134415/

### SIKIRI 15

細長い仕切りが絶妙に重宝します。

![image](https://user-images.githubusercontent.com/22117028/290502931-bc0f95be-f362-43b0-8818-b24145bf94c2.png)

https://monosizecatalog.com/item-4965534134811/



## 小物ケース 仕切り付
もはやM5ATOM専用ケース。
仕切りを外せばM5StickCもいい感じに収納。
高さ的にEchoが入り切らないのがちょっと残念。

![image](https://user-images.githubusercontent.com/22117028/290503039-94e11a44-bbc2-419a-b33c-9cd6dd15cc76.png)

https://monosizecatalog.com/item-4549131533583/



## ストックBOX5

個人的に最強のレゴ管理BOX。

![image](https://user-images.githubusercontent.com/22117028/290503095-00222669-1235-44f6-a89e-e020425b706b.png)

https://monosizecatalog.com/item-4549131496802/



## シューズBOX

ストックBOX5のでかい版的なやつ。
頻繁に使わない工具とかの収納に。

![image](https://user-images.githubusercontent.com/22117028/290503134-5955a8e8-f96a-421b-bfdb-757716e0ceb3.png)

https://monosizecatalog.com/item-4984355078623/



## 積み重ねボックス 大・フタ付

頻繁に出し入れする際に便利な簡易フタ付き。
けど廃盤…！？😭

![image](https://user-images.githubusercontent.com/22117028/290503177-d609f416-cacb-46ae-997a-fae20a3e4df2.png)

https://monosizecatalog.com/item-4984355160328/



# おわりに

以上、スーパー神サイト「MONO SIZE」と私の推しボックスのご紹介でした。
みなさまの推しボックスもありましたらぜひMONO SIZEのページリンクと共に教えてください☺
【AWS】ストレージ

# ストレージとは
データを長期間保存するための記憶装置。

| ストレージ | 説明 |
| ---- | ---- |
| ブロックストレージ | 高速なデータアクセスに有効 |
| ファイルストレージ | 複数のクライアントからのデータアクセスに有効 |
| オブジェクトストレージ | APIを使って接続 |

# ブロックストレージ
データを**ブロック**という単位で分割して管理するストレージ。データを格納するブロックには一意のIDが付与され，データアクセス時にこのIDを使用する。このアクセス方式を**ブロックアクセス**という。データへのアクセスはOSが提供する**ファイルシステム**を使用。

## EBS(Elastic Block Store)
EC2向けにブロックストレージを提供するサービス。

# ファイルストレージ
データをファイルとみなし，階層構造になったフォルダに保存するストレージ。データアクセス時にはデータが保存されているパスを指定する。
**ファイル共有機能**を持ち，ネットワークごしにファイルストレージへマウントすることでPCやサーバでデータを保持しているかのように扱える。

## EFS(Amazon Elastic File System)
共有ファイルストレージサービス。複数のEC2インスタンスからマウントし共有して利用することが可能。

# オブジェクトストレージ
1つのデータをオブジェクトという単位で管理する。

## S3(Amazon Simple Strage Service)
オブジェクトストレージを提供するサービス。

# AWS Strage Gateway
オンプレミス環境とAWSを連携させてオンプレミスのバックアップを取得するゲートウェイサービス。オンプレミスにあるサーバーとS3などのストレージを連携させることができる。
オンプレミス側にStrage Gateway 仮想マシンを作成し，仮想マシン経由でデータのバックアップを行う。AWS上のストレージにデータを保存することで可用性，耐障害性の向上が期待できる。

| ゲートウェイタイプ | 説明 |
| ---- | ---- |
| ファイルゲートウェイ | オンプレミスのファイルをS3に保存 |
| ボリュームゲートウェイ | ディスクデータをS3に複製 |
| テープゲートウェイ | 既存の物理テープ型にバックアップしつつ，仮想化されたテープ型ストレージ(S3)にデータをバックアップ |

# Snowball 
物理ストレージデバイスを使用してAWS環境にペタバイト級の大量データを転送できる。

# 参照
https://www.youtube.com/watch?v=59autczYjXI&list=PLPzcoMdqG5noLR7rAc552mvPADUmmdSt1&index=8
AWSの基本・仕組み・重要用語が全部わかる教科書
よく使うEthereumのテストネットの情報まとめ(2023.12現在)

## 概要

Ethereumでコントラクトの動作確認をするためのテストネットに関しての情報をまとめておく．
MetaMaskへの登録形式に合わせて内容を記述する．

## 各テストネットの情報

### Goerli Testnet 

- ネットワーク名：Goerli Testnet
- RPC URL：https://goerli.infura.io/v3/
- ChainID：5
- 通貨記号：GoerliETH
- ブロックエクスプローラー：https://goerli.etherscan.io
- 入手方法：

【方法1】alchemyのfaucetで取得(0.02ETH/day)
受け取るために0.001ETH(mainnet)をウォレットに入れる必要がある．

https://goerlifaucet.com/

【方法2】Goerli PoW Faucetで取得(約0.01~0.04ETH/day)
PoWなので手に入る量は端末性能に依存する．

https://goerli-faucet.pk910.de/

:::note warn
goerliは**2023年12月末**にサービスを終了予定．
後任として，Holesky testnetが2023年9月から稼働している(後述)．
:::

### seporia Testnet 

- ネットワーク名：Sepolia Testnet
- RPC URL：https://sepolia.infura.io/v3/
- ChainID：11155111
- 通貨記号：SepoliaETH
- ブロックエクスプローラー：https://sepolia.etherscan.io
- 入手方法：

【方法1】alchemyのfaucetで取得(0.5ETH/day)

https://sepoliafaucet.com/

【方法2】sepolia PoW Faucetで取得(約0.01~0.04ETH/day)

https://sepolia-faucet.pk910.de/

:::note warn
sepolia は **2026年12月末**にサービスを終了予定．
:::

### munbai 

- ネットワーク名：
- RPC URL：https://rpc-mumbai.maticvigil.com/
- ChainID：80001
- 通貨記号：MATIC
- ブロックエクスプローラー：https://mumbai.polygonscan.com/
- 入手方法：

【方法1】alchemyのfaucetで取得(0.2MATIC/day)

https://mumbaifaucet.com/

【方法2】polygon technologyのfaucetで取得(0.2MATIC/day)

https://faucet.polygon.technology/

:::note warn
Layer2のPolygonのテストネットワークになるため，
上記の goerli / sepolia と，ベースとなっている通貨が異なることに注意する．
(特にトランザクションのガス代などの費用に関する検証時)
:::

### Holesky 

- ネットワーク名：Holesky Testnet
- RPC URL：https://ethereum-holesky.publicnode.com/
- ChainID：17000
- ブロックエクスプローラー：https://holesky.etherscan.io/
- 入手方法：

【方法1】Automataのfaucetから取得(2ETH/day)

https://www.holeskyfaucet.io/

【方法2】quicknodeのfaucetから取得(0.2ETH/day)
受け取るために0.001ETH(mainnet)をウォレットに入れる必要がある．

https://faucet.quicknode.com/ethereum/holesky

## まとめ

Ethereumのテストネットに関する情報を備忘録としてまとめた．
MetaMaskのネットワーク登録形式に合わせたので，
新しい環境にMetaMaskを入た際のセットアップ時に見返そうと思う．

年末でgoerliが終了するので，今後コントラクトの動作確認を行う場合は，sepoliaかmunbaiを使用し，
情報がある程度で回り始めたら，Holeskyを利用すると思う．
Siv3Dゲームジャム2023に参加した話

## 作ったゲーム
タイトル: 「スペースコレクター」
![ゲームのイメージ](https://raw.githubusercontent.com/tas9n/bnscup2023/master/gameplay.png)

[ダウンロード](https://github.com/tas9n/bnscup2023/releases/tag/1.0)

## 参加してみて
学外のゲームジャムは初めての参加でした。
テーマは「すくう」で、初めは金魚すくいなどが頭に浮かびましたが、そこから「すくい上げる」を頭に浮かべ、今回のようなゲームにしようと思いました。
僕は絵などが得意ではなかったのですが、Siv3Dでは絵文字や短形を用いることができたので簡単にプレイヤーやオブジェクトを実装することができました。

## 使った技術（？）

以前からよく使っていたのですが、
描画処理の後に
```cpp
Circle{ Scene::Center(), Scene::Size().x }.draw(ColorF{ Palette::Black, 0.0 }, Palette::Black);
```
のようにすることで、シーンの周辺を暗くするような処理や
`Effect`や`Shape2D::NStar`を使い星がきらきらしているように見せたり
`Update`で周期的に`true`を返す`Spawner`クラスを実装しオブジェクトの生成などを用意にしました。
他には`GameObject`を派生させ`Player`と衝突したときには各オブジェクトではなく、`Player`が処理をすることでわかりやすくするなどしました。
他には[リーダーボード](https://github.com/Siv3D/Siv3D-Samples/tree/main/Samples/Leaderboard)を参考に工夫し、ゲームのスコアなどを競えるように、ランキングも実装しました！

## 詰まったところ
角度の補間がうまくいかなかったのですが、以下の`Math::LerpAngle`で解決しました。
```cpp
angle = Math::LerpAngle(angle, Vec2{ other->pos - pos }.getAngle(), 0.0075);
```
絵文字と短形しか使っていなかったので、見た目が悪くならないか特に気を配りながら開発しました。

## 最後に
Siv3Dは普段から扱っていたので、開発中あまり詰まることはありませんでしたが、この日までにここまで進める！など決めておかないとうまく開発が進みませんでした。
今回ゲームジャムに参加してみて、改めて個人での開発は企画やグラフィックなど大変だなと感じました。

個人での参加でしたがとてもいい経験になったと思います！
運営のかた、今回このゲームジャムを開催してくださって本当にありがとうございました！
もし次回があればもっともっとレベルアップした自分を見せれればと思います！
郵便番号・住所 相互変換 Excelアドイン

ようやく目的のものを作成できました。
長かった・・・苦労した・・・
この記事は、そんな開発の記録です。

郵便番号と住所とを、相互に変換するExcelアドインです。

https://ganges.pro/customer/blog/yuubinhelper/

![20230922fig1-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132059/f17c69d0-cdde-63eb-1a94-c871c4e757b0.png)

![20231214fig3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132059/0aefe725-f82e-282e-d1b4-2ecbb0eb0f7c.png)


## 作成を考えていた時期
郵便番号と住所との変換機能は、顧客管理ソフトガンジスを開発した頃から作成したいと考えていました。2018年頃の話です。
当時、独自に開発はせず、Webのサービスを利用してソフトにその機能を実装しました。

## 作成しなかった理由
その後、時々、機能作成の方法を考えることがあったのですが、住所から郵便番号への変換の精度を高める方法が難しく、断念していました。

また、私の場合、Excel上で、郵便番号・住所・名前・電話番号を、整形・正規化することが多いです。それには、それらの機能がアドインとしてあると便利だなぁ、と思っていました。しかし、C#に慣れてしまった今となっては、今更VBAで作成したくありませんでした。

## Excel-DNA
ところが、C#でExcelアドインの開発ができるExcel-DNAがありました。

https://excel-dna.net/

Excel-DNAを知ったのはいつなのか忘れてしまいましたが、実際に使ってみるととても楽なのが分かり、感動しました。
最初に作ったのは、**郵便番号から住所に変換**するアドインです。
郵便番号から住所への変換はさほど難しくはないのです。

## 住所の正規化
これが出来たので、**住所から郵便番号への変換**を、本格的に考えました。
調べるなかで、住所の正規化のライブラリを知りました。

https://github.com/geolonia/normalize-japanese-addresses

住所を正規化をすると、郵便番号への精度の高い変換ができそうです。

よし、住所の正規化ができるようにしよう！　と決意。
しかし、このライブラリは`TypeScript`で書かれています。`TypeScript`は私の技術の範囲外です。
.NETでどうにかこのライブラリを利用できないか、試行錯誤が始まりました。

## 試行錯誤
最初、`TypeScript`を`C#`に移植しようと少し挑戦しましたが、`TypeScript`に慣れていない私には難しい。少し文法を学んだだけでは、無理そうです。移植は、`TypeScript`も`C#`もよく分かる人でないと難しいんじゃないか、と思いました。

次に、`JavaScript`を.NET上で動かせるようなので、このライブラリも動かせるなら楽だなぁと、ずいぶん実験しました。多くの知見を得ましたが、最終的にこの方法は断念。

https://qiita.com/hiro_t/items/45460dea35db13e9bedf

次に、`TypeScript`を`C#`に変換するオンラインのサービスを利用しました。すると、おおまかな`C#`のコードが生成できました。これなら、修正すれば移植できそうです。とはいえ、かなり難しい部分もありました。

https://qiita.com/hiro_t/items/6e1dd8a0c1a2d3b5cfbe

特に難題だったのは、`regex`の処理です。

https://qiita.com/hiro_t/items/b5963812544c6479dd2b

`TypeScript`のコードをVisualStudioで動かせるようにして動作を確認しつつ、かなりの日数をかけて移植に成功。

https://github.com/mikihiro-t/NormalizeJapaneseAddressesNET

しかし、ここまでしても、道半ばです。目的は、住所から郵便番号への変換です。

## 郵便番号のデータ
郵便番号と都道府県・市区町村・町域とのデータは、郵便局から提供されていますが、それを整形する機能を開発するのがとても大変でした。
例えば、町域名で「（丁目）」とついているのを解釈して、データを整形する必要があります。

https://qiita.com/hiro_t/items/2d193ab459157f8792a3

また、正規化した住所と、整形した郵便番号データとを比較して、郵便番号に変換する機能を作成します。
終わりが見えないユニットテストを繰り返し、一つ一つ問題を解決していきました。

そしてやりとげました。

## アドイン化
次に、これらの機能をまとめて、`ExcelDNA`でアドインにします。

もちろん、ここでも解決しないといけない問題がありました。

https://qiita.com/hiro_t/items/f37256a59946c6c0faa7

一筋縄では解決できないのです。
これも解決しました。

## 仕上げ
ついに、仕上げの段階です。
アドインをダウンロードできるようにし、ヘルプなどのドキュメントを整えました。

そして、この記事を書いて、長年の課題の解決に至る道をふりかえったのです。
若手エンジニア奮闘記⑩未経験若手エンジニアがぶち当たる「勉強」の壁を乗り越えるためには？

# はじめに

こんにちは！
今回ブログを執筆することになりました、入社一年目の中井です！
まずは簡単に自己紹介させていただきたいと思います。私は大学時代にアルティメットというスポーツを割とガチで行い、趣味でゴルフを嗜むなど、今までの人生でスポーツしかやってこなかったのではないかというほどITとは無縁の生活を送っていました。
また、勉強嫌いには定評があり、高校三年生の頃に受験勉強を一日１０時間やっただけで蕁麻疹が出たほどです。

そんな私がなぜIT業界に就職したかというと…
「これから需要ある業界といえばITでしょ！！！」
といった浅い理由でした。

ちなみにタイピングすらままならない、パソコンの操作も慣れていないといった全くのド素人でした。
就職してから苦労することなど、この時はまだ知りません…
 
# 「勉強」の壁

私が最初に「勉強がきつい！」と感じたのは、基本情報技術者試験の勉強を始めた時です。
勉強の始め方がわからない…
はじめても何のことだかさっぱり…
周りは順調に進んでいる…

こんなことを考えながら日々過ごしていました。

ただ、ここで諦めるようなやわな人間ではありません。時間が経過していくと徐々にできないことや知らないことが悔しくなってきて、
「やってやんよぉ！！」という勢いで頑張った結果、合格することができました。
スポーツで培ったメンタルが役に立ったのでしょうかね。

つまり、気合です。

# まとめ

勉強をするため必要なことは、気合と根性！というのは飽くまで私の場合で、他に気が付いたことを記載したいと思います。

・まずは勉強ツールを開くことから始める。
・勉強していることについて興味を持つ。（私生活につなげて考えると段々興味が湧いてきました。）
・周囲の環境が大事。（私は同期とともに切磋琢磨しながら進めていました。）
・将来の自分のための投資と考える。
・適度な休憩は大事！

このような意識で取り組むことで嫌いだった勉強もあまり苦ではなくなりました。何より思っていたよりもITに関する勉強は、点と点が線で結ばれる瞬間があって楽しいものでした。

勉強めんどくさいなぁ、勉強を始めようかなぁ、と考えているそこのあなた！
こんな私でもできたことなので、よろしければ参考にしてみてください。

最後までご覧いただきありがとうございました。
Prologで作る簡単な日本語プログラミングによるインタプリタ実装

https://twitter.com/public_ai000ya/status/1721975097446240565

`->` のならばなぁ。Prologだと使えるんだけど、単なる三項演算子か、',' でしかないしなぁ。ならばといえば Prolog のメダカ演算子が `:-` ならばの逆の意味で、whereというか `ここで` 演算子だよなぁ。などと思い、日本語プログラミングを論理型言語で書けるとその変の理解が深まるのだよなぁ。
論理の世界には４つのならばがあって２つは論理式の中に現れるアンドと三項演算子でもう一つが規則定義の際に使う横棒、もう一つが証明木で使う横棒なんです。

ということで今日のテーマは、言語実装を趣味としてしている人々にとって足りない力があります。それが論理プログラミング力です。
今日はPrologのユーザー定義演算子を定義することで日本語プログラミング環境を簡単に構築し、その上で足し算ができるだけのインタプリタを作ります。

## 演算子定義

Prologはユーザー定義の優先順位付きの演算子を定義できます。

```prolog
:- op(1200,xfx,ならば).
:- op(1000,xfy,かつ).
:- op(700,xfx,が).
:- op(500,xf,が整数).
```

このように定義すると1200の優先順位を持つ `ならば` 二項演算子と 1000 の優先順位をもつ `かつ` 二項演算子、700の優先順位を持つ `が` 二項演算子と、500の優先順位をもつ `が整数` 単項演算子を定義できます。
xfx,xfy,yfxの違いは結合性がないか、右結合か左結合の違いを表します。

## 項の展開

Prologには強力なマクロ機能のようなterm_expansionという機能があります。
term_expansionはリードマクロのように働きすべてのトップレベルの項を自由に書き換えられます。

```prolog
term_expansion(B ならば A, A:-B).
```

と書くと、`B ならば A.` というトップレベルの項を `A :- B.` に書き換えることができます。
通常の述語は述語の定義で代替できますが、トップレベルの項の動きはterm_expansionを使わないと書き換えられないので使いました。

このterm_expansionはハイジニックなマクロというかプリプロセッサとして働くので何でもできちゃうんで凄いのですけど、ここでは演算子の置き換えさえできればいいので深入りはしません。

## 日本語述語の定義

```prolog
integer(I) ならば I が整数.
call(A),call(B) ならば A かつ B.
I is E ならば I が E.
```

整数であることを調べる `が整数/1` と、 論理積を表す `かつ/2`、算術式を計算する `が/2` の述語を定義します。

## 評価規則の定義

```prolog
I が整数 ならば e(I,I).
e(E1,I1) かつ e(E2,I2) かつ I が I1+I2 ならば e(E1+E2,I).
```

整数を足し合わせるだけの言語の評価規則は２つ必要になります。
１つは整数であれば整数であることを返す規則。
もう一つは足し算であればその項を分解して評価し評価結果を足し合わせる規則です。

## 使い方

１ファイル内で使うには以下のように記述することで定義したインタプリタを実行して試すことができます。

```prolog
:- e(1+2+3,R) かつ writeln(R) かつ R=6.
:- halt.
```

## まとめ

Prologで演算子を定義し、その演算子を使って日本語プログラミング環境を構築、日本語でインタプリタを実装し、実際に使ってみました。

プログラム全体を以下に示します。

```prolog
:- op(1200,xfx,ならば).
:- op(1000,xfy,かつ).
:- op(700,xfx,が).
:- op(500,xf,が整数).
term_expansion(B ならば A, A:-B).
integer(I) ならば I が整数.
call(A),call(B) ならば A かつ B.
I is E ならば I が E.


I が整数 ならば e(I,I).
e(E1,I1) かつ e(E2,I2) かつ I が I1+I2 ならば e(E1+E2,I).

:- e(1+2+3,R) かつ writeln(R) かつ R=6.
:- halt.
```

論理プログラミングは人工知能用言語としては古いかもしれませんが、操作的意味論や型理論の図式をネイティブの感覚で理解する上で有用です。高速に動作することはありませんが、述語論理を用いた形式的な論理的な思考をネイティブな感覚で理解する道具として使うと普通の奴らの上の更に上を行ける道具として使えるので、いい加減プログラミング言語の実装は飽きたよ。という方でも、そういえば論理プログラミングはよくわからんな。という方がいらっしゃったら、ちょっとだけいじってみると新たな境地にいざなってくれるかもしれません。
いろいろ翻訳、JSもね。"UxTranslator"

[Symfony Component Advent Calendar 2023](https://qiita.com/advent-calendar/2023/symfony-component)の17日目の記事です。

## いろいろ翻訳、JSもね。"UxTranslator"

[UxTranslator](https://ux.symfony.com/translator)は、[Translation](https://qiita.com/ippey_s/items/0ac4a10de007960984fc)コンポーネントで使った翻訳ファイルを使って、フロントエンドも翻訳してしまうSymfony UXコンポーネントです。

### インストール

```
composer require symfony/ux-translator
```

### 使い方

Translationで用意した翻訳ファイル`translations/***.ja.yaml`を使いますが、こちらはIDでのみ取得できるようです。

```yaml:translations/message.ja.yaml
apple: "これはりんごです。"
pear: "これはなしです。"
hello: "こんにちは {name}さん"
```

インストール時、`assets/translator.js`というファイルがあります。これを使って翻訳ができます。

:::note
翻訳時、IDは大文字化され、`.`やネストは`_`に変わります。
```yaml
apple: "これはりんごです。"
gender:
    male: "男性"
    female: "女性"
app.name: "アプリ名"
```
↑の場合は
```
APPLE
GENDER_MALE
GENDER_FEMALE
APP_NAME
```
となります。
:::

```javascript:assets/sample.js

import {trans, setLocale, APPLE, PEAR} from './translator.js'

setLocale('ja'); // ロケールをjaに設定

console.log(trans(APPLE)); // これはりんごです。
console.log(trans(PEAR)); // これはなしです。
console.log(trans(HELLO, {name: "すみだ"}); // こんにちは すみださん
```

### 翻訳ファイルの更新

翻訳ファイルですが、`var/translator/index.js`に保存されています。つまり、`translations/`にあるyamlファイルを直接は見ていません。翻訳ファイルを更新した場合、この`index.js`も更新する必要があります。更新する際は、

```shell
bin/console cache:warmup
```

を実行すれば、更新されます。

## まとめ

今回は`UxTranslator`でした。一度jsになるものの、同じ翻訳ファイルを使ってJS側も翻訳が可能になるのは楽ですね！
C言語のテストをGoっぽく書いてみる

# tl;dr
- GoのtestingパッケージのようなものをCで書いてみた。
- 実用に耐えるものかは考えてない遊びのプログラム。

# 動機
- Cのテストを書きたいが趣味のプログラムなので大層なフレームワークは必要なかった。
- [この記事](https://jera.com/techinfo/jtns/jtn002)に感化されてbetter assert.h的な簡素なもので満足できそうだと思った。

# 実装

```c
typedef struct {
  char *name;
  bool ok;
} TestingT;

typedef void (*TestFunc)(TestingT *t);

#define RUN_TEST(test_func) \
  do {  \
    TestingT t = { .name = #test_func, .ok = true }; \
    printf("=== RUN  %s\n", t.name); \
    test_func(&t); \
    if (t.ok) { \
      printf("--- PASS %s\n", t.name); \
    } else { \
      printf("--- FAIL %s\n", t.name); \
    } \
  } while(0)

#define ERRORF(t, fmt, ...) \
  do { \
    t->ok = false; \
    printf("\t%s:%d: " fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__); \
  } while(0)

#define FATALF(t, fmt, ...) \
  do { \
    t->ok = false; \
    printf("\t%s:%d: " fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__); \
    return; \
  } while(0)
```

- テスト関数のシグニチャは `TestFunc` のようにする。
- RUN_TESTにテスト関数を渡して実行する。
- ほかはGoと同様。

# 使い方
```c
#define LEN(array) (sizeof(array) / sizeof((array)[0]))

void fizzbuzz(int x, char *buf) {
  if (x % 15 == 0)
    sprintf(buf, "fizzbuzz");
  else if (x % 3 == 0)
    sprintf(buf, "fizz");
  else if (x % 5 == 0)
    sprintf(buf, "bazz");
  else
    sprintf(buf, "%d", x);
}

void test_fizzbuzz(TestingT *t) {
  struct {
    int input;
    char *want;
  } tests[] = {
    { 1, "1"},
    { 2, "2"},
    { 3, "fizz"},
    { 4, "4"},
    { 5, "buzz"},
    { 6, "fizz"},
    { 7, "7"},
    { 8, "8"},
    { 9, "fizz"},
    { 10, "buzz"},
    { 11, "11"},
    { 12, "fizz"},
    { 13, "13"},
    { 14, "14"},
    { 15, "fizzbuzz"},
  };

  for (int i = 0; i < LEN(tests); i++) {
    char got[10];
    fizzbuzz(tests[i].input, got);
    if (strcmp(got, tests[i].want) != 0) {
      ERRORF(t, "[input=%d] want %s, but got %s", tests[i].input, tests[i].want, got);
    }
  }
}

int main(int argc, char **argv)
{
  RUN_TEST(test_fizzbuzz);

  return 0;
}

/* 実行結果

$ ./unittest 
=== RUN  test_fizzbuzz
        example.c:46: [input=5] want buzz, but got bazz
        example.c:46: [input=10] want buzz, but got bazz
--- FAIL test_fizzbuzz

*/
```
- `"buzz"` のタイポを検出できている。
- `ERRORF` はテストを中断させないので5, 10の両方のケースで失敗している。assert系の関数やマクロだとこれができないことが多い。

# イイところ
- Goのテストの思想そのままだが、テストのために新しい記法を覚える必要がない。
- `ERRORF`が即時失敗にならないので `FATALF` とちゃんと使い分ければTable-Driven Testを書ける。
- `TestingT` に属性を足せば色々拡張できそう。

# イマイチなところ
- `FATALF` は `return` することでテストを中断させているのでヘルパー関数の中で呼んでもテストが続行される。
物理は全ての性別に開かれているか？

こんにちは。

一応「理物女子」と称することができるタイプの人間がこの記事を書いています。

最近YouTubeで話題のあの人とは違う人です。実験ではお世話になりました。

只今「今年のPhys.Labのアドカレはいつにも増してやばい」と友人たちが談笑している横でこの記事を書いております。Phys.Labのアドカレ、「特に今週がやばい」と聞き及んでおりますので、ぜひ既に公開されている記事も含め色々とご覧になってください。

そんな中でジェンダー関連のトピックで乱入したいと思います。無理にふざけても盛大に滑りそうなので、素で書きますね。

東京大学、女子率が少ないので女子を増やそう！というムーブメントが進んでいますね。また、「Diversity&Inclusion」という標語も掲げられています。多様性を尊重しよう！という主旨らしいです。

当方、理学部物理学科の女子率は、異常に低いです。約70人の物理学科生の中で約6人が女性です。他者のセクシュアリティを勝手に類推することも公開することも重大なタブーですから「およそ」です。ちなみに「6人」という数字でも、弊学科ではなかなか稀に見る多さだそうです。って教授がおっしゃっていました。衝撃。

理学部の他の学科もそうですが、女性は本当に少ない。女性同士の交流を！ということなのか、最近理学部で「女子学生交流会」というものが開かれるようになりました。参加対象者は、女子学生・男女参画に興味のある男性、とのこと。え、男性も可能なのか...？ と、結構ザワついたようですが、この定義には、私は割と賛成。性別とは男女の2種類のみ存在するわけではないですしね。自らに「女性」という要素を持つと感じることができる人ならば誰でも出入りできる場所であって欲しいです。

（ところで、男女参画というと、世の中の性別が2種類しかないみたいで、とても悲しいのですよね...。実際はグラデーションのようになっていて、本当に多様でcolorfulなのがセクシュアリティなのだと思っています。この2つは決して矛盾する概念ではないのだが、同時に議論するのがとても難しいと感じています。悔しいなあ。）


ところで、「『女性』という特徴がマイノリティである」この学科で、その当事者の居心地はどうなのでしょうか。

まず、私の感想としては「まあ別にそんなに困らんな」です。

我らが物理学科の同期がたむろする部屋を覗くと、オンラインゲームをしながら常軌を逸した叫び声を上げる人や、3000ピースのジグソーパズルに熱中する人、なぜか4つあるステゴザウルスのぬいぐるみを積み上げる人、ホワイトボードに友人の名前を書きまくる人など、非常にやb...楽しい人たちを観測することができます。

物理学科に入って1年と少し、「常識って、一体どう定義すればいいんですかね？」というぐらいには常識というものを失いました（元から無かっただろうテメェは！というツッコミは無視しておきますね、特に私の中学・高校同期の皆様）。

で、肝心のジェンダーに関しては、あまり困っていません。女性だからと言って顕に下げられたり、誤解を受けたりするようなこともない。きっと「私って女性なんだな〜〜〜！」と感じるようなことがないのだから、本当に困っていないのだと思います。順応しちゃったとかではなくて。

単に、物理に性別は関係ない、というのをごく普通に体現している友人に恵まれているのだと思います。そもそも染色体依存性のある物理量なんて発見されてませんし、性別によって学びたい学問を学ぶ機会が奪われること自体、異常事態なんですが。

   　
一方で、やはりこんな声も聞くのです。
友人は言いました、「女性が少ないのは、やっぱりしんどいんだよ」と。

女子学生で集まってご飯を食べると、こんな話がメインになることもあります。

「あの研究室って女性いたっけ？」
「どうだろう、いなかった気がする」
「うーーん、それはきついなあ」

先ほど「そんなに困っていないなあ」とか言っておいてアレですが、これ結構研究室を選ぶ上での重要事項になってしまう気がします。ちなみに、不本意です、もちろん。もっと気楽に研究分野を選びたい。

自分で選んだ分野を突き進めばいいじゃないか、周りの目など気にせずに！なんて言葉が聞こえてきそうですが、正直、そう簡単にはいかない気がします。

「あのね、僕は『何を研究するか』よりも『誰と研究するか』の方が大事だと思うんだよ」

そう話してくれた教授のことを思い出します。確かにそうなんです。物理（に限らず学問というもの全般かもしれない）においては「議論すること」がとても重要らしいのです。私も最近になってじわじわと感じつつあります。

性別というのは、思っている以上に重要なアイデンティティで、同じ性別の人でまとまってコミュニティが形成されていることが多い。個人的意見ですが、それはごく自然と起こりうることでしょう。既に形成されたコミュニティを解体してみんなで仲良くしよう！というのをDiversityともInclusionとも呼びたくはありません。

だから、自分とは違うアイデンティティを持つコミュニティに飛び込んでいくのは、ものすごく勇気がいる。それがその人にとってどれほどの負担になるのかは、やはりその人によって異なるのです。

そこで費やす時間や精神力を、本当は物理を追求することに使いたいのです。
でも、そうもいかないなあ、しんどいなあと思っている人がいるのも、事実なのです。


私は幼い頃から理系分野ばかりに熱中してきて、女性だからという理由でそれを妨げられたことがありません。しかし、周りには、性別によって自分の学びたい分野を諦めることになってしまった人が、確かにいるのです。そして、そんなに少ない例じゃない。

　

どこか遠い国の話でもなくて、多分、この記事を読んでいる人の半径数m圏内でも起こっていることなのです。

　
どうか、性別によって学問を諦めるような現状がなくなって欲しいと願います。
理学部物理学科、楽しいです。入ってよかったと心から思います(テスト期間以外は)。
　
そして、この文章を読んだ方が、性別関係なく、物理学に興味を持ってもらえたら嬉しいです。
　
では、真面目な話、おしまい。

読んでくださりありがとうございました。
Pythonで「リストの要素を入れ替える」の動作を確認してみた

# 概要

Pythonで「リストの要素を入れ替える」の動作を確認してみました。以下のページを参考にしました。

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

# 実装

以下のファイルを作成しました。
```sample.py
colorlist = ["Blue", "Red", "Green"]
print("オブジェクトの id = " + str(id(colorlist)))
colorlist[1] = "White"
print(colorlist)
print("オブジェクトの id = " + str(id(colorlist)))

colorlist = ["Blue", "Red", "Green", "White"]
colorlist[1:3] = ["Yellow", "Pink", "Black"]
print(colorlist)
colorlist[1:5:2] = ["Gold", "Silver"]
print(colorlist)
```

以下のコマンドを実行しました。
```
$ python3 sample.py 
オブジェクトの id = 139937320132096
['Blue', 'White', 'Green']
オブジェクトの id = 139937320132096
['Blue', 'Yellow', 'Pink', 'Black', 'White']
['Blue', 'Gold', 'Pink', 'Silver', 'White']
```

# まとめ

何かの役に立てばと。
エンジニアと目線を合わせるために

こんにちは、緑川です。
今回は技術広報を行う上で、個人的に早めにやっておけばよかったことを反省を踏まえて、簡単に書き留めておきます。
今回は広報というより、"エンジニアと目線を合わせるために"という点で記しています。自社の技術を知るためには、GHEを見るとか、エンジニアにインタビューをするとか、そういう日々の情報収集が一番大事だと思いますが、加えて下記をやっておくと目線が合って発信ネタの幅が広がると思います。

### 1.一回くらいプルリクを出してみる
技術広報に限らずだと思いますが、業務量が多いと本業以外のことになかなか手を出せないですよね。技術広報にとって「コードを書く」というのは本業ではないので、元エンジニアの技術広報の人でないと「自社で一回もコードを書いたことがない」という人もいるのではないでしょうか(自分がそうだったのですが)？

私自身は開発環境を整えていたのですが、特にコードを書くわけでもないので宝の持ち腐れでした。それでも技術広報の仕事はできてしまうのが、このキャリアにおいてステップアップの壁のような気が若干していますが、実際にプルリクを出すところまでやるといろんなことが体験できるので、その壁がやや低くなると思います。体験できることとしては、ドキュメントの豊富さやインフラの整備によりスムーズにツールの導入が完了したり、セキュリティの堅固さにも関わらずDBへの接続のしやすさだったり、エンジニアに聞くことの心理的安全性の高さだったり、たくさんあるかと思います。他にも、実際のプロダクトのコードをローカルに落としていじって遊んでみたり、DBから色々なデータを調べてみたりすることで、自社の技術のことがより理解できますし、発信するネタにもなるかと思います。

もしハードルが高かったり、わからないことがあったりすれば、気軽にプロに聞けますし、エラーは大抵誰かしらが経験済みでSlackに対処法が残ってたりするので、初めて行うとしても最高の環境下にあると思います。本業ではないので失敗もあるかと思いますが、その後の学習効果が高まりますので（生成効果）、コードを書いてプルリクを出したことがない人は一回はやっておくのがおすすめです。

### 2.スクラムを理解する
このご時世、多くの企業で開発にスクラムが導入されていると思います。
これも上記と同じで別にスクラムのことを知っていなくても技術広報の仕事はできますし、社内で何かスクラムのイベントを行なっていても「エンジニアの人たちが何か打ち合わせをしているなー」という認識で問題が起こらなかったりします。

とは言え、開発の流れを理解しないことには、エンジニア一人一人の役割が正しく認識できなかったり、今どういう状況なのか、どこが重要なイベントなのかが理解できなかったりするので、エンジニアの働き方だったり開発の仕方だったりはきちんと理解しておくべきなんですよね。エンジニアと共通言語を持つというのは何もプログラム言語やアーキテクチャだけの話というわけではないのです。

何より「うちのスクラムはこうやっていますよ！」というのも技術広報の一部なので、本当にスクラムは早めに理解しておくべきだったと思います。ちなみに今は認定スクラムマスターです。

### 3.幅探索優先
『両利きの経営』という書籍（言葉）の影響で、 最近は探索と深化という言葉が広まっていると思いますが、それに似たようなもので、知識も縦か横に探索することができるかと思います。縦と横、エンジニアの場合はどちらを選択するかで結構キャリアが大きく変わるかと思いますが、技術広報の場合は自他を比較をすることで広報すべき自の良さが把握できるので、知識は横を優先に広げていくべきなのかと思います（わかりやすい言葉にすると幅探索優先）

今年は「割と一つの技術にこだわり過ぎてしまっていたなー」という反省が個人的にあるのですが、技術広報は企業全体の技術力を広報する立場から組織横断型人材になることが求められると思いますので、知識の習得の仕方や働き方など深さ優先探索ではなく、早めに幅探索優先を意識して動いていくべきだったなと思います。

### おまけ.なんでも数値を残しておく
KPIは不要派なのですが、それでも勉強会に参加した人数やカンファレンスでのブース来場人数なんかは、予算やノベルティ制作に関わってくるので、正確な数値を早めに毎回残しておくべきだったとは思います。ノベルティの数とか懇親会の規模とか、毎回記憶を無くしてしまうのですが、正確な数値を残しておけばよかったな、と思います。

カンファレンスのブースで↓をおいている企業を見たことがないですけど、どうやってブースへの来場者をカウントしているんでしょうかね（ノベルティを減らした数とか）？ 

![counter_goren.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3007435/98eba8de-c74e-4c21-2f93-43dc7f4f5c8f.png)

今度機会があったら持って行こうかと思います。
hygen 使ってみた


# インストール
```sh
yarn add hygen --dev
```

`npm` の場合は `npm install --save-dev` してください。`devDependencies` に入れます。bundle 時に入っていてもうれしくないので。

# hygen を使ってみる
```sh
yarn hygen init self
```
このコマンドを使うと、テンプレートのジェネレータが生成されます。

```sh
yarn hygen generator with-prompt component
```
さらに、このコマンドで _templates/components 以下にファイルが生成されます。生成されたファイルたちを使ってコード生成を行います。

### テンプレートの `.t` ファイルと `.js` を書き換える


```_template/components/story/prompt.js
module.exports = [
  {
    type: 'input',
    name: 'name',
    message: "ファイル名を入力"
  },
]

```

```_template/components/story/component.t
---
to: src/components/<%= name %>.stories.ts
---
import { defineComponent } from 'vue';
import <%= name %> from './<%= name %>.vue';

const meta = {
  title: 'components/<%= name %>',
  component: <%= name %>,
};

export const Default = {
  render: () => defineComponent({
    components: {
      <%= name %>,
    },
    template: `
      <<%= name %> />
    `,
  })
};

export default meta;
```

こっそり、ディレクトリ名を `with-prompt` から `story` に変更しました。コード生成時には `story` という識別子を使うことができます。
見ての通りのテンプレートエンジンで、今回は Storybook のストーリーを生成するように書きました。

`prompt.js` は対話的生成に使えます。

# 対話的生成
```sh
$ yarn hygen component story
> ✔ ファイル名を入力 · hoge

> Loaded templates: _templates
>        added: src/components/hoge.stories.ts
```

`yarn hygen component {コンポーネントの名前}` で生成が始まります。

# おわり
願わくば設計資料からそのままコンポーネントが生成されるようになってほし。。。
ある日の定例会での出来事

この記事はUiPath (produced with UiPath Friends) Advent Calendar 2023協賛記事です。

はじめまして、イノウエです。
UiPathでプリセールスをしてます。

Tech企業歴は1年2か月、プリセールス歴は半年です。

今年の5月にプリセに異動させて頂き、
初アサイン案件での体験を書かせて頂きます。
よろしくお願いいたします。


6月頃より、実施していたPoCですが、
お客様の業務をヒアリングし、
スコープを決め、
実機を構築し、
検証を進めておりました。

予定していたタスクはスケジュール通り進み、
期待していた効果も出始めています。
そんなある日の定例会の出来事でした。

PoCをやっていく中で
“ある程度の精度が期待できそう”ということがわかってきた

我々としては
『これはイケるだろ』　『どや！』
という感じで定例会で精度を提示し説明

一松さん(仮名：入社二年目のクライアント社員)
「ふむふむ」と言いながら聞いている

精度も出そうだし良かったぁ、とひと安心をする私

そんな中、一松さんの一言

精度が出るのはわかったのですが
これがなんなのですか

この一言を聞いた私は
まるで雷に打たれたような衝撃を受けた
そして私はようやく気づいた


現場の従業員にとって重要なのは
『今日私は何をするのか』
『明日私は何をするのか』

作業がどう変わるのか
どれだけラクになるのか


なるべく具体的に
“To-Beを見せてあげる必要がある”
“明日何をするのか”を見せてあげる必要がある


教訓
現場従業員にはなるべく具体的に
『作業がどのように変わるのかを見せてあげよう』
【SwiftUI】ウィジェットを強制的に更新する

# はじめに
アプリ側でウィジェットの着せ替えを設定できる仕組みを作った際に、
着せ替えを変更したタイミングで即時にウィジェットに反映されないと「変更されないじゃん」と思われてしまう可能性が高いです。
それを防ぐためにアプリ側で強制的に更新させたいです。

今回はその方法を記事にしました。

# 実装
アプリ側で絵文字を設定するとウィジェットに表示される絵文字も変更されるというアプリで考えます。
`emoji`を`@AppStorage`で持ってAppGroupで共有しています。
これでウィジェット側でも`emoji`を使えるようになります。
```swift
import SwiftUI

struct ContentView: View {
    @AppStorage("emoji", store: UserDefaults(suiteName: "group.com.demo")) var emoji: String = "❔"
    
    private let emojis = ["🐶", "🐱", "🐭", "🐹", "🐰", "🦊", "🐻", "🐼", "🐻‍❄️", "🐨", "🐯", "🦁", "🐮", "🐷", "🐸", "🐵"]

    var body: some View {
        VStack {
            Text(emoji)
            
            Button {
                emoji = emojis.randomElement()!
            } label: {
                Text("絵文字変更")
            }
        }
        .padding()
    }
}
```

ただ、上記のコードでは変更がウィジェットのほうで即時反映されません。
そこで、ボタンを押したタイミングでウィジェットに更新リクエストを送ります。
```diff_swift
import SwiftUI
import WidgetKit

struct ContentView: View {
    @AppStorage("emoji", store: UserDefaults(suiteName: "group.com.demo")) var emoji: String = "❔"
    
    private let emojis = ["🐶", "🐱", "🐭", "🐹", "🐰", "🦊", "🐻", "🐼", "🐻‍❄️", "🐨", "🐯", "🦁", "🐮", "🐷", "🐸", "🐵"]

    var body: some View {
        VStack {
            Text(emoji)
            
            Button {
                emoji = emojis.randomElement()!
+               WidgetCenter.shared.reloadAllTimelines()
            } label: {
                Text("絵文字変更")
            }
        }
        .padding()
    }
}
```

:::note warn
ウィジェットを複数ターゲットで用意している場合、上記のコードを使用するとすべてのウィジェットが更新されてしまします。

特定のウィジェットターゲットだけ更新したい場合は、以下のようにバンドルIDを指定してください。

```swift
WidgetCenter.shared.reloadTimelines(ofKind: "com.demo.demo-widget")
```
:::

# 公式ドキュメント
https://developer.apple.com/documentation/widgetkit/widgetcenter
Pleasanterから通知されるリンクで編集画面の特定のタブに遷移したい

# はじめに
Pleasnateからの通知にURLを指定する場合、デフォルトであれば、基本的に全般タブへリンクします。複数のタブを用意したテーブルで、特定のタブへ直接リンクしたい場合、通知のカスタムデザインで設定できます。

# 実装イメージ
Pleasanterの編集画面で、タブを複数用意します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/922382/a18831bd-7dd8-6afe-2cb7-deb33e37065f.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/922382/bf95f7a4-ac98-381d-4344-4e0e84cebe9f.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/922382/0d714224-b5a0-1b2a-536f-b379ccc3f353.png)

このテーブルに通知を設定します。デフォルトだと以下のようなメールになるはず。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/922382/f56c475b-f08b-611a-2b6e-c4c8634a0657.png)

これでリンクを開くと、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/922382/ec487b9d-69dd-6145-5056-dbe98c7c0f88.png)
全般タブが開きます。

ここで、タブ１の項目を更新したらタブ１へリンク、タブ２の項目を更新したらタブ２へリンクするような設定を行います。


# テーブル設定
テーブルの管理 > 通知から設定します。

#### 全般タブへリンクする通知設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/922382/014f4069-f753-7eff-d426-078cb5f3d2d4.png)
ポイントとしては、変更を監視する項目から、タブ１、タブ２の項目を無効化しておきます。

#### タブ１へリンクする通知設定

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/922382/bfe1484e-0c2d-f073-0c1b-9546155f982f.png)


ポイントは３つ

- カスタムデザインのURLに、タブ遷移のリンクを付与します。
{Url}/edit?new=1#FieldSetTab1
→"/edit"以降がタブ１へのリンク指定になります。
- 変更を監視する項目にタブ１の項目のみを有効化
- 通知対象から作成を外す（有効にしておくと、タブ１項目未入力の状態でも新規作成時は通知対象となってしまい、全般タブとダブって通知されてしまうため）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/922382/f241b4ab-0d79-ea99-af8d-822fee2275f2.png)

このようにタブ１へのリンクが付与されて通知されました。

なお、各タブへのリンクの調べ方は、タブにマウスオーバーすることで、リンクが確認できるのと

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/922382/1a33ddb8-91d6-0dc7-18fd-7f47e90fee7e.png)

また、タブ上で右クリック→リンクをコピーして、エディタなどに貼り付けることで確認できます。

# 注意点
これでタブでのリンクを通知することはできますが、いくつか注意するポイントがあります。

- 例えば、タブ１で項目に値を入力→タブ２へ移動し項目入力し更新した場合、タブ１とタブ２の両方から通知されることになります。
- タブへのリンクで遷移遷移した後、他のタブへ移動して更新すると、通知からリンクしたタブに戻ってしまいます。どういうことかというと、

特定のタブにリンク
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/922382/048b8a5f-eb24-1599-5753-72f404b55158.png)


タブを移動し更新

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/922382/cdd8a5b6-2262-1533-4670-2f4af5bace55.png)

更新後、Urlにタブへのリンクが残ったままのため、更新後タブに戻ってしまう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/922382/dcede20b-dbb0-af66-4a60-be07ad36adac.png)


# 終わりに
概ね実現したいことはできたのですが、最後の注意点など細かな部分にこだわるのであれば、もう少し工夫（スクリプトなどによる？）が必要になってくるかもしれません。
【Rails7】StimulusとBootstrap 5トーストでフラッシュメッセージを表示

## 概要
このガイドでは、Bootstrap 5のトースト機能とStimulusを組み合わせてRailsアプリケーションにフラッシュメッセージを表示する方法を説明します。Bootstrapのトーストは、ユーザーに重要な情報を簡潔に提示するのに適しています。Bootstrapトーストの詳細は[こちら](https://getbootstrap.jp/docs/5.3/components/toasts/)で確認できます。

## 手順

### Stimulusコントローラの作成
まず、以下のコマンドを使用してStimulusコントローラを生成します。
```bash
./bin/rails generate stimulus toast
```

### コントローラの実装
`app/javascript/controllers/toast_controller.js` に以下のようにコードを記述します。

```app/javascript/controllers/toast_controller.js
import { Controller } from "@hotwired/stimulus"
import { Toast } from "bootstrap"

// Connects to data-controller="toast"
export default class extends Controller {
  connect() {
    this.element.querySelectorAll('.toast').forEach(toastNode => {
      let toast = new Toast(toastNode);
      toast.show();
    });
  }
}
```

### ビューの設定
フラッシュメッセージを表示するためのビューを設定します。`app/views/shared/_flash_message.html.erb` に以下を記述します。
fontawesomeが入っていますが、使って無ければ消しても問題ありません。

```erb
<div id="toast-container" data-controller="toast">
  <% flash.each do |message_type, message| %>
    <div class="mb-2 toast border-<%= message_type %>" role="alert" aria-live="assertive" aria-atomic="true">
      <div class="toast-header text-<%= message_type %>">
        <% if message_type.to_s == "success" %>
          <i class="fas fa-check-circle me-1"></i>
        <% else %>
          <i class="fas fa-exclamation-circle me-1"></i>
        <% end %>
        <strong class="me-auto"><%= message_type.to_s.capitalize %></strong>
        <button class="btn-close" data-bs-dismiss="toast"></button>
      </div>
      <div class="toast-body"><%= message %></div>
    </div>
  <% end %>
</div>

```

このコードは、Bootstrapのトーストコンポーネントを利用して、フラッシュメッセージを動的に表示します。`data-controller="toast"` 属性によって、Stimulusコントローラがこのビュー要素と結びつきます。

### トーストの動作
Bootstrapのトーストはデフォルトで一定時間表示された後、自動的に非表示になります。

### 実装例のスクリーンショット
以下は、成功と失敗のフラッシュメッセージがどのように表示されるかの例です。

- 成功時のフラッシュメッセージ：
  ![success-flash-message.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/849608/ab6481d2-6cb3-af80-d2c2-b9766e397eab.png)

- 失敗時のフラッシュメッセージ：
  ![fail-flash-message.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/849608/23efeee4-d3c4-e319-6546-c9e0e9771a26.png)
Salesforce sfコマンドを使った未管理パッケージのリリース

# 初めに
- せっかくVSCodeで作成したLWC、そのままCLIで未管理パッケージまで作成して他組織に配りたい、ってなった時にどうしたらいいのか全く不明だったので、一応できた手順をメモします
- とりあえずできた、というレベルのため、間違いなどありましたら適時コメントいただけると非常に嬉しいですし、理解が追いつけばその度更新いたします
- 手順系の情報が少ないので、参考になれば幸いですが、管理パッケージに関してはまだ挑戦しておらず、少し手順が変わる可能性があります😭

## 前提
- すでにsfdxプロジェクトを作成済みで、成果物がほぼ出来上がっている状態

## やること
### 1. 組織にVSCodeから認証します
### 2. Dev Hubを認証組織で有効化します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484310/44bc3e38-310c-be3e-a31a-bf98be81c481.png)
### 3. 対象組織のDev Hub組織をDefaultに設定します
```
// デフォルトのDev Hub組織の設定のための組織ログイン
sf org login web --set-default-dev-hub --alias DevHub
// 一応環境を開いて確認
sf org open --target-org DevHub
// 再度コマンドから対象組織のDevHubがDefaultになっているか確認
sf org list
```
### 4. 非管理Packageを作成します
```
sf package create --name yourPackageName --package-type Unlocked --path force-app
```

- そうすると、`sfdx-project.json`が下記のようになる
```json
{
  "packageDirectories": [
    {
      "path": "force-app",
      "package": "yourPackageName",
      "versionName": "ver 0.1",
      "versionNumber": "0.1.0.NEXT",
      "default": true,
      "versionDescription": ""
    }
  ],
  "name": "yourPackageName",
  "namespace": "",
  "sfdcLoginUrl": "https://login.salesforce.com",
  "sourceApiVersion": "58.0",
  "packageAliases": {
    "yourPackageName": "0H..."
  }
}
```

:::note warn
`Error (1): The requested resource does not exist`と表示されてしまった場合は、下記の通り対象組織で、[ロック解除済みパッケージと第二世代管理パッケージを有効化]を有効化してください
:::

- 設定 > Dev Hub

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484310/2e19bb0d-dcc7-773d-8436-ec945ad11f21.png)


### 5. パッケージバージョンを作成
```
sf package version create --package yourPackageName --path force-app --installation-key-bypass --wait 10 -v DevHub -c -f config/project-scratch-def.json 
```
  - 今回は、パッケージインストールパスワードを不要としています  
  - `-c`をつけるだけで、Code Coverageのチェックをするオプションとなります   
    - Coverageが75%に満たない場合、リリース版にPromoteできません 
  - 今回、カスタム表示ラベルのtranslationsのmetaファイルがあり、これは`-f config/project-scratch-def.json`をつけないとエラーになったため付けています  
  
https://salesforce.stackexchange.com/questions/405983/not-available-for-deploy-for-this-organization-when-adding-a-translation

  - また、この場合、`project-scratch-def.json`に下記設定を加える必要があります  

```json:project-scratch-def.json
    "languageSettings": {
      "enableTranslationWorkbench":  true,
      "enableEndUserLanguages": true
    }
```

### 6. インストールURLを確認

```
sf package version list --verbose
```
  - ちなみに、この段階ではBetaバージョンとなり、Developer EditionやSandboxにはインストールできるパッケージとなります

### 7. リリースバージョンにPromote

```
sf package version promote --package 04...
```
  - `04..`はパッケージバージョンIdを指定してください
  - これで、本番組織にもインストールできる未管理パッケージの作成完了となります

## 参考
- `sf package` コマンド一覧はこちらから：

https://developer.salesforce.com/docs/atlas.en-us.sfdx_cli_reference.meta/sfdx_cli_reference/cli_reference_package_commands_unified.htm#cli_reference_package_create_unified  

- Mediumの記事  

https://tempflip.medium.com/how-to-create-unlocked-salesforce-packages-with-a-namespace-e267cf361489
Gemini Pro APIをiOSで

Gemini Pro API公開されましたね

精度的にはGemini Ultraからかなり機能が絞られているだけあってGPT-4よりは劣ることが公式ベンチマークなどからもわかっていますが、一方で以下のようなメリットもあると思います。

- Google AI Studioですぐ試せる
- プレビュー版なのでまだ無料（ただし商用利用は不可）
- 画像を使ったマルチモーダルプロンプトも無料で試せる
- 各プラットフォームのライブラリとクイックスタートガイドが日本語で用意されている

最も注目すべきはもちろん一番最後、各プラットフォームのライブラリとクイックスタートガイドが日本語で用意されているというところです！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/10943/4ea25b08-f2c7-6bc4-8c59-4f8cf29eded1.png)

これは試しやすさに関して200点満点！

というわけで早速試してみたところを簡単に共有します。

## 動作の様子

<iframe width="478" height="850" src="https://www.youtube.com/embed/a33z9QYiPsI" title="iOS Gemini Sample" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>

アプリとしてはSwiftDataやSwiftUIを使ってプロンプトを実行したり、その結果を保存したりできる形にしました。

## やり方

やり方は公式のドキュメントがすでに充実しているのでそちらにお任せします。

https://ai.google.dev/tutorials/swift_quickstart?hl=ja

## 工夫ポイント・つまりポイント

とりあえず自分のコードがこちら

https://github.com/touyou/GeminiPlayground

Geminiの呼び出し部分は、画像のある無しでモデルを変える必要があったため以下のようにしました。

```swift
func execute(_ parts: [PartsRepresentable], hasImage: Bool) async throws -> String? {
    let modelName = hasImage ? "gemini-pro-vision" : "gemini-pro"
    let model = GenerativeModel(name: modelName, apiKey: GeminiAPIKey.default)
    let response = try await model.generateContent(parts)
    print(response.candidates)
    print("FB: ", response.promptFeedback ?? "none")
    return response.text
}
```

また、APIからの一個のプロンプトは合わせて4MB以下にする必要があるため、画像は以下のように圧縮して持つようにし

```swift
.onChange(of: selectedItems) {
    Task {
        selectedImages.removeAll()
        
        var datas = [Data]()
        for item in selectedItems {
            if let imageData = try? await item.loadTransferable(type: Data.self),
               let uiImage = UIImage(data: imageData),
               let compressionData = uiImage.jpegData(compressionQuality: 0.25) {
                selectedImages.append(Image(uiImage: uiImage))
                datas.append(compressionData)
            }
        }
        promptImages = datas
    }
}
```

また編集画面に今のサイズをステータス表示するようにしています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/10943/3ada2536-fd7e-30f8-ed45-3beb2cc75850.png)

実際はさまざまなPayload含めて4MBなのでギリギリを攻めることはできませんでした。

## まとめ

以上めちゃくちゃクイックにですが、iOSでGemini Pro APIを使ったら、を紹介しました。
速度重視記事ということで最低限の内容でしたが、参考にしてもらえれば嬉しいです。
CentOS7にMariaDBをインストール

CentOS7にMariaDB Server11.2.2をインストールする手順を記録します（2023年12月）。

# yumリポジトリの設定
以下のコマンドを実行する。
```
$ curl -sS https://downloads.mariadb.com/MariaDB/mariadb_repo_setup | sudo bash
```
# MariaDB Serverのインストール
以下のコマンドを実行する。
```
$ sudo yum install MariaDB-server
```
- `Is this ok [y/d/N]: `が出力されたら、`y`を入力して進む
- `完了しました!`と出力されたらインストールが完了

# mariadb serviceの有効化・開始
以下のコマンドを順に実行し、有効化・開始する。

```
$ sudo systemctl enable mariadb
$ sudo systemctl start mariadb
```

# 参考
[MariaDB 「CentOS7にMariaDB　Community　Server最新版をインストール」](https://mariadb.com/ja/resources/blog/install-mariadb-server-centos7/)
PHPでdh key too smallエラーを解決する

## 概要
openssl`1.1.1`から、[opensslの設定が変わり](https://www.google.com/url?q=https://wiki.debian.org/ContinuousIntegration/TriagingTips/openssl-1.1.1&sa=D&source=editors&ust=1702441550562129&usg=AOvVaw303sCdJtutwRxHltstCllb)、デフォルトのセキュリティレベルが``2``になった。
通信の際に使用する鍵の長さが想定より短い場合、`dh key too small`というエラーが発生し、通信が失敗してしまう。

> This is caused by the SECLEVEL 2 setting the security level to 112 bit. This means that RSA and DHE keys need to be at least 2048 bit long.

## 設定を見てみる
```shell
find / -name openssl.cnf
```

```
[system_default_sect]
MinProtocol = TLSv1.2
CipherString = DEFAULT@SECLEVEL=2
```

この`DEFAULT@SECLEVEL`はopenssl`1.1.0`では``1``だったが、2になっている。

## 解決方法
- `DEFAULT@SECLEVEL`を1に下げる
    - opensslの設定ファイルで`DEFAULT@SECLEVEL=2`を `DEFAULT@SECLEVEL=1`にする
        - これはアプリケーションのすべての通信に影響するのでできれば避けたい
    - プログラムレベルで通信時のセキュリティレベルの設定を変える
        - 言語により通信時の設定ができる機能があると思うのでそれを利用
            - PHPなら[curl_setopt](https://www.php.net/manual/ja/function.curl-setopt.php)とか
- 鍵の再設定をする
    - （試していませんが）通信先の設定もいじらないといけない場合があるため、難しいかも。可能であればこちらが理想

※ セキュリティの設定なので詳しい方と相談する。

## さいごに
ライブラリのパッチバージョンが`1`違うだけでもこういった現象が起きうることが分かりました。
念頭においておきたいと思います。

## 参考
https://www.google.com/url?q=https://wiki.debian.org/ContinuousIntegration/TriagingTips/openssl-1.1.1&sa=D&source=editors&ust=1702441550562129&usg=AOvVaw303sCdJtutwRxHltstCllb
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=907788#21
https://www.openssl.org/policies/releasestrat.html

## 補遺
opensslは1.1.1もサポートを終了している。
https://www.openssl.org/policies/releasestrat.html
> Versions 1.1.1 and 1.0.2 are no longer supported.

サポートが終了しているバージョンを使用している場合は（可能なら）openssl3系に速やかに移行するべき。
コマンド覚えるのめんどいならオリジナルコマンド作ろう

## 概要

よく使うコマンドがあるけどパイプとか繋げて入力するの怠い(覚えられない)し, histroyコマンドで探るのもめんどい
ので自分用にコマンド作ってみる

## 手順
### オリジナルコマンドを格納するディレクトリを作成する

```bash
# ホームディレクトリに移動する
% cd
# ディレクトリ&ファイル作成&実行権限をつける
% mkdir {任意のディレクトリ} & touch {任意のディレクトリ}/{任意のファイル名} & chmod 777 {任意のディレクトリ}/{任意のファイル名}.sh
```

### オリジナルコマンドを作成する

```bash:{任意のディレクトリ}/{任意のファイル名}.sh
#!/bin/sh
uuidgen | tr "[:upper:]" "[:lower:]"
```

### パス追加

```bash:~/.zshrc
export PATH=$HOME/{任意のディレクトリ}:$PATH
```

### 読み込み(orターミナル再起動)

```bash
% lower_uuid
2edf9ade-03be-4079-a29d-bc1d48d1f2d6
```

### 以上

あとは, 自分好みのコマンドをどんどん作成したディレクトリ配下に追加していって, 必要があれば `~/.zshrc`を再読み込みorターミナル再起動するだけで使えるようになります