OmniAICreator/Qiita-1.07M huggingface dataset:
DMMの短期インターンに行ってきたよって話

![image.png](https://image.dmm-corp.com/qsxrp4g4qngbtismms5ygo8jdix7)
# DMM1Weekインターン結果報告
どうもGadgeloggerだ！季節が変わってきて寒くなってきたねぇ。。。俺は酒ばかり飲んで免疫力爆アゲと思って調子乗ってたら風邪引きました。最悪です🤦‍♂️<br>

とまあそんな前置きは置いといて
# どんなインターン？（公式ページから抜粋）
DMM.comは、Webを通じて様々なコンテンツを提供する事業会社です。

2022年12月に新規でローンチした「DMM TV」をはじめとした国内有数の動画配信コンテンツや、電子書籍、FX、オンラインサロン、英会話、3Dプリントなど、60以上の幅広いサービスを時代に合わせて柔軟に展開することにより、常にユーザーへ価値を提供しています。



今回はAndroidの短期インターンを開催！

DMMの新卒技術研修をベースとした演習を体験していただきます。

「アプリ開発にチャレンジにしたい」「DMMの演習が気になる」などの興味をお持ちの方は、是非ご参加ください。

[詳しい情報はこちら](DMM.comは、Webを通じて様々なコンテンツを提供する事業会社です。%20%202022年12月に新規でローンチした「DMM%20TV」をはじめとした国内有数の動画配信コンテンツや、電子書籍、FX、オンラインサロン、英会話、3Dプリントなど、60以上の幅広いサービスを時代に合わせて柔軟に展開することにより、常にユーザーへ価値を提供しています。%20%20%20%20今回はAndroidの短期インターンを開催！%20%20DMMの新卒技術研修をベースとした演習を体験していただきます。%20%20「アプリ開発にチャレンジにしたい」「DMMの演習が気になる」などの興味をお持ちの方は、是非ご参加ください。)

# インターンに参加したきっかけ
本当は１ヶ月間の長期インターンにエントリーしたが、自分のスキル不足で落選してしまった😇<br>
その際に人事の方から「Androidの１週間なら枠空いてるけど来てみない？」と親切に紹介してくださったので参加した感じやわ！<br>

# 使用する技術スタックは？
言語：Kotlin・Jetpack Compose<br>
バックエンド：Docker

# 作るアプリは？
Twitterのようなパクったアプリを作ろう！な感じ。要件は<br>
- ログイン機能
- 投稿機能
- 投稿削除機能<br>
な感じで、フロントエンドとバックエンド両方触れることができるいい感じのテーマのアプリやね。
# 雰囲気とかどうやった？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1657253/148c3c48-38e2-884c-d8f8-efb319335ff9.png)
雰囲気はすごくゆるいね！！！！<br>
１週間のうち2日間は環境構築とかを行なう感じで、トラブッたらすぐにエンジニアの方がヘルプに入ってくださるのでサポート体制は抜群だった。<br>
残りの3日間で黙々と要件に沿ったAndroidアプリを作っていく感じで、プログラミングの経験がなくてもマニュアル通りにすればアプリ自体は作れる感じだから「技術力ないんだけど・・・・」みたいな人でも受けやすいなと感じた。

# インターンを受けてみて
普段はFlutterで開発してて、気分転換にSwiftをちょこっとだけするような人間なので、全く触れたことがないAndroidアプリに触れることができていい経験だった！<br>
本来はオンラインのみのインターンなのでインターン生同士の交流はできないんやけど、特別にDMM本社にお邪魔させていただく機会を得ることができた。<br>
学生同士で交流できて同じ就活情報を共有できる友達を作ることができたので感謝しかねぇ。<br>


ちなみに今回のインターンの結果報告はDMMさんでもまとめてくださっているのでリンクを貼っとくね。

https://inside.dmm.com/articles/internandroidgo/
静的ライブラリをCrystalからリンクする

## いそがしい人のための結論

Crystalでは、簡単に静的ライブラリをリンクできる。

`-link-flags` フラグを指定すればよい。

```sh
crystal build a.cr --link-flags "-L/path/to/the/dir -lpiyo`
```

以上。

## はじめに

　C言語のライブラリには「共有(shared)ライブラリ」と「静的(static)ライブラリ」があります。Rubyでバインディングを作成するときは、Ruby-FFIやFiddleを使って共有ライブラリを呼び出すと楽なことが多いので、もっぱら共有ライブラリに触れていました。C拡張ライブラリとしてGemを作る場合は、静的ライブラリにリンクすることも可能ですが、一般にはパッケージマネージャーで配布される共有ライブラリを使うのが王道だと思うので、静的リンクは少し縁遠い世界でした。

## Crystalでは静的ライブラリにリンクすることができる

クリスタルでコマンドライン・ツールを作って配布するときは、Dockerイメージを使ってmuslでコンパイルすることが多いですね。C言語のライブラリをCrystalから呼び出すときも静的にビルドしたいですね。Crystalの公式のマニュアルを読んでもやり方がわかりにくかったので、Qiita記事に残します。

## 参考資料

次の記事がよくまとまっていました。

https://qiita.com/naoyoshinori/items/5c0b96ae2ae17cb4bf4f

## 静的ライブラリを準備する

簡単な例として、Intの文字列を足し合わせるだけのライブラリを作ります。`addition.h` と `addition.c` を用意します。

```c:addition.h
#ifndef ADDITION_H
#define ADDITION_H

int add(int a, int b);

#endif
```

```c:addition.c
#include "addition.h"

int add(int a, int b) {
    return a + b;
}
```

静的ライブラリ `libaddition.a` を生成します。`ar` コマンドで複数のオブジェクトファイルをまとめて、静的ライブラリとすることができます。ここでは `addition.o` 一つだけです。

```sh
gcc -c addition.c -o addition.o
ar rcs libaddition.a addition.o
```

作成された `libaddition.a` をC言語から使う場合は、次のようなコードを書いて、

```c:main.c
#include <stdio.h>
#include "addition.h"

int main() {
    int result = add(5, 3);
    printf("Result: %d\n", result);

    return 0;
}
```

こんな感じのコマンドでコンパイルします。

```sh
gcc main.c -L. -laddition -o main
```

ここで、`-L` コマンドはライブラリのパスを直接指定していますが、`ldconfig -v` というコマンドを使うことで、すでにパスが通っている場所や利用できるライブラリの一覧などが表示できるようです。

## Crystalから静的ライブラリを使う

実は、Crystalのコードは共有ライブラリのときと同じです。

```cr:a.cr
@[Link("addition")]
lib LibAddition
  fun add(a : Int32, b : Int32) : Int32
end

puts LibAddition.add(5, 3)
```

大切なのは、ビルドコマンドに `--link-flags` を追加することです。

```
crystal build a.cr --link-flags "-L/home/kojix2/Crystal/tmp -laddition"
```

正しくコンパイルされていることを確認します。

```
./a
8
```

実際に生成されたプログラムがリンクされているライブラリを確認してみましょう。

```sh
ldd ./a
```

```
	linux-vdso.so.1 (0x00007fff799c2000)
	libpcre2-8.so.0 => /lib/x86_64-linux-gnu/libpcre2-8.so.0 (0x00007f8f86b50000)
	libgc.so.1 => /usr/local/lib/libgc.so.1 (0x00007f8f86ae2000)
	libevent-2.1.so.7 => /lib/x86_64-linux-gnu/libevent-2.1.so.7 (0x00007f8f86a90000)
	libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f8f86a6c000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f8f86800000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f8f86d3c000)
```

`libaddition` はありません。つまり、libaddition.so がない環境でもこのプログラムは動作します。めでたしめでたし。

この記事は以上です。

---

本来は「Crystal言語がどのようにして動作するのか調べてみた（中編）」を投稿する予定だったのですが、昨年は記事をかけるだけの進捗がなく、あきらめて薄いネタを投稿しました。なお、Crystal言語の理解を諦めたわけではありませんので、少しずつ勉強していずれはCrystalがどのように動作しているのか理解したいと思っています。
2024年のDrupalについて

Qiita Advent Calendar 2023も終わりましたが、通常通り時間がないので年を越えました…。
時間の使い方が不自由なので、思い立ったら動くのが吉です。

2024年に迎えるにあたり、下記のURLを参照しながら他の情報も踏まえて簡潔に紹介します。

[Drupal core release schedule](https://www.drupal.org/about/core/policies/core-release-cycles/schedule "Drupal core release schedule")

# Drupal 10.3 リリース候補日
Drupal 10.2 が2023年末にリリースされましたが、 ６ヶ月後にDrupal 10.3 がリリース予定。
* 2024年6月17日の週

さらに６ヶ月後にDrupal 10.4 がリリース予定。
* 2024年12月9日の週

# Drupal 11 リリース候補日
Drupal 10 は2022年にリリースされましたが、2024年はいよいよ Drupal 11 がリリースします。
現時点ではリリース候補日は３つあります。
* 2024年6月17日の週
* 2024年7月29日の週
* 2024年12月9日の週

# これからの Drupal

## CKEditor 5
CKEditor 4　は2023年12月３１日にサポートが切れました。CKEditor 4 のカスタムモジュールを利用している場合に、CKEditor 5 に対応しているか確認が必要です。
[Drupal CKEditor 4 LTS – what to expect beyond EOL](https://ckeditor.com/blog/drupal-ckeditor-4/ "Drupal CKEditor 4 LTS – what to expect beyond EOL")

## フィールド作成のUX向上
主に Drupal 10.2 からですが、フィールド作成する画面が変わりました。選択できる項目がグリッド表示されアクセシビリティが向上しています。


# Drupal 10.3で導入される機能
2024年に Drupal　Core に導入されるモジュールをを紹介します。

## Automatic updates
GUIでモジュールやテーマの更新を行なったり、自動で更新されるモジュールが実装されます。
最近はコアアップデートとモジュールでサイトダウンも体験しなくなったので、カスタマイズしていないサイトでは有益でしょう。
[Automatic updates](https://www.drupal.org/project/automatic_updates "Automatic updates")

## Project Browser
これまではDrupal.orgでモジュールを探していましたが、Drupalサイト上の管理画面でモジュールが操作できる機能がコアに実装予定です。
[Project Browser](https://www.drupal.org/project/project_browser "Project Browser")
![qiita-2024-01-19-10.29.23.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59566/66c3e3b6-5b16-6fef-84dc-d777cbf27060.jpeg)

# おわりに
これから利用する方も、利用している方にも簡潔に Drupal を2024年に利用する上で、情報をまとめてみました。
Drupal を利用することで自身の物事が進展できると幸いです。
【ネットワーク】初心者のためのイーサネット説明(MDIとMDI-X)

## 概要
前回の記事はイーサネットについて説明をしました。
今回は前回の続きを説明していきます。

前回の記事は下記のものになります。
こちらの記事を読んでからの方が理解しやすいと思います。
是非、こちらも読んでみてください。

https://qiita.com/nakamura_slj/items/2f2df1f946a579023fbc

## 対象とする読者
* ネットワークの基礎から学びたい人
* 前回の記事を読んだ人
* これからIT業界で仕事をしようと考えている人
* CCNAの資格を取ろうとしている人

## MDIとMDI-X
LANケーブルを差し込むポートには、MDIとMDI-Xの２種類があります。
機器によってMDIとMDI-X、どちらの仕様かが決まっていて、下記のように受信と送信で使用するピンが異なる仕様となっています。
通信を行う際には、送信と受信が向かい合うように接続します。
MDIのポートを持つ機器同士をつないでしまうと、互いに１、２番が送信、３、6番が受信となってします。
MDI-X同士の場合も同様になります。

| 種類 | 説明 | 機器の例 |
|:--------|:----------|:----------|
|MDI|８本のうち、１番目と２番目を送信に使用し、３番目と６番目を受信に使用します。|ルータやPCなど|
|MDI-X　|８本のうち、１番目と２番目を受信に使用し、３番目と６番目を送信に使用します。|ハブやスイッチなど|

そこで、前回の記事で説明したストレートケーブルとクロスケーブルを使い分けて、送信と受信が向かい合うようにします。

ストレートケーブルはMDIのポートを持つ機器とMDI-Xのポートを持つ機器同士を接続する際に利用します。
ストレートに動線が伸びていけば送信と受信が向かい合う形になります。

クロスケーブルはMDIのポートを持つ機器同士、またはMDI-Xのポートを持つ機器同士を接続する際に利用します。
ストレートに伸ばすと送信と受信が向かい合わないため、途中で動線をクロスさせます。
そうすることで、送信と受信が向かい合うようになります。

参考程度にストレートケーブル、クロスケーブルで接続するものの例をそれぞれいくつかあげようと思います。

【ストレートケーブルで接続するもの】
* ルータとスイッチ
* PCとスイッチ　など

【クロスケーブルで接続するもの】
* ルータとルータ
* スイッチとスイッチ
* PCとPC
* PCとルータ　など

# 最後に
以上となります。
今回はイーサネットの続きの内容を説明しました。
次回はイーサネットの規格について説明しようと思います。
Java学習 条件分岐

# if文
Javaでのif文
```java
class Main {
  public static void main(String[] args) {
    int value = 10;

    if (value > 0){
      System.out.println("値は正です。"); 
    }
  }
}
```
実行結果
```
値は正です。
```

## if文の使い方
```java
if ( 条件式 ) {
  条件式を満たす場合に実行する処理
}
```
### Rubyの記述方法との違い

・条件式を（）で囲む必要があること
・行いたい処理を{}で囲む必要があること

## そのほかの条件分岐
Rubyでのelse, elsifはJavaでは以下のように記述する。

```java
class Main {
  public static void main(String[] args) {
    int value = 10;

    if (value > 0){
      System.out.println("値は正です"); 
    }else if (value < 0){
      System.out.println("値は負です"); 
    }else {
      System.out.println("値は0です"); 
    }
  }
}
```

Rubyでの使い方と基本は同じ
```java
if (条件A) { 
  // 処理A
} else if (条件B) {
  // 処理B
} else {
  // 処理C
}
```
* 条件Aが「真(True)」の時は処理Aが実行される
* 条件Aは「偽(False)」で、条件Bが「真(True)」の時は処理Bが実行される
* 全ての条件が「偽(False)」の時は処理Cが実行される

### Rubyの記述方法との違い
Rubyでは `elsif` と記述したが、Javaでは `else if` と記述する。

# まとめ
Rubyのif文と記述方法に少し違いがあるが、使い方の違いはほとんどない。
RAGの品質評価フレームワークの選択肢

# RAGの品質評価 
最近、LLMコミュニティは自動評価の利用を探求しており、多くの研究者や企業がLLMを使用して自身のLLMアプリケーションの出力を評価しています。

DatabricksがGPT-3.5とGPT-4を評価として使用して、自社のチャットボットアプリケーションを評価した実践は、LLMを自動評価ツールとして使用することが効果的であることを示唆しています。

https://qiita.com/taka_yayoi/items/ea80ae072b2706e399b1

この方法がRAGベースのアプリケーションを効率的かつコスト効果的に評価することもできるでしょう。


# 評価のためのフレームワーク
RAG評価フレームワークの分野では、RAGAS、ARESが比較的新しいものです。
これらの評価の主な焦点は、回答の信頼性、回答の関連性、およびコンテキストの関連性という3つの主要な指標にあります。さらに、オープンソースライブラリであるTruLensも同様の評価モードを提供しています。
これらのフレームワークはすべて、評価のためにLLMを評価者として使用しています。

## RAGAS（Retrieval-Augmented Generation Assessment System）

https://github.com/explodinggradients/ragas

RAGASは、リトリーバルシステムの関連性の高いキーコンテキスト段落を特定する能力、LLMがこれらの段落を忠実に使用する能力、および生成自体の品質を考慮した評価フレームワークです。

RAGASは、手書きのシンプルなプロンプトに基づいており、これらのプロンプトを使用して、回答の信頼性、回答の関連性、コンテキストの関連性という品質の3つの側面を完全に自動化された方法で測定します。

このフレームワークでは、OpenAI APIを通じて利用可能なgpt3.5-turbo-16kモデルを使用して、すべてのプロンプトを評価します。

### 回答の信頼性の評価：
LLMを使用して回答を個々のステートメントに分解し、それぞれのステートメントがコンテキストと一致するかどうかを検証します。最終的に、サポートされているステートメントの数と総ステートメント数を比較することにより、「信頼性スコア」が計算されます。

### 回答の関連性の評価：
LLMを使用して潜在的な質問を生成し、これらの質問と元の質問との類似性を計算します。
回答関連性スコアは、生成されたすべての質問の元の質問への平均類似度によって導き出されます。

### コンテキストの関連性の評価：
LLMを使用して質問に直接関連する文を抽出し、これらの文の数をコンテキスト内の総文数との比率としてコンテキスト関連性スコアを使用します。

これらの評価方法により、RAGASは、リトリーバル拡張生成のパフォーマンスを総合的かつ精密に評価することを目指しています。これにより、研究者や開発者はRAGシステムのさまざまな側面を評価し、改善のための洞察を得ることができます。

https://www.creationline.com/tech-blog/66773


## ARES（Augmented Retrieval Evaluation System）

https://github.com/stanford-futuredata/ARES


ARESは、コンテキストの関連性、回答の信頼性、および回答の関連性の3つの側面でRAGシステムのパフォーマンスを自動的に評価することを目指しています。

RAGASは手書きのシンプルなプロンプトに基づく新しい評価フレームワークであり、新しいRAG評価設定に対する適応性が限られているため、ARESの作業の重要性の一つです。

ARESは、少量の手動で注釈付けされたデータと合成データを使用し、評価のコストを削減し、予測駆動推論（PDR）を使用して統計的な信頼区間を提供し、評価の精度を向上させます。

### アルゴリズムの原則
合成データセットの生成： ARESは最初に、ターゲットコーパスの文書から言語モデルを使用して合成の質問と回答を生成し、肯定的および否定的なサンプルを作成します。

### LLM裁判官の準備：
次に、ARESは合成データセットを使用して軽量言語モデルをファインチューニングし、コンテキストの関連性、回答の信頼性、および回答の関連性を評価するためにトレーニングします。

### 信頼区間を使用したRAGシステムのランキング：
最後に、ARESはこれらの裁判官モデルを適用してRAGシステムをスコアリングし、PPI（Predictive-Driven Reasoning）メソッドを使用して手動で注釈付けされた検証セットと組み合わせ、信頼区間を生成し、RAGシステムのパフォーマンスを確実に推定します。

## TruLens

https://www.trulens.org/

https://future-architect.github.io/articles/20230914a/

https://zenn.dev/kun432/scraps/3c51fef2b1fac4
[Windows] Wondows用Xサーバー、sshクライアントソフトでLinux計算マシンを便利に使う

## Windowsで簡単にUbuntu Desktopアプリを使いたい
　別室に設置したUbuntu DesktopマシンへWindowsからssh接続して計算させたりしている。すると計算結果を気楽にプロットしたい、Ubuntu Desktop用アプリのウィンドウを接続元のWindowsで見たい、という時がある。これは[Windowsクライアントを使って、クラウド上のLinuxサーバでGUIアプリを実行したい（2）](https://qiita.com/yamada-hakase/items/80cef4ed58fefbba266b "qiita")のようなことだが、こちらの設定は面倒というか自分でやるのは難しそうだな、、と躊躇していたところ、もっと簡単な方法を見つけて便利に使っているのでチョット紹介。

## MobaXterm
　方法というのは[MobaXterm](https://mobaxterm.mobatek.net/ "MobaXterm")をインストールするだけというもの。無料版でも上記の用途は満たせる。
　ホームページ下部の"Get MOBAXTERM NOW!"から無料のHome Editionを選択すればよい。有償版と比べると機能が限られていることがわかる。
 ![HP.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3636689/ff166a34-f058-809e-4f6b-d59bc6a25174.jpeg)
　ダウンロードは管理者権限がなくとも使える実行ファイル版のPortable Editionとインストーラーを使ってインストールするInstaller editionがある。環境に合わせて好きな方を選択すればよい。

## Ubuntuの場合の設定
　ssh接続するLinuxサーバー側にはデスクトップ環境を構築しておく必要がある。Ubuntuの場合はdesktop版がインストールされているならばsshや使いたいデスクトップアプリをインストールしておくだけでよい。Ubuntu server版の場合、最も簡単なのは下記をインストールする方法。
```desktop:terminal
$ > sudo apt install -y ubuntu-desktop
```
余計なアプリなどもインストールされてしまうが最も簡単な方法と思う。

## テスト
　クライアント側のWindowsからMobaXTermを使ってUbuntuサーバーへssh接続し、下記を入力してみる。
 ```xeyes:terminal
$ > xeyes &
```
懐かしい目玉ちゃんがWindows画面に現れるだろう。これはxeyesアプリをUbuntuで立ち上げ、Windows画面に出力した結果だ。
![xeyes.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3636689/db9961ca-be24-9a89-fa85-057183b74ca5.jpeg)

Ubuntu側にgnuplotがインストールされていればMobaXtermでプロットコマンドを入力すれば結果がWIndows側で表示される。

## まとめ
　超簡単にWindowsへX server環境を作る方法でした。これでLinuxバージョンしかないアプリも便利に使えるだろうと思う。ネット接続ワークステーションやサーバーを使うハードルが下がるのがよいと思う。
PRIME STUDY 第1回 Python 3 基礎 模擬試験 解いてみた

PRIME STUDY
第1回 Python 3 基礎 模擬試験を受けました。

スコアは 83 点 / 100点満点です。

https://study.prime-strategy.co.jp/

間違えた問題を復習します。
--
**15.次の関数を呼び出す際に、引数の指定として正しいものはどれか。**
```ruby:
def location(city, state, country='Japan'):
    print("I live in",country,".")
    print("My company is located in",city,",",state,".")
```
```ruby:正答
location(state='Tokyo', city='chiyoda')
```
:::note info
**解説**
引数は
・何番目がなんの意味 をきっちりあわせて指定する
か、
・対象関数の引数名をきっちり明示してキーワード引数するか
のどちらか
:::

**22.次のコードの実行結果として正しいものはどれか。**
```ruby:
Zen = 'ExplicitIsBetterThanImplicit'
print(Zen[1:20:3])
```
```ruby:実行結果
xitBtTn
```
:::note info
解説
「始点のインデックス番号 : 終点のインデックス番号 : スキップする数+1」
:::

**23.データ構造に関する次の記述のうち誤っているものはどれか。**
**正答**
ディクショナリは変更不能（immutable）であるがキーの型は変更可能（mutable）であり、その値は一意でなければならない。

:::note info
解説
ディクショナリは変更可能（mutable）であるが、キーの型は変更不能（immutable）であり、その値は一意でなければならない。
:::

**24.次のうち対話モードで入力したときに「True」が返されるのはどれか。**
```ruby:正答
'PHP' < 'Perl' < 'Python'
```
:::note info
解説
文字列の比較では、「辞書順の比較」が行われます。
つまり辞書に単語が載っている順番のように、先頭の文字から順番に比較が行われます。
大文字小文字を区別（大文字<小文字）

"PHP" と "Perl" を比較するときは、
まず最初の 1 文字を比較して P と P で等しい
等しいので 2 文字目を比較して 大文字H と 小文字e で e の方が大きい
ので「True」

"Perl" と "Python" を比較するときは、
まず最初の 1 文字を比較して P と P で等しい
等しいので 2 文字目を比較して e と y で y の方が大きい
ので「True」
:::

**29.エラーと例外に関する次の記述のうち誤っているものはどれか。**
**回答**
パーサ（構文解釈器）は違反のある行を表示し、**最後にエラーが検知された点**を小さな矢印で示す。**エラーは矢印より後のトークンが原因**である。

:::note info
解説
パーサは違反の起きている行を表示し、小さな「矢印」を表示して、行中でエラーが検出された最初の位置を示します。エラーは矢印の 直前の トークンでひき起こされています (または、少なくともそこで検出されています)。入力がスクリプトから来ている場合は、どこを見ればよいか分かるようにファイル名と行番号が出力されます。
:::

**36.statisticsモジュールを使って、データの平均、中央値、分散を求めたい。次のコードの【A】【B】【C】に入りうる組み合わせとして正しいものはどれか。**
```ruby:
import statistics
data = [1,10,15,20,25,30,35]
rslt1 = statistics.【A】(data)
rslt2 = statistics.【B】(data)
rslt3 = statistics.【C】(data)
print(rslt1, rslt2, rslt3)
```
```ruby:正答
mean median variance
```
Laravelプロジェクトで実際に使ってるartisanコマンド一覧(随時更新予定)

初めてプロジェクトに参加して約2ヶ月経過
いくつか忘れたのもあると思いますが、実際に現在入ってるLaravelのプロジェクトで使ったartisanコマンドを備忘録として残しておきます！

## 　artisanについてざっくり解説
PHPのフレームワークLaravelのコマンドラインインターフェースツール(CLI)のこと
CLIとはキーボードを使って文字やコマンドを入力してプログラムを操作すること


## 業務で使ったことあるartisanコマンド


## 利用可能なartisanコマンドを全部表示
```
php artisan list
php artisan
```

## REPL（Read-Eval-Print Loop）
- 読み込み（Read）：キーボードで入力したコマンドや文字を入力すること
- 評価（Evaluate）：システムがユーザーが入力したコードを解析し、実行すること
- 出力（Print）：コードの実行結果や出力の結果を画面に表示すること
 - 繰り返し（Loop）：入力を再度受け付けて、読み込みできるように戻ること
私はよくDBにアクセスしてどんなデータが取れるかどうか確認するときに使ってます
```
php artisan tinker

例
php artisan tinker
>>> use App\Models\User; //←なくてもモデル読み込んでくれる
>>> User::first();
```

## マイグレーションファイルのupメソッドを実行し、データベースにテーブルを作成
database/migrationsディレクトリを確認し、まだ実行されていないすべてのマイグレーションを順番に実行
```
php artisan migrate
```
## データベースの全てのマイグレーションをdownメソッドで削除してupメソッドで再度テーブル作成をする
```
php artisan migrate:refresh
```
## up,downメソッド関係なくデータベースのテーブルを削除し、すべてのマイグレーションを再実行する、migrationのdownが効かなかったりrefreshできないときに使う認識
```
php artisan migrate:fresh
```



## グループ化して、特定のテストを実行できます
```
php artisan test --group=(テスト名)

例
it('ログインできること', function () {
 ・・・
})->group('login');
```
## 全テストを一括で行える
```
php artisan test 
```


## 指定した名前のモデルファイルを作成
```
php artisan make:model モデル名
```
## 指定したモデルに対するファクトリを作成、テストデータの生成を書くファイル

```
php artisan make:Factory　モデル名
```
## 新しいデータベースマイグレーションファイルを作成
```
php artisan make:migration　[テーブル名]
```

## 指定したモデルに対するデータベースシーダを作成
```
php artisan make:seeder　モデル名＋Seeder
```

## model,Factory,migration,seederを一括で生成できるので楽！！
```
php artisan make:model -fms モデル名
```

## データベースにテストデータや初期データ
```
php artisan db:seed
```
【AtCoder】AtCoder Beginner Contest 336 解法メモ【Ruby】

# はじめに

ABC336に参加しました。
今回、A~Dの4問完答できたのでD問題までメモしていきたいと思います。

# [A - Long Loong](https://atcoder.jp/contests/abc336/tasks/abc336_a)

`Long`の`o`を指定の数だけ結合する問題。

文字列結合ができれば良いので特に問題はない。強いて言えば、文字をn個繋げる処理をどう実装するか、が問題になるが、Rubyには`String#*`が定義されているので難しくない。

<details><summary>自分の回答</summary>

```ruby
puts "L#{"o" * gets.to_i}ng"
```

</details>

# [B - CTZ](https://atcoder.jp/contests/abc336/tasks/abc336_b)

整数を2進数表記したときに、末尾に連続する0の数を求める問題。

色々定義されているが、2進数表記に直して末尾から0の個数を数えるだけで良い。

<details><summary>自分の回答</summary>

楽に実装したかったので、2進数表記にした後に正規表現で末尾の0を取得する方針で実装した。

```ruby
puts gets.to_i.to_s(2).match(/0*$/)[0].length
```

</details>

## B問題別解

今回の問題は２進数の末尾が0かどうかをチェックするだけなのでビットシフト(右シフト)しながら1桁目の数値をチェックすることで同じことができる。
こちらだと文字列の生成等が不要になるので上の回答よりは高速に処理ができるので参考として記載しておく。

<details><summary>右シフトを利用した回答</summary>

```ruby
n = gets.to_i
c = 0
# 1桁目が0の間、カウントアップして右シフトする
while (n & 1) == 0
  n = n >> 1
  c += 1
end
puts c
```

</details>

# [C - Even Digits](https://atcoder.jp/contests/abc336/tasks/abc336_c)

偶数のみからなる整数群のうち、小さいものからn番目の整数を求める問題。

各桁の取りうる値は`0, 2, 4, 6, 8`の5つであり、8の次は桁上がりして0に戻る。つまり5進数の特殊(数値が`0~4`ではない)なパターンと見ることができる。
そのため、5進数と`0, 2, 4, 6, 8`を`0=>0, 1=>2, 2=>4, 3=>6, 4=>8`のように対応させると、10進数でのnを5進数に変換した値の各桁を対応表にそって変換した値が答えになる。
m進数のi桁目の値は10進数のnに対して、`(n / m^(i-1)) % m`で求められるので、あとはコードに落とし込むだけでよい。

<details><summary>自分の回答</summary>

```ruby
# 1番目の値が0なのでずらしておく
n = gets.to_i - 1
# 5進数との対応表
arr = %w[0 2 4 6 8]

# 0は自明なので事前に処理する
if n == 0
  puts 0
  exit
end

ans = []
while n > 0
  ans << arr[n % 5]
  n /= 5
end
puts ans.reverse.join("")
```

</details>

## C問題別解

今回の問題は偶数からなる値のため、5進数との対応がそれぞれ2倍にしたものと対応する。
そのため、5進数に直した値を2倍すれば解答になるため実装をよりシンプルにすることができる。

<details><summary>5進数での値を2倍する実装</summary>

```ruby
puts (gets.to_i - 1).to_s(5).to_i * 2
```

</details>

# [D - Pyramid](https://atcoder.jp/contests/abc336/tasks/abc336_d)

与えられた数列の中に含まれるピラミッド数列の最大値を求める問題。

まず、与えられた数列の大きさによって、生成されうるピラミッド数列の理論値が決まる。具体的には配列の長さnに対して`(n + 1) / 2`(少数切り捨て)となる。
その場合の数列の各要素の最大値はi番目の要素aiに対して`ai = MIN(i, n - i)`となる。
※先頭と末尾はピラミッドの端になるため1になり、そこから1つピラミッドの内側に入るたびに1増加するため。
※Nが奇数の時は中央が最大となる1つのピラミッドのみだが、Nが偶数の時は最大のピラミッドは2つ選び方がある。

与えられた数列の要素のうち上で求めた理論値未満となる値がある場合は、そこがピラミッドの間の谷(または谷に続く道)となり取りうるピラミッドの高さを下げる要因となる。
ピラミッド数列は隣接する要素との差は1となるため、周囲より低い要素から左右に1段ずつ高くするように要素を更新していくことを全ての要素で行えば出来上がった配列の最大値が答えとなる。
ただし、この処理はn個の要素に対し左右n個の要素の更新処理が入るため、O(N^2)の計算量になり得るので効率化する必要がある。

やりたいことは低い位置から1段ずつ増えていく階段を作りたいだけなので、先頭と末尾からそれぞれ一つ前の高さより高い場合は一つ前の高さ+1に更新する処理をかけてあげると求めたい配列が得られる。
得られた配列の中で最大の値が答えとなる。

<details><summary>自分の回答</summary>

```ruby
n = gets.to_i
arr = gets.split.map(&:to_i)
# 最大のピラミッド数列の場合の値に調整
# ※先頭・末尾から計算する際に1から上書きする処理が入っているためこの処理は不要
arr.each_with_index do |a, i|
  arr[i] = [a, i + 1, n - i].min
end

# 先頭から登る
ba = 0
arr.each_with_index do |a, i|
  if a > ba
    ba += 1
    arr[i] = ba
  else
    ba = a
  end
end

# 末尾から登る
ba = 0
arr.reverse.each_with_index do |a, i|
  if a > ba
    ba += 1
    arr[-i - 1] = ba
  else
    ba = a
  end
end

puts arr.max
```

</details>

# 最後に

C問題で凡ミスして2ペナもらったけどD問題までちゃんと解けてよかったです。
E問題も挑戦してみましたが今回は全く手が出なかったです。解説を軽くみていると桁DBというものを使うらしいので後で確認して理解を進めておきたいですね。

# 参考リンク

- [AtCoder Beginner Contest 336](https://atcoder.jp/contests/abc336)
セレクトボックスを作る

サンプルコード
<select name="your-kind" id="your-kind">
  <option value="" selected disabled>選択してください</option>
  <option value="">セレクト1</option>
  <option value="">セレクト2</option>
  <option value="">セレクト3</option>
</select>

以下は説明
select要素
		
属性:　name=""
値:文字列	
説明:部品の名前を指定


属性:size=""
値:行数	
説明:表示行数を指定
この属性の値に 1 を指定するとプルダウン形式のメニューになり、2 以上を指定するとリスト形式のメニューになります。（この属性を指定しない場合は、1 を指定した時と同じになります）

属性:multiple
値は不要
説明:複数選択を可能にする
Windowsの場合は、ShiftまたはCtrlキーを押しながらクリックすると、複数を選択することができます。

option要素
		
属性:value=""
値:文字列
説明:送信される文字列を指定
この属性を省略した場合は、option要素内のテキストが送信されることになります。

属性:selected
値は不要
説明:選択された状態を指定

属性:disabled
値は不要
説明:部品を無効化する
この属性が指定された部品は、選択することができなくなります。
【PythonとJava】コードを書いて比べてみた！！

# 実際に書いてみた！
PythonとJavaのコードの違いをまとめてみました！
## 問題①
https://atcoder.jp/contests/abc336/tasks/abc336_a
### Python
pythonで解いた場合は以下になる
```python
N = int(input())  # 文字列を読み込み整数に変換する
ans = 'L'
for i in range(N):
    ans += 'o'
print(f'{ans}ng')
```
### Java
Javaで解いた場合は以下になる
```java
import java.util.Scanner;
public class Test {
        public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        int num = input.nextInt(); // 整数を読み込む
        String ans = "L";
        for(int i = 0; i < num; i++){
            ans += "o";
        }
        System.out.println(ans + "ng");
        numIn.close();
    }
}

```
## 問題②
https://atcoder.jp/contests/abc339/tasks/abc339_a
### Python
```python
S = input()
ans_lst = S.split('.') # 「.」で区切りリストに格納
print(ans_lst[-1])
```
### Java
```java
import java.util.Scanner;

public class Main {
    public static void main(String args[]){
        Scanner sc = new Scanner(System.in);
        String str = sc.next();
        
        String rep = str.replace(".", ",");
        String[] array01 = rep.split(",");
        
        int ans = array01.length - 1; // 配列の長さ-1を取得する。
        System.out.println(array01[ans]);
        sc.close();
    }
}
```

メモリの消費量はJavaが半分になっている。
実行時間はPythonが短い。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2759758/8eea5c26-0238-fbbb-f766-fc69a887012c.png)

## 九九の表示
期待する出力
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2759758/d5fe9f00-0b63-9470-2ad7-17dec0744318.png)
### Python
```python
for i in range(1, 10):
    for j in range(1, 10):
        value = i * j
        print(f"{value:2}", end=" ")
    print()  # 改行
```
### Java
```java
public class sample4 {
    public static void main(String[] args){
        for(int i = 1; i < 10; i++){
            for(int j = 1; j < 10; j++){
                int value = i * j;
                System.out.printf("%2d ", value);
            }
            System.out.println(); // 改行
        }
    }
}
```
閉じたVPC内でECS FargateをXRayでトレースを取るための設定

掲題の件、閉じたVPCからECS FargateをXRayでトレース取る手順です。


## VPC Endpoint作成
ネットワーク繋がらない環境なので、XRayへのVPC Endpoint作成しておきます。こちらは省略します。

## aws-xray-daemonの準備
ECSのXRay連携ではサイドカーとしてaws-xray-daemonを起動することになります。

https://docs.aws.amazon.com/ja_jp/xray/latest/devguide/xray-daemon.html

自分でビルドしたりも可能ですが、今回はPublicのECRから取得してきます。以下のURLになります。

https://gallery.ecr.aws/xray/aws-xray-daemon


ドキュメントに記載されていることが多い、Docker Hubにある`amazon/aws-xray-daemon`と名前が変わっていて `xray/aws-xray-daemon` となっていることに注意です。


## Pull Through Cache
当然、閉じたVPCからPublicのECRにアクセスできないので、ECRのPull Through Cacheを利用します。設定としては[Terraformで言えば](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ecr_pull_through_cache_rule)以下の標準的なものを利用してみます。

```terraform
resource "aws_ecr_pull_through_cache_rule" "example" {
  ecr_repository_prefix = "ecr-public"
  upstream_registry_url = "public.ecr.aws"
}
```

後はECRへのVPC Endpointを作成すれば、以下の名前で`xray/aws-xray-daemon`をPullできるようになります。

```
123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecr-public/xray/aws-xray-daemon:latest
```


##  IAM権限

### タスク実行ロールにECR Pull Through Cache用権限付与
ECR Pull Through Cacheから `xray/aws-xray-daemon` をPullするため、[こちらのドキュメント](https://docs.aws.amazon.com/ja_jp/AmazonECR/latest/userguide/pull-through-cache.html)を参照して以下のような権限から必要なものを与えます。

- ecr:CreatePullThroughCacheRule
- ecr:BatchImportUpstreamImage
- ecr:CreateRepository

こちらはECSの `タスク実行ロール` に設定します。

### タスクロールにXRay Daemon用権限付与
こちらは以下のマネージドポリシーの利用することが可能です。 `タスクロール` にアタッチしておきます。

- arn:aws:iam::aws:policy/AWSXRayDaemonWriteAccess


## ECSタスク定義
ECSタスク定義の例は以下の通りです。

```python
{
  "networkMode": "awsvpc",
  "cpu": "2048",             # xray-daemonのCPUも合計値に含まれるので注意
  "memory": "4096",          # xray-daemonのMemoryも合計値に含まれるので注意
  "containerDefinitions": [
    # mainコンテナ等
    {
      "name": "xray-daemon",
      "image": "123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecr-public/xray/aws-xray-daemon:latest",　# ECR Pull Through Cacheを指定
      "cpu": 32, 
      "memoryReservation": 256,
      "portMappings": [
        {
          "containerPort": 2000,
          "hostPort": 2000, # hostPortとcontainerPortの値は合わせる
          "protocol": "udp"
        }
      ]
    }
  ],
  "logConfiguration": {
    "logDriver": "awslogs",
    "options": {
      "awslogs-group": "/ecs/xxxx",
      "awslogs-region": "ap-northeast-1",
      "awslogs-stream-prefix": "logs",
      "max-buffer-size": "25m",
      "mode": "non-blocking"
    }
  }
}
```

## Pythonに組み込み
後はPythonに組み込みます。

```sh
poetry add aws-xray-sdk 
# or
pip install aws-xray-sdk 
```

```python
from aws_xray_sdk.core import patch_all, xray_recorder

xray_recorder.configure(service="myapp")
plugins: tuple[str] = ("ECSPlugin",) # Tupleである必要があるので注意
xray_recorder.configure(plugins=plugins)
patch_all()


if __name__ == "__main__":
    xray_recorder.begin_segment(name="Main")
    main(env=EnvironmentToFargateTask.parse_obj(env))
    xray_recorder.end_segment()
```
CloudEventsを使用したGoogle Cloud Functionsの簡単セットアップ

# はじめに
本記事は、下記を試したメモです。
[cloudevents](https://github.com/GoogleCloudPlatform/functions-framework-nodejs/blob/main/docs/cloudevents.md)


# cloudeventsをインストール
```
go install github.com/cloudevents/conformance/cmd/cloudevents@latest
```
※READMEには、go getと記載がある

# パス追加
```
export PATH=$PATH:$(go env GOPATH)/bin
```

# 確認
```
cloudevents --help
```

# インストール
```
npm install @google-cloud/functions-framework
```

# index.js追加
```index.js
const functions = require('@google-cloud/functions-framework');

functions.cloudEvent('helloCloudEvents', (cloudevent) => {
  console.log(cloudevent.specversion);
  console.log(cloudevent.type);
  console.log(cloudevent.source);
  console.log(cloudevent.subject);
  console.log(cloudevent.id);
  console.log(cloudevent.time);
  console.log(cloudevent.datacontenttype);
});
```

# package.jsonに下記追加
```package.json
{
  "scripts": {
    "start": "functions-framework --target=helloCloudEvents"
  }
}
```

# 実行
```
npm start

> start
> npx functions-framework --target=helloCloudEvents

Serving function...
Function: helloCloudEvents
Signature type: cloudevent
URL: http://localhost:8080/
```

# cloudevents実行
```
cloudevents send http://localhost:8080 --id  abc-123 --source cloudevents.conformance.tool --type foo.bar
```

# 実行結果
```
> start
> npx functions-framework --target=helloCloudEvents

Serving function...
Function: helloCloudEvents
Signature type: cloudevent
URL: http://localhost:8080/
1.0
foo.bar
cloudevents.conformance.tool
undefined
abc-123
undefined
undefined
```

# 所感
これを使えばGoogle Cloud Consoleで「保存してデプロイ」を何回もクリックすることは、回避できそう！

# 参考
https://github.com/GoogleCloudPlatform/functions-framework-nodejs/blob/main/docs/cloudevents.md
Laravel + Vue + Inertia.jsでVueのレイアウトを設定する

# はじめに
この記事はLaravel、Vue、Inertia.jsの構成でVueのレイアウトを設定する方法について書いています。
いくつかファイルを作成するのですが、最終的に下記のようなディレクトリ構成になります。
```
resources
    ┗js
      ┣Layouts
      ┃     ┗DefaultLayout.vue
      ┃     ┗CustomLayout.vue
      ┗Pages
          ┗index.vue
```
# 前提
* Laravel、Vue、Vite、Inertia.jsで環境構築ができている
* サンプルコードには`<script setup>`構文を使う

# デフォルトのレイアウトの設定方法
デフォルトのレイアウトは各ページファイルで自動的に適用されるレイアウトになります。ページファイル内でレイアウトを指定している場合はそちらが優先して適用されます。

設定方法について説明していきます。
まずはレイアウトファイルを作成します。
```vue:resources/js/Layouts/DefaultLayout.vue
<template>
  <header>
    <h2>Header</h2>
  </header>
  <slot />
</template>

<style scoped>
header {
  height: 70px;
  width: 100%;
  background-color: #cfd8dc;
  display: flex;
  align-items: center;
}
h2 {
  margin-left: 30px;
}
</style>
```
次に`app.js`を下記のように修正します。
```js:resources/js/app.js
import { createApp, h } from "vue/dist/vue.esm-bundler"
import { createInertiaApp } from "@inertiajs/vue3"
import { resolvePageComponent } from "laravel-vite-plugin/inertia-helpers"
import DefaultLayout from "./Layouts/DefaultLayout.vue"

createInertiaApp({
    resolve: (name) => {
        const page = resolvePageComponent(
            `./Pages/${name}.vue`,
            import.meta.glob("./Pages/**/**/*.vue")
        )
        page.then((module) => {
            // ここで設定する
            module.default.layout = module.default.layout || DefaultLayout
        })

        return page
    },
    setup({ el, App, props, plugin }) {
        createApp({ render: () => h(App, props) })
            .use(plugin)
            .mount(el)
    },
})
```
最後にページファイルを作成します。
```vue:resources/js/Pages/index.vue
<template>
  <div style="padding: 10px;">
    index.vue
  </div>
</template>
```

表示されたページでレイアウトが適用されます。
![inertia-layout.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1046681/8ac31fc5-8229-0e3e-6c1a-37bb8e1a5e70.png)

# 各ページのレイアウトの設定方法
先ほどはデフォルトのレイアウトの設定でしたが、ページごとにレイアウトを指定して設定する方法もあります。
まずは新たにレイアウトファイルを作成します。
```vue:resources/js/Layouts/CustomLayout.vue
<template>
  <header>
    <h2>Header</h2>
  </header>
  <slot />
</template>

<style scoped>
header {
  height: 70px;
  width: 100%;
  background-color: #1E88E5;
  display: flex;
  align-items: center;
  color: #fff;
}
h2 {
  margin-left: 30px;
}
</style>
```
先ほど作成したページファイルを修正します。
```vue:resources/js/Pages/index.vue
<!-- ここから追加 -->
<script setup>
import CustomLayout from "/resources/js/Layouts/CustomLayout.vue"
defineOptions({ layout: CustomLayout }) // ここでレイアウトファイルを指定する
</script>
<!-- ここまで追加 -->
<template>
  <div style="padding: 10px;">
    index.vue
  </div>
</template>
```
下記のように`CustomLayout.vue`が適用されます。
![inertia-layout2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1046681/ffc7bcbf-5a85-dcb2-4233-da1b9a5b7e25.png)

以上になります。
最後まで見ていただきありがとうございました。

# 参考
https://inertiajs.com/pages

https://laracasts.com/discuss/channels/vite/vite-inertiajs-persistent-layouts
EKS 1.24 から 1.28 へアップグレードしたので感想等

# 背景

EKSの1.24が2024/01末日 でEOLを迎えます。
それに伴って、最新のバージョンに上げました。（サービス無停止）
そこで得た知見をシェアします。

前提として
AWS上でクラスタを構築していて、terraformで管理されています。

# 全般

kubernetes上にOSSで他のアプリケーション(Argo etc)を使っていたら
upgrade guide みたいなものがあるので一通りを通すと、問題に直面した時に感が利く。
release noteとか、見てたら、日が暮れてしまうので、そこまでしなくてよかったと反省。

https://aws.github.io/aws-eks-best-practices/
が更新されていそうなので、適宜眺めておくとよかった。

in-placeであげるよりも、同じ構成のクラスタをもう一つ用意して、lbで切り替えた方が良さそう。

IaC必須

# kubernetes

https://aws.amazon.com/about-aws/whats-new/2023/12/amazon-eks-upgrade-insights/
こういう機能が出たけど、あまり役に立たなそうだった。（Custom resource使っていると、影響あるリソースが網羅できていないので注意）

# ArgoCD

あまりk8s 依存がないので、単体であげる方が良さそう。
最新のバージョンは権限まわりが厳しくなっているので、ちゃんと設計した方が良さそう
雑に最低権限だけ与えていても動くっちゃ動く

# ArgoWorkflow

あまりk8s 依存がないので、単体であげる方が良さそう。
アップグレードによる影響がほぼない。
webhookAPI使えるので、うまく利用して、CronWorkflowとかcliで管理すると楽

# Istio

canary releaseができるみたいなので、利用して、単体でupgradeすると良さそう。
1.21はExternalName周りの挙動に気になる変更があるので、1.20にアップグレードしてから、当該の機能を有効化する動作検証やっといた方が良さそう。

# 感想

動作確認になかなか骨が折れた。
動作確認のためにcli commandをたくさん書いて、テスト項目書を作ったので、cli周りはそこそこ慣れた。

やったことのボリュームが大きすぎて、何か書き残そうと思ったけど、まとめるのがしんどくなるので、内容が薄くなってしまう。

SREチームのメンバー数人に合意を得ながら一人で進めたので、
このプロジェクトに従事した３ヶ月で書いたドキュメントの量はそこそこあるが、
X(twitter)の採用ページにドキュメント書く人材よりコード各人材のが価値がある。
みたいな記載があって悲しくなった。
M5GOでLチカ

## はじめに
M5GOはGroveコネクタによって様々なセンサや各種I/Oデバイスを容易に接続することができるマイコンボードで、プロトタイプの制作に適しています。M5GOには３種類のGroveポート（A、B、C）が1個ずつ付いていますが、M5GOの本体にジャンパピンを差し込める端子はありません。自分好みの回路を作るには、Groveポートに差したコードをジャンパピンに変換してから回路に接続することになります。
ここではそれを利用して簡単な例として、M5GOのGPIO（汎用I/Oポート）のBポートをGroove変換コードを使ってジャンパピンに変換して、Lチカを行いました。

## Lチカのやり方

### Grove変換コードについて
次のGrove変換コードを使用しました。このコードは購入した時点ではコネクタに付いている爪が干渉してM5GOに差し込めないため、爪を取る必要があります。

https://www.switch-science.com/products/6245?variant=42382097645766

本記事の「参考」の二番目の記事に、Groveコードは黄色と白の配線がstack製とは逆になっているという注意点が載っています。

### 回路とスケッチ
回路は次のように配線しました。
- Grove変換コードの白線を抵抗（数100Ω）の一方の端子へ接続
- 抵抗のもう一方の端子をLEDのプラス極へ接続
- LEDのマイナス極をGrove変換コードの黒線へ接続

次の写真は回路を作成してLチカさせている様子です。Grove変換コードのコネクタはM5GoのBポートに差し込んでいます。

![20240114_194521.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1729073/6cdb5e24-5de0-0744-d7d3-624ee66d244a.jpeg)

Arduino IDEのスケッチです。抵抗に接続されているGrove変換コードの白線はM5Stack製のコードの黄色線に相当するため、M5Goの26番につながります。したがって、26番ピンをオンオフ制御すればLEDをオンオフできることになります。

```
void setup() {
  pinMode(26, OUTPUT);
}

void loop() {
  digitalWrite(26, HIGH);
  delay(1000);
  digitalWrite(26, LOW);
  delay(1000);
}
```
## 開発環境
マイコンボード：M5GO Ver.2.7
ボード情報：M5Stack by M5Stack, ver. 2.1.0
Ardiono IDE：ver. 2.2.1
OS：Windows11

## 終わりに
何かのご参考になれば幸いです。

## 参考
https://www.marutsu.co.jp/pc/static/large_order/grove_221103

https://raspberrypi.mongonta.com/useful-tools-and-parts-for-m5stack/
AWS-CLF (Cloud Practitioner) 合格体験記


# はじめに
こんにちは！<font color="black">**@mto2yma2**</font>です。

今回は過去に受けて1発合格を果たせたAWS-CLFの合格体験記として、
当時の勉強法だったり勉強時間等振り返りながら備忘録程度に記していきます。
今ではCLFのバージョンも変わってしまっていますが、
この記事を読む方に少しでも参考になればと思います！:relaxed:

とりあえず簡単に……↓
- <font color="black">**筆者のスペック**<font>
・理系学生
・NW、DBなど情報系に関する基礎知識0
・コーディング能力無し


## AWS-CLFの結果
とりあえず点数は以下の通りです！
700点以上で合格のところ、なんとか<font color="black">**752点**</font>で<font color="red">**一発合格**</font>できました！！！

![スクリーンショット 2024-01-18 204058.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3674393/b450dc19-0528-0f3e-6b93-fd648b78d689.png)

2022年の10月末日の受験なので1年ちょっと前ですね:sweat_smile:
合計勉強時間は40~50hほどだったと記憶してます。

そこで今回は資格取得までに何を行ったかなどをまとめてみます！
これからAWSを触るための第一歩としてCLFの取得を目指す方の参考になればと思います:pray:

## 使用教材
とりあえず下の2つを使いました。
- 図解まるわかり AWSのしくみ

https://www.amazon.co.jp/%E5%9B%B3%E8%A7%A3%E3%81%BE%E3%82%8B%E3%82%8F%E3%81%8B%E3%82%8A-AWS%E3%81%AE%E3%81%97%E3%81%8F%E3%81%BF-%E8%A5%BF%E6%9D%91%E6%B3%B0%E6%B4%8B/dp/479817470X/ref=asc_df_479817470X/?tag=jpgo-22&linkCode=df0&hvadid=588993955828&hvpos=&hvnetw=g&hvrand=10007730171490239532&hvpone=&hvptwo=&hvqmt=&hvdev=c&hvdvcmdl=&hvlocint=&hvlocphy=1009306&hvtargid=pla-1837854917272&psc=1&mcid=56915e4de487368483f316d77f44c042&th=1&psc=1

アマゾンのリンクを貼っていますが、メルカリなどで<font color="red">**800円**</font>ほどで購入しました:sunglasses:
~~技術書は高いので安く済ませたいですよね（　＾ω＾）~~

そもそもAWSに興味をもったきっかけが、夏のインターンでクラウド事業部に配属されAWSを実際に触ったことでした！
AWSってなんぞや、というのを自分なりに解像度をあげるために書籍をGETしました（紙派なので）

- 【CLF-C02版】この問題だけで合格可能！AWS 認定クラウドプラクティショナー 模擬試験問題集（6回分390問）

https://www.udemy.com/course/aws-4260/

こちらは定番のUdemyの模擬試験解集ですね。
セールの時を狙って<font color="red">**1800円**</font>？かそれ以下で購入しました！

模擬試験集は基本×2、本番実戦×4の内容で構成されています。
実際のCLFの試験よりUdemyの方が難しかったかなという印象です（752点ですが）
参考程度に私がどのようにUdemyを活用したかを示しておきます。



<font color="black">**①基本の2つをとりあえず解く**<font>
→初見では4割前後の正答率
→わからない単語はネットで調べたり、先述した本を見直して定着を図る。
→サービス名とその役割、動き方をなんとなく把握する。
→見直して2回目を受ける（7割程度）

<font color="black">**②本番実戦を2つ解く**<font>
→基本よりは難しいため初見は4~5割
→①同様に見直して2回目、あるいは3回目まで受ける(8~9割まで仕上げる)

<font color="black">**③試験2日前に3つめの本番実戦を解く**<font>
→この時初見で8割程度だった。

<font color="black">**④本番実戦4つ目は解かず**<font>
→時間がなく解かず…解けず…
→~~基本的に本番実戦を3つも解いたので中身もあまり変わらないだろうという気持ちも~~

## 試験会場について
試験会場に行くのが面倒くさかったので、自宅で受けました。
Pearson VUEというシステムでの受験となりました、詳しくは下を参照ください。

https://www.pearsonvue.co.jp/Clients/AWS.aspx

基本はこちら側がカメラをつけっぱなしにして、試験管とはチャットでやり取りをします。
一見かなり楽ですが、少し気になったこともあるので以下に示します。

<font color="black">**①試験開始時間が20-30分ほど遅れる。**<font>
リモート受験なので仕方ないことですが、受験環境は口うるさく言われます。
机から2ｍくらい離れたカレンダーをしまうように言われたり、かなり周りの環境はクリアにさせられました。
自分の後ろにおいてあったティッシュケースも片すよう言われました笑
そうこうチャットで話しては直してなどをするうちに開始時間が伸びていました。
後ろに予定がある人は注意してください！

<font color="black">**②チャットでのやりとり**<font>
画面から少し目が逸れるような動きが確認されたらチャットで注意されます。
あるいはカメラに近づきすぎて額しか映らなかった時も注意のチャットが飛んできました笑
毎回チャットに返信して訂正後の姿勢などを確認もらわないといけないので、気が逸れてしまいそうにもなりました。

とはいえ、移動時間などを考えると自宅で受けた方が圧倒的に楽だと思います！
集中できる環境を選んでください！

## 最後に
いかがでしたでしょうか！
これからAWSを触る人で知識を付けたい人、まずはCLFの取得を目指す人のお役に立てれば幸いです！！！

<font color="black">**いろんな勉強方法はありますが、結局は実際に無料枠を使ってAWSを触って肌で覚えるのが良いと思います！笑**<font>
あくまで本記事は試験をパスするための試験勉強にすぎないので…:sweat_smile:

ただ！、Udemyでの試験と見直しを高速サイクルで回せばすぐに知識はつくと思います！

今後も資格取得に関する体験や、現場での備忘録替わりに更新できたらと思います！
【Swift】LocalizedErrorを持つ列挙型を比較したい

# はじめに
以下のような列挙型を定義することはよくあると思います。
```swift
enum SampleResult {
    case success
    case failure(LocalizedError)
}
```

これを`Equatable`に準拠させようとすると以下のような関数を実装しなければいけません。

```swift
enum SampleResult: Equatable {
    case success
    case failure(LocalizedError)
    
    static func == (lhs: SampleResult, rhs: SampleResult) -> Bool {

    }
}
```

# よくある解決策
`localizedDescription`を比較しています。
しかし、別のエラーでも`localizedDescription`は一緒にしていることがあると思います。
これでは正確な比較になりません。
```swift
enum SampleResult: Equatable {
    case success
    case failure(LocalizedError)
    
    static func == (lhs: SampleResult, rhs: SampleResult) -> Bool {
        switch (lhs, rhs) {
        case (.success, .success):
            true
        case let (.failure(lhsError), .failure(rhsError)):
            lhsError.localizedDescription == rhsError.localizedDescription
        default:
            false
        }
    }
}
```

# 解決策
```swift
enum SampleResult: Equatable {
    case success
    case failure(LocalizedError)
    
    static func == (lhs: SampleResult, rhs: SampleResult) -> Bool {
        switch (lhs, rhs) {
        case (.success, .success):
            true
        case let (.failure(lhsError), .failure(rhsError)):
            String(reflecting: lhsError) == String(reflecting: rhsError)
        default:
            false
        }
    }
}
```

# 解説
以下のような2つのエラーがあります。
```swift
import Foundation

enum DemoError1: LocalizedError {
    case networkError
    case serverError
}

enum DemoError2: LocalizedError {
    case networkError
    case serverError
}
```

`String(reflecting:)`でエラーを出力すると、`プロジェクト名.エラー列挙型名.エラー名`が文字列に変換されます。
```swift
import Foundation

print(String(reflecting: DemoError1.networkError))
print(String(reflecting: DemoError1.serverError))
print(String(reflecting: DemoError2.networkError))
print(String(reflecting: DemoError2.serverError))

// Demo.DemoError1.networkError
// Demo.DemoError1.serverError
// Demo.DemoError2.networkError
// Demo.DemoError2.serverError
```

以下のようなネストされた同名のエラーであってもパスが違うので別のものとして認識できます。
```swift
import Foundation

struct HomeView {
    enum DemoError: LocalizedError {
        case networkError
        case serverError
    }
}

struct SearchView {
    enum DemoError: LocalizedError {
        case networkError
        case serverError
    }
}

print(String(reflecting: HomeView.DemoError.networkError))
print(String(reflecting: HomeView.DemoError.serverError))
print(String(reflecting: SearchView.DemoError.networkError))
print(String(reflecting: SearchView.DemoError.serverError))

// Demo.HomeView.DemoError.networkError
// Demo.HomeView.DemoError.serverError
// Demo.SearchView.DemoError.networkError
// Demo.SearchView.DemoError.serverError
```

# おわり
この実装で何か問題がありましたら、コメントで教えていただきたいです。
プレイヤーを追従するカメラの実装

プレイヤーが移動するとカメラも一緒についてくる処理を実装します。実行環境はUnity 2022.3.10fです。

# プレイヤーの操作
まずはプレイヤーを操作できるようにします。操作方法は矢印キーで移動、スペースキーでジャンプ、Zキーを押しながら矢印キーでダッシュとします。操作するためのオブジェクトを用意して以下のスクリプトをアタッチしてください。

```C#:PlayerController.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[RequireComponent(typeof(CharacterController))]
public class PlayerController : MonoBehaviour
{
    public float moveSpeed; //普段の移動速度
    public float dashSpeed; //ダッシュ時の移動速度
    public float jumpPower; //ジャンプ力
    private CharacterController controller;
    private Vector3 moveVelocity;

    void Start()
    {
        controller = GetComponent<CharacterController>(); //CharacterControllerを取得
    }

    void Update()
    {
        if (Input.GetKey(KeyCode.Z)) //Zキーが押されている場合
        {
            moveVelocity.x = Input.GetAxis("Horizontal") * dashSpeed; //横軸の入力を取得
            moveVelocity.z = Input.GetAxis("Vertical") * dashSpeed; //縦軸の入力を取得
        }
        else
        {
            moveVelocity.x = Input.GetAxis("Horizontal") * moveSpeed; //横軸の入力を取得
            moveVelocity.z = Input.GetAxis("Vertical") * moveSpeed; //縦軸の入力を取得
        }

        transform.LookAt(this.transform.position + new Vector3(moveVelocity.x, 0, moveVelocity.z));

        if (controller.isGrounded) //オブジェクトが地面にいる場合
        {
            if (Input.GetKeyDown(KeyCode.Space)) //スペースキー入力すると
            {
                moveVelocity.y = jumpPower; //Y軸正の方向に移動
            }
        }
        else
        {
            moveVelocity.y += Physics.gravity.y * Time.deltaTime; //重力によるY軸負の方向への移動
        }

        controller.Move(moveVelocity * Time.deltaTime); //オブジェクトを動かす
    }
}
```

アタッチしたらInspectorビューからMove Speed、Dash Speed、Jump Powerにそれぞれ値を入れます。自分の環境で試した場合、Move Speedは3、Dash Speedは8、Jump Powerは3くらいがいい感じでした。これでキャラクターを操作できるようになりました。プレイヤーが動き回るための簡易的なステージも作っておきましょう。Hierarchyから3D Object→Planeで簡単に作れます。

# 追従するカメラ
次にカメラがキャラクターについてくるようにします。以下のスクリプトを作成してMain Cameraにアタッチします。

```C#:CameraFollow.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CameraFollow : MonoBehaviour
{
    private Vector3 diff; //カメラとプレイヤーの距離
    private GameObject target; //追従するターゲットオブジェクト
    public float followSpeed; //追従するスピード

    void Start()
    {
        target = GameObject.Find("Player"); //名前がPlayerのオブジェクトを取得してターゲットに指定
        diff = target.transform.position - this.transform.position; //カメラとプレイヤーの初期の距離を指定
    }

    void LateUpdate()
    {
        transform.position = Vector3.Lerp(this.transform.position, target.transform.position - diff, Time.deltaTime * followSpeed); //線形補間関数によるカメラの移動
    }
}
```

アタッチしたらプレイヤー用のオブジェクトの名前を「Player」に設定しておきます。また、InspectorビューからFollow Speedに値を設定します。自分の環境では5に設定しました。Sceneビューを見ながらキャラクターが見やすいようにカメラの位置を調整します。この時のカメラとプレイヤーの距離を保ちながらカメラはプレイヤーを追いかけます。
LateUpdate関数の中でVector3.Lerpが使われていますが、これにより距離が離れているほど速く近づき、近いほどゆっくり近づく動きが実現でき、カメラが滑らかに移動します。実行するとプレイヤーがダッシュした時も、プレイヤーの動きに合わせてカメラが付いてくることが確認できます。

# 参考
https://gihyo.jp/book/2023/978-4-297-13741-0
https://www.socym.co.jp/book/1315
https://docs.unity3d.com/ja/560/ScriptReference/Vector3.Lerp.html
prettierの整形の際に出たエラー備忘録

## 環境

```bash
"dependencies": {
    "next": "13.5.6",
    "react": "^18",
    "react-dom": "^18"
  },
  "devDependencies": {
    "@types/node": "^20",
    "@types/react": "^18",
    "@types/react-dom": "^18",
    "@typescript-eslint/eslint-plugin": "^6.19.0",
    "@typescript-eslint/parser": "^6.19.0",
    "autoprefixer": "^10",
    "eslint": "^8.56.0",
    "eslint-config-next": "13.5.6",
    "eslint-plugin-react": "^7.33.2",
    "postcss": "^8",
    "prettier": "^3.2.4",
    "react-hook-form": "^7.49.3",
    "tailwindcss": "^3",
    "typescript": "^5"
  }
```

## 今回でたエラー

```
(node:1050) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.
(Use `node --trace-warnings ...` to show where the warning was created)
[error] Invalid configuration for file "ご自身のプロジェクトパス":
[error] Unexpected token 'export'
```

## 解決策

`package.json`に下記を追記するだけ

```bash
"type": "module",
```

追記後の`pacage.json`は下記になります。

```bash
  "name": "hogehoge",
  "version": "0.1.0",
  "private": true,
  "type": "module",
```
【社内 LT 会資料】アノテーションツール CVAT の紹介

# 注意事項

この資料は画像認識に関係の無い会社内での LT 会のもののため、内容が薄く、平易な言葉で表現しています。

- - -

# 前回の LT 会

ディープラーニングによる画像分類の取り組みを紹介した。

https://qiita.com/tfandkusu/items/3c83669669d01f58e8f2

- - -

# 学習データ作成のためのツール紹介

そのためには学習データが必要。
学習データは人力で作成する必要があり、そのためのツールをアノテーションツールを呼ぶ。
今回は OSS (MIT ライセンス) のツール「CVAT」を紹介。

https://www.cvat.ai/

- - -

# できること(一部抜粋)

- アノテーション作業
    - それが何であるかを入力
    - 対象の位置を入力
- ユーザー管理
    - アノテーションタスクを作り、ワーカーにお願いすることができる
- [作業結果の出力](https://opencv.github.io/cvat/docs/manual/advanced/formats/)
- [自動アノテーション](https://opencv.github.io/cvat/docs/manual/advanced/automatic-annotation/)
    - ありもののモデルでアノテーションしておいて、人間は間違いを正す。

- - -

# インストール方法

- [クラウド版](https://www.cvat.ai/pricing/cloud)
- [自分で構築](https://opencv.github.io/cvat/docs/administration/basics/installation/)
    - Docker Compose で構築できる

- - -

# このスライドの作者は使うの？

使わない。

## 理由

- 標準のキーバインドが使いにくいが、変更できない。

- - -

# Flutter Desktop で自作

https://qiita.com/tfandkusu/items/435650c5b4667ea97169

自分が使いやすいキーバインドになっている。
ユーザー管理はできないが自分で作業するので問題なし。[題材](https://qiita.com/tfandkusu/items/b8b498d60ddff3db4d50#%E9%A0%AD%E5%87%BA%E3%81%97%E3%81%AE%E6%96%B9%E6%B3%95)的に著作権の問題があり、他人に画像を渡せない。

- - -

# 今後の予定

このアプリ自体は今でも使えるが、書き方が古いので、最新の Flutter の学習をかねてリニューアル中。
Gitとかの備忘録

## はじめに
この記事では、初心者が仲間内で開催されたGit・Github講座を受けて理解したことを備忘録として保存します。

## Gitとは
Gitはローカルでバージョン管理をするためのツール。

## Githubとは
Gitを使ったオンラインサービス。自分のローカルのGitリポジトリを公開したり別の端末と共有したり他人と一緒に開発したりするときに使う。

## 使い方
### clone
Github上のリポジトリをローカルに複製する。
一緒にbranch情報も複製される。
### addとcommit
add: リポジトリの変更を保存する部分を指定する
commit: 変更をメッセージといっしょに保存する。
### pullとpush
pull: Github上に上げられた変更をローカルに適応する。
push: Github上に変更を保存（アップロード）する。

## プルリクエスト
Githubではファイルの編集は差分で記録している。
同じ箇所を複数人が触ると競合発生！
⇨ 権限がないとpushできないようにする。
⇨ 変更したかったら権限者にお願いしよう！
これがプルリクエスト。

競合したときに片方を消してもう片方を優先するのをマージという。

## さいごに
多分もっと便利な機能があるはずだけどここまでできればOKらしい！これだけでもめちゃめちゃ便利では？？？
Google のグローバルサイトタグを読み込んでいると、onYouTubeIframeAPIReadyが勝手に定義される

タイトルの通りです。

# 何が困るのか。
以下のような実装を行う過程で問題に遭遇しました。

- YoutubeIframeAPIを使って動画プレイヤーを埋め込む。
- 動画プレイヤーは、コンポーネント化して使い回せるようにする。
- コンポーネント初期化時に、YoutubeIFrameAPIを読み込む。
- 複数箇所にコンポーネントを使う場合、YoutubeIFrameAPIの読み込み処理を重複させないようにしたい。
- YoutubeIFrameAPIの読み込み処理をすでに実行したかどうか、`window.onYouTubeIframeAPIReady`が定義済みかどうかで判別する

## YoutubeIframeAPIを読み込むとき
それと同時に以下のように、コールバック関数である`onYouTubeIframeAPIReady`をグローバルに定義すると思います。
```JavaScript
window.onYouTubeIframeAPIReady = function () {
  console.log('onYouTubeIframeAPIReady!!');
  resolve();
};
var tag = document.createElement('script');
tag.src = '//www.youtube.com/iframe_api';
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
```
なので、`window.onYouTubeIframeAPIReady`が`undefined`かどうかによって、API読み込み処理を実行済みかどうかを判別できるはず。
```JavaScript
if (typeof window.onYouTubeIframeAPIReady !== 'undefined') {
  // すでに読み込み処理済み
  // window.YT.Playerが定義される（＝読み込み完了）されるまで待ってから初期化
} else {
  // 読み込み処理してない
}
```
と思うじゃん？

## グローバルサイトタグの罠
ところが、YoutubeIframeAPIを読み込む前から、`window.onYouTubeIframeAPIReady`が定義されていることがありました。
```JavaScript
console.log(window.onYouTubeIframeAPIReady);
// -> function (){r&&r();q()}
```
なんじゃこりゃ？
よくよく調べてみると、Googleのグローバルサイトタグを読み込んだ時に、勝手に定義されるようです。
（これに気がつくまでに相当時間を取られました）
```html
<script async src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX"></script>
```
なので、いつまで経ってもYoutubeIframeAPIの読み込みを開始しないため、動画が再生できないという現象に遭遇することになりました。


# どう対処したのか
グローバルサイトタグがなぜonYouTubeIframeAPIReadyを定義しているのかはわかりません。
しかし、この問題にどう対処したのかだけ書いておきます。
~~コンポーネント類の初期化を始める前に、`onYouTubeIframeAPIReady`を`undefined`にしてしまうことにしました。~~
```JavaScript
if (typeof window.onYouTubeIframeAPIReady !== 'undefined') {
  window.onYouTubeIframeAPIReady = undefined;
}
```

~~あまり良い解法だとは思いませんが、すぐ対処してとりあえず動くことが優先です。
現場からは以上です。~~

### よりよい方法
より良い方法に行き着いたので追記。
```JavaScript
  const originalCallback = window.onYouTubeIframeAPIReady;
  window.onYouTubeIframeAPIReady = function() {
    if (originalCallback) originalCallback();
    // Youtube API読み込み後の処理を書く
  }
```
これなら、もともと定義されているコールバック関数も実行される。
qiskit_experimentsを用いて状態操作

[Qiskit pulseを用いて状態操作](https://qiita.com/tare_/items/ccef2856903eef886cf6)では，qiskit.pulseを用いて状態操作を行いました．今回は同様の実験を，qiskit_experimentsを用いて，より簡単に行いたいと思います．

# qiskit_experiments
[Qiskit pulseを用いて状態操作](https://qiita.com/tare_/items/ccef2856903eef886cf6)では，マイクロ波の波形から逐一設定していました．これらの面倒な設定を代行してくれるのがqiskit_experimentsです（多分）．

それでは，[Qiskit pulseを用いて状態操作](https://qiita.com/tare_/items/ccef2856903eef886cf6)と同じ実験を実際に行ってみましょう．

# Calibrations

```python
import numpy as np
import qiskit.pulse as pulse
from qiskit.circuit import Parameter
from qiskit_experiments.calibration_management.calibrations import Calibrations
from qiskit_experiments.library.calibration.rough_frequency import RoughFrequencyCal
from qiskit import schedule
from qiskit import IBMQ


IBMQ.save_account("") #tokenを代入
#IBMQ.load_account()
provider = IBMQ.get_provider(hub='ibm-q')
backend = provider.get_backend('') #使えるbackendを選んでください

qubit = 0
cals=Calibrations.from_backend(backend)

# 単位変換係数
GHz = 1.0e9 # Gigahertz
MHz = 1.0e6 # Megahertz
us = 1.0e-6 # Microseconds
ns = 1.0e-9 # Nanoseconds

# おおよその周波数を取得
freq01_estimate = backend.defaults().qubit_freq_est[qubit]

# その周辺で周波数をスイープ
frequencies = np.linspace(freq01_estimate-30*MHz, freq01_estimate+30*MHz, 100)

spec = RoughFrequencyCal([qubit], cals, frequencies, backend=backend)
spec.set_experiment_options(duration=120*ns, sigma=15*ns, amp=0.05)
```

これでマイクロ波の波形の設定まで終わりました．[Qiskit pulseを用いて状態操作](https://qiita.com/tare_/items/ccef2856903eef886cf6)と比較すると，簡略化されていることが分かります．一方で，[公式ドキュメントのRoughFrequencyCal](https://qiskit.org/ecosystem/experiments/stubs/qiskit_experiments.library.calibration.RoughFrequencyCal.html)を見ると，波形はGaussianSquareしか対応していないことが分かります[^1]．実際に波形について見てみると，
```python
next(iter(circuit.calibrations["Spec"].values())).draw()
circuit.calibrations["Spec"]

#{((0,),
#  (-30000000.0,)): ScheduleBlock(ShiftFrequency(-30000000, DriveChannel(0)), Play(GaussianSquare(duration=240, sigma=30.000000000000004, width=0.0, amp=0.05, angle=0), DriveChannel(0)), ShiftFrequency(30000000, DriveChannel(0)), name="spectroscopy", transform=AlignLeft())}
```
と，GaussianSquareになっていることが分かります[^2]．このように，波形の種類を制限してしまうという欠点もあります．

結果のプロットも簡単です．
```python
spec_data = spec.run().block_for_results()
spec_data.figure(0)
```
![result.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/887541/cbf3e0b6-c44e-90af-6bfd-ad411fd9c149.png)

自動でローレンツ関数でフィッティングしてくれます．嬉しいですね．[Qiskit pulseを用いて状態操作](https://qiita.com/tare_/items/ccef2856903eef886cf6)と同様の結果が得られていることが分かります．

# 最後に
２量子ビット操作も実験してみたいですね．


#### Version Information
|Software|Version|
|---|---|
|qiskit|0.45.1|
|qiskit_experiments|0.5.4|


||System information|
|---|---|
|Python version	|3.10.12|





[^1]:波形については，[量子ビットのパルス操作シミュレーション](https://qiita.com/tare_/items/e00ab16d3622f233a470)でも少し紹介しました．

[^2]:durationやsigmaが設定した値の2倍となって表示されていることが分かります．おそらく単位が異なるのだろうと思っているのですが，原因はよく分かっていません．