OmniAICreator/Qiita-1.07M huggingface dataset:
【Swift】人の名前を扱う

# はじめに
`PersonNameComponents`というものを知りました。

`DateComponents`のように人の名前を管理できるようです。
めっちゃ便利そうなので基本的な使い方を記録しておきます。

# イニシャライザはこんな感じ
本記事で登場してもらうのは、「山田ルーカス太郎3世」です。
あだ名は「タロー」です。

```swift
var personNameComponents = PersonNameComponents(
    namePrefix: "Mr.", /* Mr., Mrs., Ms.など */
    givenName: "太郎", /* 名前 */
    middleName: "ルーカス", /* ミドルネーム */
    familyName: "山田", /* 苗字 */
    nameSuffix: "3世", /* Sr., Jr., I, II, IIIなど */
    nickname: "タロー", /* ニックネーム */
    phoneticRepresentation: nil /* 受信機の音声表現名コンポーネント。（公式ドキュメントを翻訳しただけ。何に使用するか不明） */
)
```

# style
### abbreviated
familyNameのみ
```swift
let formatter = PersonNameComponentsFormatter()

formatter.style = .abbreviated

print(formatter.string(from: personNameComponents)) // 山田
```

### default
familyName + givenName
```swift
let formatter = PersonNameComponentsFormatter()

formatter.style = .default

print(formatter.string(from: personNameComponents)) // 山田太郎
```

### long
namePrefix + familyName + givenName + middleName + nameSuffix
```swift
let formatter = PersonNameComponentsFormatter()

formatter.style = .long

print(formatter.string(from: personNameComponents)) // Mr. 山田太郎ルーカス 3世
```

### medium
familyName + givenName
```swift
let formatter = PersonNameComponentsFormatter()

formatter.style = .medium

print(formatter.string(from: personNameComponents)) // 山田太郎
```

### short
nicknameのみ
```swift
let formatter = PersonNameComponentsFormatter()

formatter.style = .short

print(formatter.string(from: personNameComponents)) // タロー
```

# おわり
文字列で管理しているよりいいですね。

# 参考記事
https://qiita.com/treastrain/items/e0e9c3e9f517fa20ad08#numberformatter

# 公式ドキュメント
https://developer.apple.com/documentation/foundation/personnamecomponents

https://developer.apple.com/documentation/foundation/personnamecomponentsformatter/1642979-personnamecomponents
[翻訳転載] Golang Tip #3: パフォーマンスを考慮したスライスの初期化

# はじめに

https://qiita.com/a10a/items/5063899c9f4a3bf4a2f2

本記事は以下のツイートの翻訳転載です。

https://x.com/func25/status/1727362895514943975?s=20

スライスの初期化についての内容になります。

# パフォーマンスを重視したスライスの初期化[^1]

[^1]: `pre-allocation`

なぜパフォーマンスを考慮する必要があるのかについては次のPostを参照してください。

https://x.com/func25/status/1727363227749961777?s=20

以前は、`make(a, 10)` を使って初期化していました。

が、結果的に先頭に意図しないゼロを大量に含んでしまう`append()`（画像参照）を頻繁に手癖で書いてしまっていました。

これを避けるために、現在ではより効果的な初期化の方法である `make(a, 0, 10)` を使うようにしています。

![image](https://pbs.twimg.com/media/F_jRw02bcAAJ5dS?format=jpg&name=medium)

# おわりに

### `make`でのスライスの初期化について

Goのスライスには長さ（`length`）と容量（`capacity`）という概念が存在しています。

`make`を使用してスライスを初期化する場合、`make([type], [length], [capacity])`のように指定します。

```go
func main() {
	a := make([]int, 5)
	fmt.Printf("a (length: %d, capacity: %d)\n=> %v\n", len(a), cap(a), a)
	// a (length: 5, capacity: 5)
	// => [0 0 0 0 0]

	b := make([]int, 0, 5)
	fmt.Printf("b (length: %d, capacity: %d)\n=> %v\n", len(b), cap(b), b)
	// b (length: 0, capacity: 5)
	// => []

	c := make([]int, 0)
	fmt.Printf("c (length: %d, capacity: %d)\n=> %v\n", len(c), cap(c), c)
	// c (length: 0, capacity: 0)
	// => []
}
```

はじめから長さを持っているスライスに`append`してしまうと、初期化時の長さの分だけ先頭にゼロ（ゼロ値）を含むスライスができてしまうわけです。

JavaScriptでも同じような挙動になります。

``` javascript
const arr = Array.from({ length: 5 });

arr.push(5);

console.log(arr);
// [undefined, undefined, undefined, undefined, undefined, 5]
```

### スライスの容量について

長さについてJavaScriptと比較しましたが、容量については、JavaScriptには無い概念です。

スライスの長さの変更に比べて、容量に変更が発生した場合の負荷は大きいです。

４人乗りの車を家族４人で乗り回してるうちは良いですが、家族が５人になってしまうと車自体を買い替えないといけないので大変です。

https://qiita.com/takurUN/items/d2c6dc1277646005474d

パフォーマンスを考慮すると、スライスの容量に変更がないように初期化するべきではあるのですが、

長さの変更に比べて負荷がかかるとはいえ、微々たるものではあるので、ごりごり開発を進める段階においてスライスの初期化は

```golang
func main() {
	var c []int
}
```

としておいて、
リリース前に余裕がある場合はリファクタすれば良し、余裕がなければ問題が顕在化するまで放置で良しで良いと思っています。

※例外的に、以下のような場合は`make`で長さと容量を指定した初期化を行います。

```golang
func main() {
	src := []int{1, 2, 3, 4, 5}
	dst := SliceMap(src, func(v int) string {
		return fmt.Sprintf("value: %d", v)
	})
	fmt.Printf("dst: %v\n", dst)
	// dst: [value: 1 value: 2 value: 3 value: 4 value: 5]
}

// SliceMap はJavaScriptのArray.prototype.mapのようなものです。
func SliceMap[E1 any, E2 any](src []E1, f func(E1) E2) []E2 {
	// スライスの長さと容量が明らかに決定している場合、かつスコープが短い場合はmakeを使う
	dst := make([]E2, len(src), cap(src))
	for i, v := range src {
		dst[i] = f(v)
	}
	return dst
}
```
Windows11 ターミナルのデフォルトをPowerShell 7へ変更

Windows11にPowerShell 7をインストールしたのですが、ターミナルを起動するとPowerShell 5のままだったのでターミナルの既定のプロファイルを変更しました。

# PowerShell 7のインストール
※PowerShellウィンドウから実施
```:コマンド
winget install --id Microsoft.Powershell --source winget
```
```:出力
PS C:\Users\user01> winget install --id Microsoft.Powershell --source winget
見つかりました PowerShell [Microsoft.PowerShell] バージョン 7.4.1.0
このアプリケーションは所有者からライセンス供与されます。
Microsoft はサードパーティのパッケージに対して責任を負わず、ライセンスも付与しません。
ダウンロード中 https://github.com/PowerShell/PowerShell/releases/download/v7.4.1/PowerShell-7.4.1-win-x64.msi
  ██████████████████████████████   103 MB /  103 MB
インストーラーハッシュが正常に検証されました
パッケージのインストールを開始しています...
インストールが完了しました
```

# ターミナルの起動
Windows11にPowerShell7をインストールしてもスタートメニュー右クリックからターミナルを起動した場合、PowerShellはバージョン5のままです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3297641/11d1e7ba-b9a4-a629-43b6-007cf38850aa.png)

# デフォルトターミナルの変更
1. ウィンドウ上部のメニューを開いて設定を表示
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3297641/87b0061f-03af-fcab-0c58-928e6be9d96d.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3297641/95f60775-5feb-1da1-ac28-a434e6d359c8.png)

1. スタートアップの既定のプロファイルをWindows PowerShellからPowerShellに変更
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3297641/66abc990-a51e-8bcb-bb17-a29f03d560a1.png)

1. 保存をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3297641/5b120f6c-cb65-91d0-4cd6-5dd841d9a0bb.png)



1. ターミナルウィンドウを閉じる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3297641/a27dfcf1-9827-950d-2a87-a6604906a17d.png)

※次回ターミナル起動時からPowerShell 7 が立ち上がります。
【テンプレ配布】Web系エンジニア向けの職務経歴書


![cv.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3687343/2cc7862d-c2e4-37f0-9474-4b2d6529fc6c.png)

## はじめに

職務経歴書のテンプレは落ちているけど、何かダサかったり、  
エンジニア向けじゃなかったりだったので自作しました ✂️

良い感じに作れたのでこれから就活・転職される方にお使いいただければと思います 🥹

## 使い方

- 🎁：[https://drive.google.com/](https://drive.google.com/drive/folders/1Sz86zeCnkbAbckQpPGGePJ6D6JQID_q7?usp=sharing)

1. 🎁 > 職務経歴書 からお好きなバージョンのスプレッドシートを開き、  
   「ファイル」>「コピーを作成」でご自身のドライブに保存します
2. サンプルを参照しながら必要な項目を入力します  
   （入力欄が足りない場合はいい感じにコピーしてください）
3. 「ファイル」>「ダウンロード」>「PDF」をクリックし印刷設定を開きます
4. 余白を調整し、「印刷形式」>「配置」を  
   [　水平：中央　　　垂直：上　]
   に設定しエクスポートで PDF をダウンロードします

## おわりに

ご自由に編集してお使いください 💄  
良きエンジニアライフを！

PS.要望等があればコメントでお知らせいただけると嬉しいです 🙇
Route53 DNSクエリログを出力するように設定する

## 概要

Route53にて DNSクエリログを出力するように設定する方法を簡単に説明する。
ちなみにログはバージニア北部リージョンのCloudWatchに出力される。
また詳細なログの内容の説明は本記事では行わない。詳細なログの情報は下記で公式のドキュメントに記載されている。

https://docs.aws.amazon.com/ja_jp/Route53/latest/DeveloperGuide/query-logs.html#query-logs-format

上記を自分なりに解釈した内容を下記にまとめた

https://qiita.com/miriwo/items/e0a599467c74b750f550

## 方法

1. ログを出力したいドメインが管理されているホストゾーンの詳細画面を開く。

    ![Cursor_と_miriwo_work_-_詳細.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/d06bede6-f9b9-bff9-ef53-99e2fc168ca3.png)

1. 「クエリログの設定」を開く。

    ![Cursor_と_miriwo_work_-_詳細.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/407ec537-d30f-ec70-9d48-266e1cebd642.png)

1. 「アクセス許可なし」と表示されていたら「アクセス許可の付与」をクリックする。

    ![Cursor_と_miriwo_work_-_クエリログ記録の設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/0d02d7ee-2fec-f056-ade0-35b0f96e15f0.png)

1. 「ロググループを作成」をクリックする。

    ![Cursor_と_miriwo_work_-_クエリログ記録の設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/f26a3eec-351e-f9ac-1450-a95af0853600.png)

1. 任意の「新しいロググループ名」を入力し「作成」をクリックする。

    ![Cursor_と_miriwo_work_-_クエリログ記録の設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/60f55f33-ee75-117d-8de8-9990a44dddd5.png)

設定そのものはこれで完了である。

## 注意事項

本方法でログ出力の設定を行うと**バージニア北部リージョン**CloudWatchにロググループが作成されてログが出力される。

おそらく、本記事にたどり着いた皆さんは東京リージョンか大阪リージョンがメインなはずなので、ここは注意する。

## 参考文献

https://docs.aws.amazon.com/ja_jp/Route53/latest/DeveloperGuide/query-logs.html#query-logs-configuring
駆け出しエンジニアがMicrosoft AI Tour Tokyoで見てきたもの

# 自己紹介
こんにちは。
私は2023年10月(まだ5ヶ月目)に転職をして社内SEとしてAIを搭載した業務システムの開発に携わっています(と言ってもOJT的なことばかり)。これまでは全く関係ない業界で働いており、大規模な開発業務的なものに関わってこなかったので新米も新米です。

会社でAzureを採用していることもあり、業務の一環としてMicrosoft AI Tour Tokyoに参加したところ、大興奮のまま帰宅となったので、この熱量のまま思ったことを書き散らしたいと思います。
私が誤解していたりして正確さに欠けるところがありましたら、ご指摘頂ければと思います。
![PXL_20240220_041828977.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3634883/8fff4d1b-292a-f6c5-9ec7-b1798d1cf78d.jpeg)

# Microsoftが推すCopilot
openAI社がchat GPTを公開したことを起点にLLMブームが巻き起こりました。昨年(2023年)はgithub copilotやBing chat(現 copilot)が公開され、誰でも簡単に利用可能な状態になっています。
MicrosoftではOffice製品にもcopilotを導入しており、いつでもどんなシチュエーションでもどんなプラットフォームにおいても利用出来ることを目指しているようです。
日本Microsoftの津坂CEOは「AIを語るときは終わった」と仰っていました。2024は「AIを導入する年になる」とのことで、MicrosoftがCopilotを中心に据えたサービスの展開に注力していることを強調されていました。
Keynoteで私が特に感銘を受けたのは、「あくまでCopilotでありAutopilotではない」ということです。インターネット上ではAIの台頭により仕事を奪われる、などという言説を見かけることがありますが、Microsoft曰く「AIにより単調な仕事が省略されることで、人間が活躍するフィールドを広げる」ことを目指すべきであるとのことです。アイデア出しの壁打ち相手がAIであったり、議事録を纏めるのがAIであったりしても、そこには必ず人間がいて、アイデアを押し広げていける、という世界がもう来ているんだと強い確信を得ました。

# 要となるFabric
ビッグデータをどうにかこうにかしてソリューションを得る、というのは何年も前からある話だと思います。DXという言葉も思えばけっこう前から使われているような気がします。
ところが大量のデータを扱うというのはそんな簡単な話では無いため、志半ばにして挫折し中途半端なDXをやって、やった気になっている企業は多いのではないでしょうか。特にデータの形が画像、pdf、最悪の場合紙などバラバラになっていることも多いかと思います。Azure AIサービスを使えば、文章、画像、音声と言った様々な形のデータから情報を抽出してcopilot等で利用可能になるようです。AIの設計やチューニングはGUI上で行うこともコードを書いて設計することもできます。また、社内のSharePointや各サーバーに点在してしまっているデータもfabricを通して接続することで、データをAI(copilot)のために移動・収集することなく利用できるらしい(ほんと～？)。
基調講演でも言及されていたのですが、LLMの登場により非構造化データを簡単に扱えるようになったことを活用できない会社は競争に負けると感じました。

# Prompt flow
流行りのRAGを初めとしてAzure AIを用いて作成されたAIは、Azure AI Service上で
そのモデルの処理フローを確認したり、編集したりすることができます。
これがけっこう凄くて、ワークショップではVSCode上でフローを触るというのを体験しました。設定はあれこれ大変でしたが、自作したCopilotやLLMのフローをグラフィカルに確認しながら（しかもVSCode上で）プロンプトの修正やコードの追加が行えるということで、今後理解を深めていきたいなと感じた機能の一つでした。これだけ使いやすいものがあるならLangChainのようなものは不要なのでは......？


# 最後に
実は東京では初開催だったらしいのですが、たくさんの人が集まりホットな意見を交換できてとてもハッピーな一日だったのではないでしょうか。
AIによって人間の仕事が奪われるのではなく、人間の活躍するフィールドが増えていく。
裏を返せば増えたフィールドで勝負できない人間は淘汰されるということです。クリエイティブな活動を続けていけるように地道に勉強を続けていかねばならないと決意を新たにした一日となりました。


お昼ご飯に提供して頂いたローストビーフ丼は米がカチカチであまり美味しくなかったです(笑)
おやつにはお団子や稲荷寿司なども提供されました（これは美味しかった）。ケータリングはヒルトンだったようで？、会場全体的におもてなし空間でした。
ありがとうございました！

![PXL_20240220_032117104.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3634883/d1bba8e6-6a64-6613-0276-ba1946d312f1.jpeg)
![PXL_20240220_063147865.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3634883/829f1375-524c-1785-fe91-ede3d9cc2bc2.jpeg)
![PXL_20240220_064443070.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3634883/21aa625e-fa26-5b1d-d20b-eed7dbc9f16a.jpeg)
【Eclipseと】GitHubからSpringBootプロジェクトをクローンしたい【SourceTreeを使用】

## はじめに
今回はGitHub上のSpringBootプロジェクトをSourceTreeでクローンしてEclipseでエディットするまでの流れを簡単に記述していきます。初心者向け記事であり,私も初心者です。
## 用意するもの
- Eclipse
- SourceTree
- GitHubのSpringBootプロジェクトのリポジトリ
ご用意のある方はご自身のプロジェクトで,
本記事では例として以下のサイトで紹介されているプロジェクトのコピーを使います。

https://medium-company.com/mybatis-spring/

<font color="rgb(107, 142, 35)">Maven, Gradle どちらでも大丈夫です。</font>
## 手順.1 SourceTreeでクローン
GitHub上のリポジトリをコピーします。
画像の赤枠にご注目,[Code]->[HTTPS]->[コピー]
![Sample01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3667563/0e2b9d0d-0b9c-64c7-f47c-200b701f3d9f.jpeg)

次にSourceTreeでの操作です。
[Clone]項目から

一つ目のテキストボックスにはリポジトリを記述します。すなわち先ほどGitHubでコピーしたものをペーストするのみです。

二つ目のテキストボックスにはクローンしたプロジェクトを保存するフォルダのパスを記述する必要があります。ここで注意することは…
- 指定したフォルダが空であること
- フォルダのパスはあとで利用するので忘れない

以上の二点です。
<font color="rgb(107, 142, 35)">今回は例として分かりやすくするため,デスクトップに"GitSample"という空フォルダを用意しました。</font>

空欄が埋まれば最下部の[クローン]を押すのみです。
![Sample02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3667563/ac9f237b-e510-76d3-a86e-f3f2f7950a1e.jpeg)

無事にクローンが完成していれば"GitSample"のフォルダはこのようになっていると思います。クローン成功です。
<font color="rgb(107, 142, 35)">".git"ファイルは隠しファイルなので特に設定していなければ表示されません。</font>
![Sample03.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3667563/9cfec0e3-4121-d297-c07d-bf840a87e298.jpeg)
## 手順.2 Eclipseをエディタにする(プロジェクトのインポート)
Eclipseを起動後,画面左上の[ファイル]->[インポート]を選択します。選択画面では,
クローンしたプロジェクトがGradleプロジェクトなら[既存のGradleプロジェクト]
Mavenプロジェクトなら[既存のMavenプロジェクト]を選択しましょう。
<font color="rgb(107, 142, 35)">私はMevanを選択しました。</font>
![Sample04.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3667563/60439f10-851d-831b-a40d-c2530f30bd59.jpeg)
プロジェクトのパスが求められます。ここで[参照]からクローン先のフォルダ内のプロジェクトを選択します。このあとMavenプロジェクトでは[完了]を押すだけでした。
![Sample05.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3667563/f2749520-187d-5a7b-3c83-8e2786b7ad83.jpeg)
無事インポートされると<font color="#1e90ff">>プロジェクト名[boot][devtools][Gitブランチ名]</font>
など表示されています。

<font color=red>特に[boot]と表示されない場合はSpringBootプロジェクトと認識されていない可能性があり"pom.xml",Gradleプロジェクトの場合は"build.Gradle"のような設定ファイルの記述等を再確認する必要があります。</font>
![Sample06.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3667563/2a9922db-8708-a185-debe-508ce10cea63.jpeg)

ひとまずEclipseで変更したコードの記述をSourceTreeが監視する関係の構築が完了しました。お疲れさまでした。
## おわりに
プロジェクトの全体を監視すると,
自身のコーディング以外にも色んなファイルたちがコミットしてほしそうにこちらを見ている現象について解説や解決策がある有識者の皆様…助けて…＜(´⌯  ̫⌯`)＞
![Sample07.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3667563/0b2e85a3-42a0-2f97-ac19-38e695c727fd.jpeg)
ALB アクセスログと接続ログをS3に出力するように設定する

## 概要

ALBにリクエストが来たことをログに出力する方法を簡単にまとめる。
また出力されるログの内容も本当に簡単にだけ説明する。（「こんな情報が出ます」レベルの共有です。）細かい項目に関しては別途ご自身でお調べいただきたい。

## ALBで出力できるログ

ALBでは主に「アクセスログ」と「接続ログ」の出力をする事ができる。
ログはファイルとしてS3に出力される。

### アクセスログ（Access Log）

「どのようなリクエストがきてどのくらい処理に時間がかかったか」が詳細に書いてあるログ
いっぱい情報が書かれてるから一行がながーい

### 接続ログ（Connection Log）

「誰が接続したか」が書いてあるログ
日時情報、IPアドレス、接続結果ステータスが書いてある
シンプル

## ALBでログを出力させる方法

### 概要

先にも記載したがALBのログはS3にファイル形式で出力される。（たしかリクエストがあった場合5分刻みに区切ってファイルが出力されたはず。）
なのでバケットを用意するか、既存バケットにフォルダを作成しておこう。
筆者はログ単体のバケットを作成し、「access-log」と「connection-log」のフォルダを作成してそれぞれ格納した。

### 作業

S3の準備ができたら早速作業に取り掛かろう

1. ALBの詳細画面を開く。
1. 「アクション」から「ロードバランサーの属性を編集」をクリックする。

    ![Cursor_と_ロードバランサーの詳細___EC2___ap-northeast-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/19b579ec-42f9-933d-67ad-881777ce2f86.png)

1. 遷移先画面で「アクセスログ」と「接続ログ」のスライダーがあるので両方とも「ON」にする。

    ![Cursor_と_ロードバランサー属性を編集___EC2___ap-northeast-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/04e79e6f-b582-8697-43d9-09912dad4b77.png)

1. S3 URIを使ってバケットとフォルダを指定することができるので指定する。

    ![Cursor_と_ロードバランサー属性を編集___EC2___ap-northeast-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/f11c006d-ba68-7cd4-d72f-cbb10e493dfe.png)

1. 設定できたら「変更内容の保存」をクリックして保存をする。

これで準備完了だ。

## ログを見てみる

上記の設定が行われている状態でALBにリクエストが来ると先ほど設定したS３のフォルダの中にログファイルが作られる。（ログファイルは5分間隔で作成される。なのでリクエストが来たからと言ってすぐファイルが出力されるわけではない。）
S3 URIで設定したフォルダ直下にログファイルができるわけではなくある程度深いディレクトリが作られてログファイルが設置されたはずである。（記憶違いだったら申し訳ない。）
WindowsのLogseqでローカルネットワーク上(wsl含む)にある画像を表示する

かなりニッチだけど誰かは救われるかもしれないのでメモ
ほかの方法あったら教えてください (サーバー立てる以外で)

# markdownで表示しようとしてみる

Logseqではmarkdownを描けるので`![](sample.jpg)`として画像を表示できる。

この場合、書き込んでいるファイルからの相対パスが使用される。
```
file:///C:/Users/USER_NAME/AppData/Local/Logseq/app-0.10.6/resources/app/journals/sample.jpg
```

そしてwslのファイルパスは以下のようなもの。
```
file://wsl.localhost/Ubuntu/home/USER_NAME/sample.png
```

なので以下のようにすればいいように思える。
```md
![](file://wsl.localhost/Ubuntu/home/USER_NAME/sample.png)
```

だがこうした場合、Logseqが相対パスと見なしてしまうので画像は表示されない。
```md
![](file:///C:/Users/USER_NAME/AppData/Local/Logseq/app-0.10.6/resources/app/journals/wsl.localhost/Ubuntu/home/USER_NAME/sample.png)
```

# imgタグを使う

勝手に相対パスと見なされるので仕方がない
markdownにはhtmlタグを直接かけるので、srcに直接アドレスを書けば表示される。

```html
<img src="file://wsl.localhost/Ubuntu/home/USER_NAME/sample.png" />
```

・・・けどそんなの書いてられないよね

# マクロを設定する

マクロは`{{macro_name arg_1 arg_2}}`のように書いた箇所を、指定した文字列で置換する機能。

設定ファイル(config.edn)を開き`:macros`を設定する
コメントを頼りにimgタグのマクロを追加してみる

```clojure
 ;; Macros replace texts and will make you more productive.
 ;; Example usage:
 ;; Change the :macros value below to:
 ;; {"poem" "Rose is $1, violet's $2. Life's ordered: Org assists you."}
 ;; input "{{poem red,blue}}"
 ;; becomes
 ;; Rose is red, violet's blue. Life's ordered: Org assists you.
 :macros {
            {"img" '<img src="$1" />'}
          }
```

これでどこでもmacroが利用可能となる以下のように記載すれば画像が表示される
```
{{img file://wsl.localhost/Ubuntu/home/USER_NAME/sample.png}}
```

ドキュメント: https://docs.logseq.com/#/page/macros

## 備考
- この場合、画像の拡大縮小ができない
    - markdownで表示する画像は画像の右下のハンドルで拡大縮小できる
- マクロで文字列が置換されるのはLogseqで見ているときだけ
    - markdownではないのでvscodeなどで開くともちろん画像は表示されない

# おまけ: hiccupを使う

LogseqはClojureScriptで書かれており、Clojureのhtmlテンプレートエンジンであるhiccupを使える。
これを利用するとimgタグは以下のようになる。
```clojure
[:img {:src file://wsl.localhost/Ubuntu/home/USER_NAME/sample.png}]
```

なのでマクロもこう書ける。

```clojure
 :macros {
            {"img" '[:img {:src $1}]'}
          }
```

マクロで書くならどっちでもいいが手書きするならhiccupのほうが少し短い。それだけ。

ドキュメント: https://docs.logseq.com/#/page/hiccup
Pythonでスピードテスト作ってみた

こんにちはKです。

今回はいつもスピードテストのサイトに行って回線チェックを行うのですがPythonでチェックできないかなと思い調べると簡単に見つかったので紹介します。


>pip speedtest-cli

```ruby:Python
    import speedtest 
    
    st = speedtest.Speedtest()
    st.get_best_server()
    
    # 速度測定を実行
    download_speed = st.download() / 1024 / 1024  # Mbpsに変換
    upload_speed = st.upload() / 1024 / 1024  # Mbpsに変換
    ping = st.results.ping
    
    print("[測定結果]")
    print(f"download_speed: {download_speed}Mbps")
    print(f"upload_speed: {upload_speed}Mbps")
    print(f"ping: {ping}ms")

```
これだけです。
これで毎朝自分にメールで回線チェックができるようになりました。
めでたしめでたし
pyPDFを使用した簡易PDF結合ツールを作った

# 概要
タイトルに示す通り，PDFファイルに対して様々な加工を行う機能を備えたPythonの非標準ライブラリ「pyPDF」を用いた簡易的なPDF結合ツールを作った．このツールを用いることで複数のpdfファイルを結合して1つのpdfファイルを生成することができる．
pyPDFにはPDFMargerクラスというクラスがもともと存在しており，結合にはこれが用いられていたようであるが，このクラスは将来的に廃止されてしまうらしい．そのため今回は公式ドキュメントで利用を推奨されているPDFWriterクラスを用いた．
# 前提
- 使用OS: Windows11
- Pythonのバージョン：3.11.8

# 使用するライブラリ
- pyPDF: PDFの様々な加工や読み取りを行う非標準ライブラリ．次の項でインストールする．
- glob: 指定した条件を満たすパスの一覧を取得する機能を備えたライブラリ．標準なのでインストールの必要はない．
- time: sleep関数を使用するためにimportする．こちらも標準

# 準備
以下のコマンドによりpyPDFをpipでダウンロードした．
```
pip install pypdf
```

# ツールの構成
ツールは下記に示すディレクトリで構成される．file_to_mergeディレクトリには結合したいファイルを配置し，結合されたファイルはmergedディレクトリに配置する．またこの他に結合を行うmerge.pyをmergerディレクトリ下に配置する．
```
merger
├─file_to_merge
└─merged
```

# merger.py
merger.pyのコードを以下に示す．
```python:merger.py
import glob
from pypdf import PdfWriter
import time

# glob.glob: 指定した条件を満たすパスをすべて取得し，リストを返す
file = glob.glob("/pdf_merger/file_to_merge/*")
merger = PdfWriter()

# pdfファイルを順にmerge
for pdf in file:
    merger.append(pdf)

# mergedディレクトリに結合されたファイルを書き出し
merger.write("/pdf_merger/merged/merged.pdf")
merger.close()

# 処理の終了を知らせる出力
print("finish")
time.sleep(1)
```

# 動作(使用方法)
merger/file_to_mergeに結合したいファイルを配置し，merger.pyを実行するとmerger/mergedにmerged.pdfが生成される．

# まとめ
pypdfとその他いくつかのライブラリを用いて複数のpdfファイルを結合するツールを作ることができた．guiは実装していないながら，一応の実用性を担保できたのではないかと思う．

# 参考
MergingPDFFiles: pyPDFのユーザーガイド．PDFファイルを結合する方法が紹介されている．globを使用した以外はほぼすべてここを参考にしています．
https://pypdf.readthedocs.io/en/stable/user/merging-pdfs.html

Pythonで条件を満たすパスの一覧を再帰的に取得するglobの使い方：glob関数はこちらを参考にしました
https://note.nkmk.me/python-glob-usage/
arXivの論文をhtml形式で読むのを効率化【研究Tips】

# はじめに
arXivの論文のURLを`arxiv`→`ar5iv`とするとHTML形式で読むことが出来ると先輩に教えていただきました。
HTML形式にすると、Googleの自動翻訳が使えるのでさっと読みたいときに非常に便利です。
毎回手動で変換することはめんどくさいので、ブックマークバーに登録して自動で変換してくれる機能(ブックマークレット)を作成しました。
```
https://arxiv.org/abs/2311.18259
https://ar5iv.org/abs/2311.18259
```


# ブックマーク
Chromeでの登録方法を紹介します。動作確認はChromeのみでしか実施していません。

1. ブックマークバーを右クリックしてブックマークバーを表示にチェックを入れる
ホーム画面以外でも常にブックマークバーが表示され、arxiv閲覧中にブックマークバーから機能を使うことが可能に
1. ブックマークバーを右クリックして、ブックマークマネージャを選択
1. ブックマークマネージャにて、右上の３点リーダーアイコンをクリックして、新しいブックマークを追加を選択
1. 名前（自由）、URL（以下のコード）を入力して保存
```javascript:URL
javascript:(function() {
  var oldUrl = window.location.href;
  var newUrl = oldUrl.replace(/arxiv/g, 'ar5iv');
  window.location.href = newUrl;
})();
```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3085757/a1d37df3-14d6-7b38-48f4-e793474c1b63.png)


以下のような画面で、ブックマークバーをクリックするとHTML形式で表示がされます。
ブックマークバー内のフォルダに配置した場合も正常に動作しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3085757/5bcf4d1b-d32c-ff26-c056-06f9b5bf9600.png)

:::note warn
注意点
`arxiv`という単語が含まれていない限り何も起きません。
`arxiv`という単語が含まれているURLの場合、全てが置換されてしまいます。予期せぬリンクに飛んでしまう可能性があるので誤って使わないように注意してください。
:::

# 参考
以下のサイトでこの形式変換について詳しく解説がされています

https://note.com/sangmin/n/n3cb4d25e002e

拡張機能もあるようです

https://zenn.dev/polymonyrks/articles/55561073bfdb45
PythonでRPAツール作ってみた

初めましてエンジニアになりたてのkです。

PCで仕事をするとマルチ画面があるのにかなりぐちゃぐちゃになります。
当たり前のように今はPC周りのフリーソフトが溢れてますが会社事情でインストールが禁止されています、、、

そこで業務効率化ツールを作ってしまおうと思いました。
Windowsで CapsLock と Control の位置を入れ替えたい

　僕は長年 MacBook を使ってきたこともあり Windows のキーボード配置になかなか慣れませんでした。とくに Control キーと CapsLock キーの配置には甚だ疑問と違和感を感じます。そこで僕は Windows で CapsLock と Control キーを入れ替える方法を模索しました。

# PowerToys
　これが最も簡単な解決方法です。ネットでも「Windows caps control 入れ替え」などで検索するとほぼ上位にこのアプリをインストールしろとの記事が多く出ます。
　僕も初めはこのソフトを使って Control と CapsLock を入れ替えて使用していましたが、

 - **よく設定が反映されない**
 - **キーボードのレスポンスが低下する**

などの不具合がよく発生しました。
　…などとデメリットを並べましたが Windows 公式がサポートしているアプリなだけあって親和性はとても高く、その他さまざまな設定をPCに加えることができるのでお勧めできます。以下のリンクから MicroDoft Store を介してインストールできます。

 - https://apps.microsoft.com/detail/XP89DCGQ3K6VLD?hl=en-us&gl=JP

 # レジストリを編集する
 　この方法は最も確実に CapsLock と Control を入れ替えることができる一方、**リスクが高い作業** でもあります。やり方は以下の通りです。

::: note warn
**この作業で誤った行為をすると PC またはキーボードが文鎮化する可能性があります。この作業は自己責任でお願いします！！！**
:::

 ## 0. レジストリエディタを開く
 　**「Windowsキー」+「R」** を押して「ファイル名を指定して実行」を開きます。入力欄に以下の.exeファイルを記述します。
```
regedit.exe
```

## 1. Keyboard Layout までのパスをたどる
　レジストリエディタが開いたら以下の順番にパスをたどってください。
 ```
 コンピューター>
     HKEY_LOCAL_MACHINE>
         SYSTEM>
             CurrentControlSet>
                 Control>
                     Keyboard Layout
 ```

<a id="2"></a>
## 2. バックアップを取る
　万が一のことを考えて ```Keyboard Layout``` のバックアップを取ります。レジストリエディタウィンドウ上部の **「ファイル(F)」＞「エクスポート」** をクリックします。
　保存先を聞かれるので、任意の場所で保存してください。
 
## 3. Scancode Map を作成
　```Keyboard Layout``` 内に ```Scancode Map``` という名前のバイナリデータを作成します。レジストリエディタの「編集」＞「新規」＞「バイナリ値」を選択してバイナリデータを新規作成します。
 　レジストリ内に「新しい値」というバイナリデータが生成されます。このデータをクリックして選択し、「編集」＞「名前変更」をクリックします。するとバイナリデータ名を変更できるようになるので、名前を ```Scancode Map``` に書き換えてください。
　次に ```Scancode Map``` 内のバイナリ値を編集します。このデータを選択して「編集」＞「バイナリデータの修正」をクリックします。するとバイナリエディタが開くので、値を
```
00,00,00,00,00,00,00,00,02,00,00,00,1d,00,3a,00,00,00,00,00
```
になるように書き込んでください。

## 4. バックアップを取る
　編集後のレジストリデータも **[手順2](#2)** と同じ方法でバックアップを取ることをお勧めします。

 ## 5. 再起動
 　作業が完了したらPCを再起動します。すると Control キーと CapsLock キーの効果が入れ替わります。

　ほかにもいろいろな手順でキーボード配置を入れ替えることができます。皆さんがやりやすい方法でPC をカスタムしてみましょう。
GAS上でのスクレイピング（ソーラーパネル稼働状況出力）

# 前回Pythonで動いたものをGASへ移行する
前回、ラズパイ上でのPython3で、ソーラーパネル稼働状況を出力させることができました。


# ログインできない。
最初は、CSRFトークンが正常に取得できていないと思っていました。
セッションIDを維持したりしましたが、ログインできず。


    var csrfToken;  // グローバル変数としてCSRFトークンを保持
    
    function loginAndFetchPage() {
      var loginPageUrl = "https://ctrl.kp-net.com/settingcontrol/processLogin";
      var targetPageUrl = "https://ctrl.kp-net.com/settingcontrol/remotevisualization/simplevisualization/enduser";
      var username = "xxxxxxxxxxxx";
      var password = "yyyyyyyyyyyy";
    
      // 1. ログインページからCSRFトークンを取得
      csrfToken = getCsrfToken(loginPageUrl);
    
      // 2. ログイン情報とCSRFトークンを使用してログインリクエストを送信
      var loggedIn = login(loginPageUrl, username, password);
    
      if (loggedIn) {
        // 3. ログインが成功した場合、目的のページのHTMLを取得
        var targetPageHtml = getPageHtml(targetPageUrl);
        Logger.log(targetPageHtml);
      } else {
        Logger.log("Login failed.");
      }
    }
    
    function getCsrfToken(url) {
      var response = UrlFetchApp.fetch(url);
      var html = response.getContentText();
    
      // 正規表現を使用してmetaタグからCSRFトークンを取得
      var match = /<meta[^>]+name=["']_csrf["'][^>]+content=["']([^"']+)["'][^>]*>/i.exec(html);
    
      return match ? match[1] : null;
    }
    
    function login(url, username, password) {
      var payload = {
        _csrf: csrfToken,
        loginid: username,
        loginpassword: password
        // 他のログインフォームのフィールドも必要に応じて追加
      };
    
      var options = {
        method: 'post',
        contentType: 'application/x-www-form-urlencoded',
        payload: payload,
        followRedirects: false
      };
    
      var response = UrlFetchApp.fetch(url, options);
    
      // ログイン成功時に新しいCSRFトークンを取得
      if (response.getResponseCode() === 302) {
        csrfToken = getCsrfToken(response.getHeaders()['Location']);
        return true;
      }
    
      return false;
    }
    
    function getPageHtml(url) {
      // 各リクエストで同一のCSRFトークンを使用
      var payload = {
        _csrf: csrfToken
        // 他のリクエストパラメータも必要に応じて追加
      };
    
      var options = {
        method: 'get',
        payload: payload
      };
    
      var response = UrlFetchApp.fetch(url, options);
      return response.getContentText();
    }


# UrlFetchAppは実行毎に違うIPアドレスを使う
UrlFetchAppの実行毎に、CSRFトークンが変化しているようでした。
このため、上記の、セッションID維持を試みたりしていました。
ですが、どうやら、UrlFetchAppは実行毎に違うIPアドレスを使うようです。
これなら、各種情報を維持しようがログインできなかったことに合点がいきます。

https://blog.katsubemakito.net/gas/gas_ipaddress

# IPアドレス固定方法の模索
レンタルサーバーを借りてそちらで実行されている方もおいででした。

https://groups.google.com/g/google-app-engine-japan/c/Ew8Sf_YLMzE

断念されている方もおいででした。

https://qiita.com/optimisuke/items/8b355c485b2c56a24bcf

いずれかのサーバーを経由させる必要があるようです。
【超ざっくり】TerraformでAzureリソースを作成する手順をまとめてみた

# はじめに
TerraformでAzure上のリソースをする手順について、初学者なりに**超ざっくり**まとめてみました。
なお、今回ご紹介する方法以外でもAzureリソースを構築することは可能です。
別の方法は公式ドキュメントなどを参照してください。

# 目次
 - [1. Azureの事前準備](#Azureの事前準備)
 - [2. Terraformの事前準備](#Terraformの事前準備)
 - [3. TerraformでAzureリソースを作成](#TerraformでAzureリソースを作成)

# Azureの事前準備
Terraformで各種リソース作成ができるようにサービスプリンシパルを作成します。ざっくりとした手順は以下の通りです。
* サービスプリンシパルの作成
* 共同作成者ロールの付与
* 各資格情報の確認

# Terraformの事前準備
TerraformのインストールおよびTerraformコードを記述したファイルを作成します。
今回はTerraformコードを3つのファイルに分けて作成する想定です。
* Terraformのインストール
* Terraformコードファイル作成
    * 全体の処理を記述したファイル（XXX.tf）
    * 変数の設定値が記述されたファイル（XXX.tfvars）
    * 変数の型を記述したファイル（XXX_variables.tf）

# TerraformでAzureリソースを作成
4段階に分けてTerraformコマンドを実行し、Azureリソースを構築します。
* Terraformの初期化（terraform init）
* 構文エラーなど基本的な構成チェック（terraform validate）
* リソース作成前の事前検証（terraform plan）
* リソース作成（terraform apply）

# おわりに
ざっくりとした手順は以上です！
詳細な手順は今後、別の記事として作成しようと思います。

# 関連記事（随時追加していきます）
https://qiita.com/Katsuya_T/items/7f0d75f1a10272b62202

https://qiita.com/Katsuya_T/items/be62705a05fb3c39ae9f
AWSを極めたい人のための1秒で読める最初の最初の最初の最初の最初の１記事


# 謝罪

嘘をつき、
申し訳ありませんでした。

1秒では読めませんでした。4.23秒で読めます。


# AWS とは

Amazon社が、だいぶ前から開発を行い、そこそこ前から世の中に提供を開始した、サービスで、

200を超えるサービスがあるので、全部は言えない。

調べてください。

代表的なものは、

・Webサーバー：EC2
・APサーバー：EC2（Webサーバと同じものを使います：同じサービスで、両方できちゃうなんてしゅごいっっっっ！）
・データベースサーバー：RDS
・ストレージ：S3
・仮想的なネットワークを構築できんぜ。と言う要望に応えてくれるサービスをクラウドに自分の手で構築したい人のためのサービス：VPC
・サーバーレス（名前の由来はよくわからないが、トリガーを設定しておくと、自動でイベントを実行してくれるサービス）：Lambda
・DNSサービス：route53（名前がかっこいい：私が愛知に住んでた時、彼女とよく行っていたカフェの名前でもある）
・コンテナ（Dockerを構築したい！な場合）：ECR
・ブロックチェーンのネットワークを作成できる（俺は本当はこれがやりたい）：AMB
・ブラウザで使える統合開発環境：cloud9
・AIの作成とAIに学習を行う：SageMaker
・リアルタイムに複数のコンピュータを接続可能なゲーム用のホスティングサービス：GameLift
・量子コンピュータの実験できんぜ？え？やばくね？さすがAmazonエンジニア！：Braket
・モバイルアプリを構築できる：あんぷりふぁい


# クラウドとは

コンピュータ上に設置できる、資源（リソースとも言う）を、自分のサーバじゃなくて、クラウドサービスとして提供してくれているサーバーに配置することで、さまざまなメリットを受け取ることができるよ！

なサービス
ランダムであることを証明することは難しいという話


ある数列$a_n$がある。
これがランダムな数列でないことを証明するには規則性があるかどうかを示せばよい。

ではランダムであることを証明するにはどうすればよいか？
規則性がないことを示せばよい。

規則性がないことを示すためには、ありとあらゆる規則性がある数列に一致しないことを示せばよい。

しかし、これは非常に難しい。
「ない」ことを証明するということは、規則性があるすべての数列を知らなければ行えないからだ。

そして、規則性がある数列（※）というのはおそらく無限に等しいくらいあると思われる。

そんな状態で、ひとつひとつそれらの数列と比較して一致していないかを調べるのは事実上不可能であり、ある程度妥協して、多分ランダムかな～。程度の証明くらいしかできないだろう。

というわけで、タイトルの通り、ランダムであることを証明することは難しいという話でした。

---

※例えば、自然数の平方根であり、かつ正の無理数である数を小さい順に並べてできる数列の小数第1000000000位の数を項に持つ数列$a_n$があるとする。
$a_n$は規則性があるが、それを（何も知らない状態から）示すのは相当困難だろう。
クリーンアーキテクチャ個人的まとめ（Ⅳ部）

## クリーンアーキテクチャⅣ部
### 個人的概要
- コンポーネントとはデプロイの単位。システムの一部としてデプロイできる、最小限のまとまり
- よくできたコンポーネントは常に個別にデプロイできる状態を保っているため、個別に開発を進められる
- モジュール同士をつなぎ合わせて実現される一つの処理（コンポーネント）のまとめ方の観点について
    - 非循環依存関係の原則
    - 安定依存の原則
    - 安定度・抽象度等価の原則

### ポイント
#### コンポーネントの結合の３つの原則

- 非循環依存関係の原則
    コンポーネントの依存グラフに循環依存があってはならない
- 安定依存の原則
    安定度の高い方向に依存すること
    （多くのモノへ依存される方に依存すること。長い物には巻かれろ）
- 安定度・抽象度等価の原則
    コンポーネントの抽象度は、その安定度と同程度でなければならない
Azure APIマネジメント

## Azure API マネジメントとは
Azure APIマネジメントとは文字通りAPIを管理するサービスです。

コンポーネントは大きく分けて3つあり、
- API GateWay
- 管理プレーン
- 開発者ポータル

です。

## API GateWayとは
フロントエンドとバックエンドの関門です。全やり取りがここの関門を通ります。そうすることで非常に便利になります。フロントエンド側はすべて、ここの関門に投げれば良いのです。すると、ここの関門にいる人がバックエンドの適切な場所に連れて行ってくれます。（適切なルーティング）
また、認証などを一旦Gatewayで行うのでセキュリティ面でも非常に便利なのです。国際便の入国窓口のようなイメージで良いと思います。

## 管理プレーンとは
APIを編集したり、追加・作成したりします。

##  開発者ポータル
APIを編集することはできないですが、使うことができます。そうすることで適切にサービスを統合できます。

##  APIポリシー
API処理の振る舞いを定義します。
- `inbound`
- `backend`
- `outbound`
- `on-error`
を定義します。`inbound`はクライアントからAPIGatewayへの処理、`backend`はAPIGatewayからサーバーへの処理、`outbound`はサーバー側からの返信についての処理、`on-error`はエラーの場合の処理です。chooseとかwatachとかretryとかいろいろ書いて定義します。
【Oracle Analytics】ダッシュボードページ名を使用した値の切り替え方法

## 概要
ダッシュボードページ名を事前定義プレゼンテーション変数より取得し、分析の値の切替を行う方法について記載します。
本設定を行うことにより、異なるダッシュボードページに配置した共通の分析の対象カラムの値を選択ページによって切り替えることが可能となります。

## 前提
<dl>
  <dl>・予め共通の分析を表示する2つのダッシュボードページを用意しています。</dl>
  <dl>・Autonomous Data Warehouse（ADW）サンプルSales History (SH)スキーマを参照しています。</dl>
  </dl> 

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3582570/a3a66382-49fe-3438-f55c-7a62ec06e255.png)


## 参考
OBIEE12cのマニュアルになりますが、下記マニュアルを参考に記載しています。
https://docs.oracle.com/middleware/12211help/biee/ja/bi.12211/e73376/GUID-ECB6E0C3-2554-4052-AB43-EE977985C3CD.htm#BIEUG2798


## 設定内容
#### 1. プレゼンテーション変数の作成
ダッシュボードページ名を取得するため、ダッシュボードプロンプトで事前定義プレゼンテーション変数を設定します。
<dl>
<dt>・変数プロンプトの設定</dt>
  <dd>プレゼンテーション変数（P1）を設定し、変数式にダッシュボードページ名を取得する事前定義プレゼンテーション変数を設定します。</dd> 
  <dd>※下記はダッシュボードページ名取得する事前定義プレゼンテーション変数</dd>
  <dd> <strong>@{dashboard.currentPage}</strong></dd>
</dl>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3582570/e17eb41b-3f90-d34a-c58f-c8f5649423eb.png)

:::note info
分析の列式に事前定義プレゼンテーション変数を直接設定した場合、2回目以降のプロンプト検索後のエクスポートで変数の値が取得できないため、ダッシュボードプロンプトを介して事前定義プレゼンテーション変数の値を取得する方法を行っています。
:::

#### 2. 隠しダッシュボードプロンプトの設定
分析の列式で変数の値を受け取るため隠しダッシュボードプロンプトとしてダッシュボードのセクションで非表示とします。

<dl>
<dt>・セクション条件用の分析の準備</dt>
  <dd> 固定値「1」を設定した分析を作成します。</dd> 
</dl>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3582570/4041300c-a81f-8835-3c9f-6182642360a6.png)

<dl>
<dt>・隠しダッシュボードプロンプトの設定</dt>
  <dd> 「売上額」のダッシュボードページに1で作成した変数プロンプトをセクションに配置し、セクションの条件に下記条件を設定し非表示とします。</dd> 
  <dd>「販売個数」のダッシュボードページに対しても同様に設定します。</dd> 
</dl>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3582570/92a4f202-d341-bafb-8098-75e435366499.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3582570/96f5fedc-454d-8c0b-b355-8da9c660011a.png)

#### 3. 列式の編集設定
値を切り替えたい分析の対象カラムの列式を編集します。
列名に選択ページ名を表示するため、事前定義プレゼンテーション変数を設定します。

<dl>
<dt>・列式の編集</dt>
    <dd>CASE WHEN '@{dashboard.currentPage}' = '売上額 ' THEN  "SALES"."AMOUNT_SOLD" ELSE  "SALES"."QUANTITY_SOLD" END</dd> 
</dl>
<dl>
<dt>・列名の設定</dt>
    <dd>@{dashboard.currentPage}</dd> 
</dl>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3582570/3acb3776-abef-2f80-a607-78567275a80d.png)


#### 4. 動作確認
ダッシュボードページの切替を行い、対象カラムの値が切り替わることを確認します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3582570/1acee7ae-6ef8-99eb-bd4c-25a77f992258.png)

## ご案内
株式会社ジールは、Microsoft Azure やAWS（Amazon Web Services）、Google Cloud Platform（GCP）、Oracle Cloud Infrastructure（OCI）など、多彩なクラウドプラットフォーム構築・運用の知見を有しています。そのため、複数のクラウドサービスを組み合わせるマルチクラウド環境においても、ベンダーロックインを回避し、お客様のご要望に応じた最適なクラウドプラットフォームの構築・運用への対応が可能です。
https://www.zdh.co.jp/products-services/cloud-data/
研修内容を振り返る 2020.04~2020.05

## まえがき

2020/03/09からバックエンドエンジニアとして働かせていただいています。前回の記事に引き続き4月から5月にかけての自分が研修内容と実際に実施した内容・振り返りなどを一か月毎に区切って記事にしたいと思います。前回の記事はこちら↓

https://qiita.com/miriwo/items/686e819ffea927c6c745

## ご注意

- 本内容は研修を受けた自分が感じた主観であり、弊社の意向と異なる可能性があります。
- ご入社いただいたみなさんに必ず本研修を受けていただくということではありません。
- 研修内容に関してはメモを取っていましたが実際の内容と異なる可能性があります。
- 情報セキュリティの観点から一部実名を伏せて記載することがあります。

## 2020.04の自分のレベル

前提情報として2020.04時点での自分の知識レベルを簡単に書いてみます。

- Laravelの環境構築を自力ですることができる。
- LaravelのMVC構造を経験している。
- SQL文を実行したことがある。

## 研修のサポート

2020.04の記事と同じですが、毎日上司の方とzoomを用いて10分~30分程度のミーティングを行いました。また、弊社のSlackにある技術的な内容を質問できるチャンネルで詰まった部分の相談に乗ってもらったりしました。

## 2020.05までの主な研修内容

- DBとLaravelの関係性を理解しよう。
- 前回から作成している「計算ドリルアプリ」にユーザ認証機能を追加してみよう。
- 既存Webサービスのテーブル設計とSQLを考えてみよう。

### 研修内容をちょっとだけ深堀り

#### DBとLaravelの関係性を理解しよう。

マイグレーションの経験やDBに格納されているデータの取得、表示などの基礎部分を経験しました。Laravelの公式ドキュメントを確認しながら実際にマイグレーションを実行しとにかく慣れることを目標としました。

#### 前回から作成している「計算ドリルアプリ」にユーザ認証機能を追加してみよう。

先月から作成している研修用Laravelアプリにユーザ認証機能を付与します。Authを用いた認証機能を付与し、Authの振る舞いを経験します。

#### 既存Webサービスのテーブル設計とSQLを考えてみよう。

現在すでに世の中で利用されているWebサービスの一つの機能を上司の方と選び、当該の機能全体や個々のページを表示するにはどの様なテーブルが必要か、どの様なSQLを実行すれば必要なデータを取得することができるかを考えます。

## 得た知識

- LaravelアプリとMySQLのDBとの紐付け方
- マイグレート方法
- テーブルのレコード削除を物理削除から論理削除にする方法
- 認証機能の付与方法
- セッションの利用方法
- 実運用されているDBの設計時の流れ

## 苦労した点

- マイグレーションファイルの記載方法

### 苦労した点をちょっとだけ深堀り

#### マイグレーションファイルの記載方法

技術書やLaravelの公式ドキュメント通りに実施するなら問題なくマイグレートできるが、少し応用するとエラーが連発してしまいました。特にdown側の記載を忘れたり、記載されていても完全に元に戻せる様に記載されていなかったりでロールバックをしてもエラー、マイグレートをしてもエラーとなってしまいました。検証用にLaravelアプリを作成しスクラップアンドビルドを繰り返す毎にミスは減っていきました。

## さいごに

入社から一ヶ月経過し、超基礎部分は着々と積み重なってきている感じはしますが、逆に習得することが多すぎて焦っていたことも思い出しました。次の記事は2020.06までの研修内容をまとめたいと思います。
GraphQLとREST API 

## GraphQLとは
GraphQLとはFacebook社が開発したクエリ言語です。サーバーとクライアントでの情報のやり取りをするために使われる言語です。まず、クライアントサイドでは、なんのデータがどのような構造でほしいのかを伝える処理を記述します。「〇〇のデータが〇〇な構造で〇〇ぐらいほしい」のような感じです。すると、サーバー側はその要望に従って、きっちりとデータを整えて整理した状態で渡してくれます。なので、非常に便利です。

## REST APIとは
REST API（Representational State Transfer API）は、ウェブサービスの設計スタイルを指します。言語ではなく設計スタイルです。APIは、バックエンド側で一方的に作成され、クライアント側がAPIを呼び出すことでHTTP通信でデータを提供します。「データをください」というと、「全部渡すからいらないのは捨てたり、使いやすく整えたりして使ってください」という感じで渡されます。

## GraphQLと従来のAPIの違い
- クエリによる柔軟性: GraphQLでは、クライアントが必要とする具体的なデータの構造をクエリによって指定することができます。これにより、クライアントは必要なデータのみを取得することができ、データの過剰なフェッチ（オーバーフェッチ）や不足（アンダーフェッチ）を防ぐことが可能になります。この点は文章で正確に指摘されています。

- 開発の独立性: GraphQLを使用すると、フロントエンドとバックエンドの開発者がより独立して作業を進めることができます。これは、フロントエンドの開発者がバックエンドから必要なデータを柔軟に取得できるため、バックエンドの変更が直接フロントエンドのクエリ設計に影響を与えることが少なくなるからです。この点も文章で適切に説明されています。

## 従来のAPI通信によるもの
想像してみてください。あなたはレストランに行き、メニューから料理を注文します。このレストランでは、コース料理しか提供していません。例えば、あなたが魚料理を望んでいても、そのコースには前菜、スープ、デザートが自動的に含まれています。もしあなたがスープやデザートに興味がなくても、それらは提供され、結局は料理の一部を残すことになります。また、もしメニューに変更があった場合、レストランは新しいメニューを作成し、客には新しいコース全体を注文するか、または別のオプションを選ぶように促す必要があります。
ある日、レストランがメニューを更新し、新しい料理を追加したいと考えました。この変更を実現するために、レストランは新しいコースメニューを作成し、古いメニューは廃止してしまうか、そのまま維持して二つのメニューとして残します。この場合、客は新しいメニューに従って全く新しいコースを注文するか、または古いメニューから選ぶ必要があります。これは、従来のAPIでデータ構造が変更された場合に、新しいエンドポイントを作成するか、既存のエンドポイントをアップデートする必要がある状況に似ています。このプロセスはしばしば手間がかかり、クライアントとサーバーの間での調整が必要になります。

## GraphQLによるもの
一方で、カスタムオーダーが可能なカフェでは、メニューに新しい飲み物やスナックを追加することが頻繁にあります。しかし、この変更はお客様の注文方法に影響を与えません。新しいアイテムがメニューに追加されたとしても、あなたはいつも通りに自分の好みに合わせて注文をカスタマイズできます。これは、GraphQLでデータ構造が変化した場合でも、クライアントのクエリを少し調整するだけで済むことに似ています。サーバー側の変更があっても、クライアントは柔軟に対応でき、新しいデータを簡単に取り入れることができます。
Temperature MCP9701 の関数化(浮動小数点)(Arduino UNO)(リッチプログラミング)


x MCP9701-E/TO 販売コード 103199

Temperature MCP9701 の関数化(浮動小数点)(Arduino UNO)(リッチプログラミング)


Arduino MCP9701 ArduinoUno 電子工作 温度センサー


x 過去ログを見ょ!!

目的
温度センサーMCP9701のテスト


いろいろ

GITHUBに書いて(AI)に餌を与えてきた!
たぶん、しばらくすると出てくる(何の事)

AIにたのべば、SE,プログラマーは、不要らしい。
評価(スコアリング)もやってくれるらしい。
AIサマ~~~~~~~~~~~ ?

それ、作ったのは、俺。ごっこがやりたい。(?映画サマーウォーズ)

https://github.com/caa45040/Temperature_MCP9701




結果

![o_cop968.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/c4261d9f-33e5-177f-64b0-3b0273d252c2.jpeg)

![o_cop969.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/288f9ee1-0282-d47e-d1ac-7460dda13225.jpeg)


プログラム



```c++




//SER_Temperature_MCP9701_UNO_1


//インクルド
#include <Arduino.h>
#include "Temperature_MCP9701.h"


//初期化処理
void setup()
{

  //シリアルの初期化
  Serial.begin(9600);

} //setup


//メインループ
void loop()
{

  //センサーの値を読み込む
  int Sensor = analogRead(A0); // センサーの読み取り値

  //温度の表示
  float Voltage = Sensor * ( 5.0 / 1024.0 );
  float Temperature = Temperature_MCP9701(Voltage);
  Serial.println(Temperature);

  //1秒の待ち
  delay(1000);

} //loop





```

Temperature_MCP9701.h


```c++



// Temperature_MCP9701.h 
//
// ex 3.3V analogReadResolution(12);
//         float Sensor = analogRead(A2);
//         float Voltage = Sensor * ( 3.3 / 4096.0 );
//         float Temperature = Temperature_MCP9701(Voltage);
//
float Temperature_MCP9701(float Voltage){

  return((Voltage - 0.4) * (1.0 / 0.0195));

}//Temperature_MCP9701




```
Cookieって美味しそう。セッションって不味そう


# ステートレスって何か

`
状態を保持しないぜ？？どうだ！喰らったか！
`

という性格の悪い人。

な性質のこと

http通信において、説明すると、

過去の通信情報をブラウザは保持しないからね〜

といった感じ

詳しくいうと、

```
ブラウザの通信は、

AというクライアントPC　（ブラウザ）
BというサーバPC　　　　（サーバープログラム）

がhttp通信を実現する際に、

A → B （httpリクエスト）　・・・①
A ← B （httpレスポンス）　・・・②

A → B （httpリクエスト）　・・・③
A ← B （httpレスポンス）　・・・④

A → B （httpリクエスト）　・・・⑤
A ← B （httpレスポンス）　・・・⑥

と言うように、通信が行われていく

この時、普通の人間の感覚では、

③のリクエストの時に、Aさんは、②で受け取った情報や①で送信した情報を覚えている

しかし、ステートレスなブラウザさん（A）は、情報を覚えていない

困ったちゃんなのだ。

まるで、ASD込みADHDの人みたい（・・・俺も）

```


# Cookie とセッション

しかしだ、なんと、ステートレス解除！的な機能も用意してくれている

ありがとう！世の中！

それが、

・キャッシュ
・Cookie
・セッション

の３つ。

ざっくり言うよ〜

```
キャッシュ：一度見たWebサイトを一定期間、ブラウザ側に保存しておくこと
Cookie：ユーザーのIDとパスワードの組をブラウザで、一定期間保存しておくこと
セッション：ブラウザではセッションID、サーバではその他セッション情報全てを保存しておいて、ログイン以降の一連の操作をページ遷移ごとにログインさせなくてもいいようにすること
```



# Cookie の確認

実は、自分のブラウザで保存しているCookieを知る術が、ブラウザを提供してくれてる会社が、その機能を用意するために、ブラウザ内機能をプログラムしてくれている。

下記のサイトを見ながら、やってみて


https://mynavi-ms.jp/info/check_browser/


絶対にできるはず。君も。俺も。みんなも、誰でも。
Pythonにおける多次元辞書のキーと値の同時生成方法およびキーの存在確認方法

# きっかけ
Pythonの多次元辞書に関する情報があまり見つからず，何か一発でキーと値を生成できたり，キーの存在確認できたりできないものかと考えて適当にコード書いたものです。
再帰を使っているのでメモリにあまり優しくない方法ですけど、参考になれば幸いです。
何かバグ等ありましたらお教えいただけますと大変勉強になります。

# 多次元辞書のキーと値の同時生成方法

### コードと実行例

```py:code
def createMulDimDict(dic, keys, val):
    dic.setdefault(keys[0], {})
    if len(keys) == 1:
        dic[keys[0]] = val
    else:
        createMulDimDict(dic[keys[0]], keys[1:], val)
        
dic = {}
createMulDimDict(dic, ['food', 'meat'] , 'beaf')
print(dic)
# {'food': {'meat': 'beaf'}}

createMulDimDict(dic, ['food', 'fruit'] , ['apple', 'banana'])
print(dic)
# {'food': {'meat': 'beaf', 'fruit': ['apple', 'banana']}}

createMulDimDict(dic, ['machine', 'vehicle'], {'car' : ['bus', 'truck'], 'others' : ['ship', 'plane', 'helicopter']})
print(dic)
# {'food': {'meat': 'beaf', 'fruit': ['apple', 'banana']}, 'machine': {'vehicle': {'car': ['bus', 'truck'], 'others': ['ship', 'plane', 'helicopter']}}}

# JSON形式に変換
import json
json_name = 'example.json'
with open(json_name, 'w') as fp:
    json.dump(dic, fp, indent=4)
```

```json:example.json
{
    "food": {
        "meat": "beaf",
        "fruit": [
            "apple",
            "banana"
        ]
    },
    "machine": {
        'vehicle': {
            'car': ['bus', 'truck'],
            'others': ['ship', 'plane', 'helicopter']
        }
    }
}

```
実装のポイントは多次元キーを文字列のリストとして引数にするところ。
これのおかげで、再帰でキーをスライスして渡しても文字列として渡せる感じです。
値には、辞書の値として受け入れられるものならば，文字列でもリストでも辞書でも入れられます。
多次元辞書が「辞書→リスト→辞書」のように途中にリストを挟む場合などもこれをベースに少しいじれば実装できます。


# 多次元辞書のキーの存在確認方法

### コードと実行例
```python
def existKeys(dic, keys)
    if len(keys) == 1:
        return keys[0] in dic
    elif keys[0] in dic:
        return existKey(dic[keys[0], keys[1:)
    else:
        return False

with open('example.json', 'r') as fp:
    example = json.load(fp)

print(existKeys(example, ['machine', 'vehicle', 'others']))
# True

print(existKeys(example, ['food', 'vehicle']))
# False
```
こちらもポイントは上と同じく引数の文字列リストです。
['A', 'B', 'C']なんていうキーの存在確認をする際に'B'の時点でキーがなかった場合を想定して，elif節の条件を書いてます。
苦手な記号をタッチタイピングできるようになって幸せになろう

# 背景
最近、同僚に騙されて英語配列の高級キーボードを購入しました。打鍵は非常に気に入りましたが、記号の場所やシフトキーを利用した入力になかなかなれません。元のキーボードに戻すことも考えたのですが、高級キーボードを購入したので後ろ髪を強く引っ張られています。この機会にキーの配置を覚え直し、従来より快適にキーボードを操作できるようになろうと考えました。
# 作戦：ゲームで幸せになる
自分が苦手な記号入力のタイピングゲームをrubyで作りました。
このゲームで遊ぶと重点的に苦手な記号キーを練習することができます。
また、記号を入力するときは右手の小指が大活躍するので右手の小指専用のメニューも搭載した最先端仕様にしました。(笑)

```ruby:typing_game.rb
# 処理開始時刻を記録
start_time = Time.now

# 記号練習用
source_string = '!@#$%^&*()-_=+\|~`{[]};:"<>?/1234567890' + "'"
# 右手小指練習用(英語配列)
# source_string = ')-_=+pP{[]};:"?/' + "'"

# １０問出題
for num in 1..10 do
  # 文字列からランダムに5文字を選ぶ
  random_characters = source_string.chars.sample(5).join

  # 入力問題を表示
  puts random_characters

  user_input = ''

  # 正解するまで入力させる
  while random_characters != user_input do
    user_input = gets.chomp
  end
  # コンソールの入力内容を破棄
  print "\e[H\e[2J"
end

# 処理終了時刻を記録
end_time = Time.now

# 処理にかかった時間（秒）を計算
elapsed_time = end_time - start_time

# 処理時間を出力
puts "処理にかかった時間: #{elapsed_time}秒"
```
```zsh:実行コマンド
ruby typing_game.rb
```
# トレーニングの結果
## 初日
- 練習時間：30分
- 平均：180秒
- 身についた能力：記号のタッチタイピング

初日にかなりゆっくりですが、タッチタイピングを習得できました。新しいことができるようになるのは幾つになっても嬉しいことですね。

## 2日目
- 練習時間：30分
- 平均：110秒
- 身についた能力：とくになし

初日に比べてかなり速度が速くなりました。個人的には以下が重要な要因だと思います。
- 自分で**速くタイピングする**と強く意識すること 
- 初日に頑張って遅いことを実感し、**悔しく思った状態で一晩寝た**こと

冗談みたいなことですが、これは私のスポーツなどをやっていて、よく実感する面白い現象なのでぜひ試してみてほしいです。

## 3日目
- 練習時間：30分
- 平均：80秒
- 身についた能力：とくになし

100秒をコンスタントに切ることができるようになりました。キー配列もそれなりに指が覚えてきたような気がします。

# 最後に
まだまだ速度に伸び代がありますが、この３日間で不慣れなキーボードでのタイピングの速度がかなり向上したように感じます。
同じように記号の入力が苦手な人がいたら私のタイピングゲームをプレイしていただけると幸いです。
さようなら、Hotwire Stimulus ✕ React

## はじめに

私のとあるRailsプロジェクトは Hotwire Stimulus ✕ React 構成を採用していた。グラフ描画の機能を実装するために流行りの [tremor](https://www.tremor.so/) を使ってみたかったからである。

## 実装

実装は以下の通り。

```app/javascript/components/RevisionFluctuation.tsx
import React from "react";
import { createRoot } from "react-dom/client";
import { Card, Title, LineChart } from "@tremor/react";

const RevisionFluctuation = ({ data }) => (
  <>
    <Card>
      <Title>Revision fluctuation</Title>
      <LineChart
        data={data}
        dataKey="date"
        categories={["Revision count"]}
        colors={["orange"]}
        marginTop="mt-6"
        yAxisWidth="w-10"
      />
    </Card>
  </>
);

RevisionFluctuation.defaultProps = {
  data: [],
  container: HTMLDivElement,
};

const renderRevisionFluctuation = (
  data: { date: string; "Revision count": number }[],
  container: HTMLDivElement,
) =>
  container &&
  createRoot(container).render(<RevisionFluctuation data={data} />);

export default renderRevisionFluctuation;
```

```app/javascript/controllers/user_info_controller.ts
import { Controller } from "@hotwired/stimulus";
import renderRevisionFluctuation from "../components/RevisionFluctuation";

// Connects to data-controller="user-info"
export default class extends Controller {
  static targets = ["revise-dates"];
  static values = {
    revise_dates: Object,
  };

  declare readonly reviseDatesValue: { [key: string]: number };

  connect() {
    const revisionsPerDateCount = Object.entries<number>(
      this.reviseDatesValue,
    ).map(([date, count]) => {
      return { date: date, "Revision count": count };
    });

    document.addEventListener("turbo:load", () =>
      renderRevisionFluctuation(
        revisionsPerDateCount,
        this["revise-datesTarget"],
      ),
    );
  }
}
```

## なにが悪いか

結局のところ、`data-user-info-value` といった形でフロントエンドのERBから値を直に渡さなくてはならないことが悪いのである。値を渡すために Stimulus コントローラを作成して、JSX を書き、Rails のコントローラとビューを書き換える必要がある。値がフロントエンドで丸見えになることもよくない。

そんなわけで Hotwire Stimulus ✕ React 構成を取るくらいなら、フロントエンドを脱 Rails 化した方がマシだ！という結論に至るのである。
42 Paris piscine 攻略法

## 42とは
>フランス発のエンジニア養成機関です。
現在は、世界31カ国にて展開されており、2020年6月に東京校として 42 Tokyo を設立しました。
多くの企業の支援、寄付で支えられており、授業料は完全無料。
学生は、18歳以上であれば経歴を問わず入学することができ、
その後のキャリアは起業をしたり、就職するなど、自由です。
また、基礎カリキュラムを終えたら、他の42キャンパスに留学することも可能です。
革新的で、日々最新にアップデートされるカリキュラム。
世界中の学生たちが、今この瞬間も42でスキルを磨いています。

参考：https://42tokyo.jp/

## ４２に入った経緯

私自身個人的な理由で２４歳の時フランスに行くことが決まりました。

その時働いていた職場からは海外からのリモートは厳しいということで退職し、

新たにリモートでできる仕事を探し現在働いている会社を見つけました。

フランスに来てからはずっとその会社でウェブ制作の仕事をしていましたが、時差の関係で１日４時間しか働いていないため、

かなり時間を持て余してましたw

その時４２Parisの存在を知ったのです！

新しいことを始めてみようと、42Parisに申し込みました。

## Piscineの話
さて、42にはPiscineという1ヶ月間続く入学試験があります。

主にC言語を使ったプロジェクトを進めていくのですが、それがとてもしんどい・・・

このpiscine、早く進めば合格するわけではなく、

・プログラミングスキル
・コミュニケーションスキル
・規律正しさ

この主に３つのスキルで評価されます。

1. プログラミングスキルはプロジェクトが進めば進むほど評価されます。
1. コミュニケーションスキルは、どのようにチェックされているかまでは不明ですが、できるだけたくさんの人と話協力しあってプロジェクトを行うことが必要です。あとは、期間中にVoxotronという投票があり、どの人を合格させたいか何人か投票することができるのですが、その投票でより多くの票を得た人もこのコミュニケーションスキルの観点で評価されます。
1. 規律正しさは、簡単に言えばどれだけ学校に来て勉強しているか、アクセス時間が長ければ長いほど評価されます。毎日同じような時間にきて同じような時間に帰るような規則正しいリズムを作っているとより評価されやすいそうです。逆に、アクセス時間は長いものの1週間休んでしまっていたり、毎日時間がバラバラだとよくないそうです。

私はpiscineの期間中土日も含めほぼ毎日（２日だけ休みました）学校に来ていました。
平均で１日のアクセス時間は９時間だったと思います。

通うと往復で4時間以上かかってしまうようなところに住んでいたので、近くの宿泊施設を予約していました。

実際、どうだったか？と聞かれれば、「すごく楽しかったし、いい経験になった！もう二度とやらないけど（ぼそっ）」

やはり、フランス語も流暢に喋れない、英語でも専門用語は調べないといけない、そんな中毎日プログラミング漬けの日々。。。

評価の対象になるため、無理にでも他の人に話に行ったり、遅れている人を助けたりもしていました。

コミュニケーションがそこまで得意ではない自分にとってはとても大変でしたが、今思えばそのおかげで友達が作れたので、こう言う経験も悪くないのかなと思います。

## 42 paris のpiscineを受けようとしている方にアドバイス
コミュニケーションが苦手でも評価の対象となる上、仲間としてたくさんの人と繋がる機会になるため、無理にでも話に行きましょう。pisineでは、話しかけられて嫌な顔をする人はほとんどいません。

3週間目くらいで必ずと言っていいほど、精神的に病む時期がやってきますが、みんな経験しているので、最後まで絶対にやってやると言う根性で乗り切りましょうw

フランス語が喋れなくても大丈夫、何人かはフランス語をほとんど喋れない人もいます。なので、せめて英語でコミュニケーションができるようにしましょう。（全く英語が話せない人はほとんどいません。翻訳とか使って乗り切りましょう）


## 合格してからの話
やっぱり入ってよかったなと言う点と、ここは注意した方がいいなと思う点がありました。

やっぱり入ってよかったと思うのは、やはりプロジェクトの面白さです。

グループプロジェクトがあったり、Unix, Algorithm, 2D, 3Dなどなど色々なカリキュラムが充実していて、毎回知らないことがたくさん出てくるので勉強できている感覚がとても強いです。

そして42のコアであるピアツーピア（生徒が教えあったり評価し合うことでお互いを高め合う教育の仕方）によりたくさんの人と出会うことができます。

逆に注意した方がいいと思ったことは、

滞在許可書は自分で取らないといけないことです。

もともとビジタービザを持っていたのですが、学生用の滞在許可書を更新するのに、学校が手続きを行なってくれると思っていたのですが、実際は全部自分でやらないといけませんでした。

あとは、合格して通い始めたけど、途中から来なくなってしまう人がすごく多いこと。

私の周りでもそのような人がたくさんいますが、その主な理由は２つあります。
1つは物理的に距離が遠くて通うのがしんどくなる
もう1つは他の人の進む早さに圧倒され、自分は向いてないんじゃないかと思ってしまう人。

新しいことを始める時は知らない状態から入るので、最初は時間がかかります。

1番進むのが早いような人は経験者がほとんどで比べる必要はありません。

進捗が遅くても、愚直に毎日通っていればすこしずつは進むし、

何かにつまづいて止まってしまっているなら、誰かに助けを求めればいいだけです。

何が言いたいかと言うと、合格したら終わりではなく、

合格してからが本当の始まりと言うことです！

## あとがき
42 parisに日本人がほとんどいないので、もし挑戦してみたい人やもうすでにキャンパスにいる人は是非連絡してきてください。

パリには美味しい日本食のレストランがたくさんあるので食べに行きましょう笑
オーバーライド

オーバーライドはスーパークラスで定義したメソッド等をサブクラスで再定義する事です。

オーバーライドの方法は、スーパークラスで定義したメソッド等と同じ名前のメソッドを定義し、動作を記入する事です。

これを利用する事によって継承の際に、内容の修正が必要な部分だけを、サブクラス側で上書き出来る為、クラスの再利用やプログラムの簡略化が見込めます。
【JavaScript】オブジェクトの配列を、日本語を含む複数キーでソートしたい

## はじめに

### ソート対象

- オブジェクトの配列
    - 第一ソートキー：日本語の値を持つ`name`の昇順
    - 第二ソートキー：数字の値を持つ`value`の昇順

```javascript
const array = [
    {name: "うえき", value: 2}, 
    {name: "いのうえ", value: 1}, 
    {name: "うえき", value: 1}, 
    {name: "あいかわ", value: 2}, 
    {name: "いのうえ", value: 2}, 
    {name: "あいかわ", value: 1}
];
```

### 目標とするソート結果

```javascript
[
    {name: "あいざわ", value: 1},
    {name: "あいざわ", value: 2},
    {name: "いのうえ", value: 1},
    {name: "いのうえ", value: 2},
    {name: "うえき", value: 1},
    {name: "うえき", value: 2}
]
```

:::note warn
- 漢字をソートするのは困難であるため、ふりがなでソートしています
    - 詳細は以下をご参照ください
         - [JavaScriptのsort関数で日本語を50音順に並べたい](https://qiita.com/eiji-noguchi/items/af1e125932e9be19d069)
        - [MDN：String.prototype.localeCompare()](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare)
    :::

## 作成したコード

```javascript
array.sort((a, b) => {
  const firstKeySortResult = a.name.localeCompare(b.name, 'ja');
  if (firstKeySortResult !== 0) {
    return firstKeySortResult
  } else {
    return a.value - b.value; // a < b のとき、-1になり昇順になる
  }
});
```

### 簡単な解説

- まず`localeCompare`を使用して、`name`プロパティでソートします
    - `name`が同じでない（つまり`a.name.localeCompare(b.name, 'ja') !== 0`）ならこのソート結果を返します
    - `name`が同じなら、`value`プロパティでソートした結果を返します

## 別解

- 三項演算子を使って以下のようにも書けます
    - @eufss0183様からコメントにてご教示いただきました

```javascript
array.sort((a, b) => a.name.localeCompare(b.name, 'ja') || a.value - b.value);
```

### 簡単な解説

- `a.name.localeCompare(b.name, 'ja') `について、
    - 0以上か0未満なら`a.name.localeCompare(b.name, 'ja')`の結果が返る
    - 0なら`false`となり`a.value - b.value`の結果が返る

:::note info
- 「`a.value - b.value`でなんで昇順になるの？？」と思った方は以下のページを参考にしてください
    - [配列の要素を並び替える](https://www.javadrive.jp/javascript/array/index16.html#section3)
:::

## おわりに

- ひらがな、カタカナの属性を持たせれば、日本語でもソートできることを知りました
- ソートの基礎知識も再確認でき、良い機会でした