OmniAICreator/Qiita-1.07M huggingface dataset:
[プロジェクト管理]人日/人月というクソみたいな単位について

# わかりやすくてわかりにくい単位
IT屋のプロジェクトの工数とかで出てくる「〇〇人日」や「〇〇人月」と言う、
いわゆる「1人で作業したらどれぐらいかかる」を表した単位になりますが、
これ使うのマジで止めて欲しいんだよね。。。

## いや、分かるんだけど。。。
見積もりをするに当たり、その工程にどれぐらいかかるかっていうのを、
なんとなく分かりやすい単位で表すのに使うには非常に便利なんだけど、
人によって作業スピードが違うし・技術的なレベルも雲泥の差があったりするのに、
どうして一括りに「〇〇人日」や「〇〇人月」としてしまうのか、
これって誰も得しなくね？って思うわけですよ。

# マネージャーの皆様へ
まだ知識がバブちゃんな新人や、純粋に仕事が出来ない ~~（無能な）~~ 人が、ベテラン基準で算出された工数にて作業をする時に、めっちゃ被害者になるって見積もりする権限のある人は理解をして欲しいわけですよ。

いや普通はそこら辺も考慮したうえで、
ベテランでも社会人3年生ぐらいのスキルレベルでの見積もりしたり、
若干のバッファを詰んで見積もりをするかと思いますが、
お客様の中には「お前そんな工数かからんやろ、一気に減らすンゴ」とか訳わからん補正が入ったりなかったり。。。

# そもそも
年齢・スキル・経験も全く異なるメンバーが集まってプロジェクトが回るのに、ソレを同じ単位で計算すること事態どうなの？
またベテランとの作業量や専門性も違うので、作業者の単価という金銭面的な補正はあるにしろ、ソレがきちんと給料として反映される派遣系の会社とかってあまりないように思うので、何かそこら辺ちゃんとした単位が出来てほしいなぁと思う今日このごろでした。
商用webアプリでSIL Open Font Licenseのwebフォントを使う時に必要な対応

# 概要
webフォントを商用利用のwebアプリに組み込むにあたって、色々調べたのでメモ

# SIL Open Font Licenseについて

原文
https://openfontlicense.org

日本語訳
https://licenses.opensource.jp/OFL-1.1/OFL-1.1.html

# どうすれば商用で使えるの？

OFL（SIL Open Font License）であることを明示すればほぼ自由にWebフォントを利用できる。
ただし、具体的な明示方法についての説明はない。

https://yomotsu.net/blog/2012/10/09/webfont-license
こちらの記事を参考にした。（10年以上前の記事だけどSIL Open Font Licenseのバージョン 1.1ができたのが2007年2月26日で、それより後の記事なので問題なさそう）
CSSファイル内にコメントで配布元のURLを記載する、という方法が良さそう。

# そもそもwebフォントのライセンスってどうやって確認するの？
基本的にはwebフォントの配布元サイトを確認すればわかる。

# おまけ
日本語webフォントは容量が大きいから気をつけてね、というお話。
欧文フォントなら数キロバイトで済むので気にしなくていい。
https://ics.media/entry/200317/#%E3%82%A6%E3%82%A7%E3%83%96%E3%83%95%E3%82%A9%E3%83%B3%E3%83%88%E3%81%AF%E8%AA%B2%E9%A1%8C%E3%81%8C%E5%A4%9A%E3%81%84
PowerShell v7.4でリダイレクトの動作が改善されていた

PowerShellのv7.4より前までは、バイナリを出力するコマンドをリダイレクトするとファイルが壊れる現象があり、困っていた。
自分の場合、`git show`でバイナリファイルを取得する際に、以前のPowerShellではファイルが壊れるため、Git Bashに切り替えて取得するようにしていた。

```powershell:PowerShell v7.3まで
PS> git show revisio:binary/file/path > binaryfile # ファイルが壊れる
```

```sh:Git Bash
$ git show revisio:binary/file/path > binaryfile # ファイルは正常
```

v7.4でバイトストリームをそのままリダイレクトするようになったため、PowerShell上でいけるようになっていた。
https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_redirection?view=powershell-7.4#example-7-redirecting-binary-data-from-a-native-command

```powershell:PowerShell v7.4以降
PS> git show revisio:binary/file/path > binaryfile # ファイルは正常
```

とてもありがたい。
ngx-bootstrapでモーダルダイアログ作成

# ngx-bootstrapを用いてモーダルダイアログを表示する方法

1. 呼び出し側のHTML
 ダイアログのComponentを呼び出し側のHTMLに記述する。

```
・・・
<app-sample #sampleDialog></app-sample>
・・・
```

2. 呼び出し側のTypescript
  ダイアログComponentを宣言し、ダイアログ側のopen関数を呼び出す

```
@ViewChild("sampleDialog") sampleComponent: SampleComponent;
・・・
click(): void { //ダイアログを表示するボタンのクリック処理
  this.sampleComponent.open();
}
・・・
```

3. ダイアログ側のHTML
```
<div class="modal fade" bsModal #sampleModal="bs-modal" tabindex="-1" [config]="{backdrop: 'static'}">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-body">
     ・・・
      </div>
    </div>
  </div>
</div>
```
このままでは自動的に余白ができてしまう。もし余白をなくすのであれば
```
<div class="modal-body" style="padding:0px;">
```
とする

4. ダイアログ側のTypescript
  ModalDirectiveを宣言し、それを用いて表示/非表示を行う
```
@ViewChild("sampleModal") modalRef: ModalDirective;
・・・
open(): void {
  this.modalRef.show();
}

onClickClose(): void {
  this.modalRef.hide();
}
・・・
```
PowerApps dropdown連動表示の実装

# 要望
カテゴリーとサブカテゴリーのdropdownがあります。
カテゴリーを選択すると、サブカテゴリーの項目を絞り込み、選択された項目をクリアします。

# 実装
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/368087/d8f7a713-6f0a-81a7-dd90-9ebd829909b6.png)

|項目 |プロパティ  |式  |
|---|---|---|
| |OnStart  |Set(changeFlg,false);  |
|SharepointIntegration  |OnNew  |Set(changeFlg,false); |
|SharepointIntegration  |OnView  |Set(changeFlg,false); |
| |  |Set(selectedLoopupItem,LookUp(リスト名,ID=SharepointIntegration.SelectedListItemID));  |
|SharepointIntegration  |OnEdit  |Set(changeFlg,false); |
| |  |Set(selectedLoopupItem,LookUp(リスト名,ID=SharepointIntegration.SelectedListItemID));  |


|項目 |プロパティ  |式  |
|---|---|---|
| カテゴリー|OnChange  |If(changeFlg=false && DataCardValue1.Selected.Value=selectedLoopupItem.'フィールド名'.Value,"",Reset(DataCardValue2);Set(changeFlg,true););
|サブカテゴリー |DefaultSelecteditems  |If(changeFlg=false ,Blank(),Parent.Default)  |
| |Items  |If(!IsBlank(DataCardValue1.Selected),Filter(リスト名,Name=DataCardValue1.Selected.Value))  |
| |DisplayFields  |["Title"]  |
| |Reset  |true  |
| |Update  |{Id:DataCardValue2.Selected.Id,Value:DataCardValue2.Selected.タイトル}
  |

# 参考サイト
https://qiita.com/yamad365/items/18d50ab976d4ede96d13
[AIX] ユーザ定義パスワードポリシー(pwdchecksの使用例)

AIXのデフォルトの方式の他に、ユーザ定義のパスワードポリシーを設定することが出来ます。
### 参考資料:
chuser コマンド
https://www.ibm.com/docs/ja/aix/7.3?topic=c-chuser-command
New AIX Password Restrictions introduced in AIX 6.1 and 7.1
https://www.ibm.com/support/pages/new-aix-password-restrictions-introduced-aix-61-and-71
pwdrestrict_method サブルーチン
https://www.ibm.com/docs/ja/aix/7.3?topic=p-pwdrestrict-method-subroutine
-e オプション
https://www.ibm.com/docs/ja/openxl-c-and-cpp-aix/17.1.0?topic=co-e
### 手順:
##### 1. チェックロジックを作成
渡される引数の種類と型は固定。
Messageには、任意の出力メッセージを指定可能。
###### サンプル:
入力が"PASSWORD"であればture、それ以外はfalse
```
# cat checktest.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int checktest_sub(
    char *UserName,
    char *NewPassword,
    char *OldPassword,
    char **Message
){
    *Message = (char *)malloc (100*sizeof(char));
    if(strncmp("PASSWORD", NewPassword, strlen("PASSWORD")) == 0 ){
        strcpy(*Message, "test success message\n");
        return(0);
    }else{
        strcpy(*Message, "test fail message\n");
        return(1);
    }
}
```
###### 注意点:
・function名には"main"以外の名前を使用
・Message変数は必ずmalloc()で領域を確保
##### 2. エントリーポイントを指定してコンパイル
1. のチェックロジックで作成したfunction名(今回はchecktest_sub)をエントリーポイントとして指定
例
```
# ibm-clang -e checktest_sub checktest.c -o checktest
```
##### 3. ユーザ属性に設定
pwdchecks属性に2.で作成したオブジェクトファイルを指定
例
```
# chuser pwdchecks=/work/checktest testuser
```
### 実行例:
```
# su - testuser
$ passwd
"testuser" のパスワード変更中
testuser の旧パスワード:
testuser の新パスワード: <== "PASSWORD"以外を入力
test fail message
testuser の新パスワード: <== "PASSWORD"を入力
test success message
もう一度、新パスワードを入力してください:
```
JavaScript頻出メソッド

# JavaScript頻出メソッド

## ・目的
記憶定着のため、頻出メソッドの用法をアウトプットする。

## ・今回の対象メソッド
#### 〇配列処理に使用するメソッド
filter/map/reduce
#### 〇オブジェクト処理に使用するメソッド
Object.keys/Object.values/Object.entries

## ・対象メソッドの用例
#### 〇filter
filterの引数にコールバック関数を渡し、コールバック関数で指定した条件を満たす対象配列の要素を格納した新しい配列を作成する。
```
    let menbar = [{Name: 'John', id: 25}, {Name: 'Jane', id: 30}, {id: 20}, {Name: 'Doe',id: 1}, {id: 22}]
    let unKnowns = menbar.filter(function (person) {
      if (!person.Name) { return true; }
    });
    console.log(unKnowns);
    // 表示データ　[ { id: 20 }, { id: 22 } ]
```

#### 〇map
mapの引数にコールバック関数を渡し、コールバック関数の処理を実行し新しい配列を作成する。
```
    let data = [
      { キー: '001', 注文番号: '001', 発注者コード: '001' },
      { キー: '002', 注文番号: '002', 発注者コード: '002' },
      { キー: '003', 注文番号: '003', 発注者コード: '003' }
    ];
    
    const itemData = data.map((key) => {
      return {
        キー: key.キー,
        注文番号: key.注文番号,
        発注者コード: key.発注者コード,
        価格: 1000,
        数量: 2,
    }
    })
  
    console.log(itemData);
   // 表示するデータ　[ { キー: '001', 注文番号: '001', 発注者コード: '001', 価格: 1000, 数量: 2 }, { キー: '002', 注文番号: '002', 発注者コード: '002', 価格: 1000, 数量: 2 }, { キー: '003', 注文番号: '003', 発注者コード: '003', 価格: 1000, 数量: 2 } ]
```

#### 〇reduce
reduceの引数にコールバック関数を渡し、コールバック関数の処理を対象配列の要素に対して実行し、単一の値を生産する。
```
　let data = [
　　{ id: '001', 注文番号: '100'},
　　{ id: '002', 注文番号: '200' },
　　{ id: '003', 注文番号: '300' }
    ];
  // 取得したいデータのidリスト作成
  const idList = await data.reduce((list, val) => {
    list.push(sanitize(val.id));
    return list;
  }, []);

  console.log(idList);
  // 表示データ　[ '001', '002', '003' ]
```

#### 〇Object.keys
対象オブジェクト内のプロパティのキーを格納した配列を作成する。
```
 let mailData = {001 : {注文数量:1, 商品名:"商品A", 商品価格:1000}},{002 : {注文数量:2, 商品名:"商品B", 商品価格:2000 }};

 // 送信するデータがある場合にメール送信
  if (Object.keys(mailData).length > 0) {
    await send_mail(mailData, user);
  }
  console.log(Object.keys(mailData));
  // 表示データ　[001, 002]
```

#### 〇Object.values
対象オブジェクト内のプロパティの値を格納した配列を作成する。
```
 let itemData = {001 : {注文数量:1, 商品名:"商品A", 商品価格:1000}},{002 : {注文数量:2, 商品名:"商品B", 商品価格:2000 }};

 // 登録データが存在する場合、商品データ登録
  if (Object.values(itemData).length > 0) {
    await registr_data(itemData, user);
  }
  console.log(Object.values(itemData));
  // 表示データ　[{商品名:商品A, 商品価格:1000, 注文数量:1}, {商品名:商品B, 商品価格:2000, 注文数量:2}]
```


#### 〇Object.entries
対象オブジェクト内のプロパティを格納した配列を作成する。
```
 let itemData = {001 : {注文数量:1, 商品名:"商品A", 商品価格:1000}},{002 : {注文数量:2, 商品名:"商品B", 商品価格:2000 }};

 // 登録データが存在する場合、商品データ登録
  if (Object.entries(itemData).length > 0) {
    await registr_data(itemData, user);
  }

  console.log(Object.entries(mailData));
  // 表示データ　[ [ '001', { 注文数量: 1, 商品名: '商品A', 商品価格: 1000 } ], [ '002', { 注文数量: 2, 商品名: '商品B', 商品価格: 2000 } ] ]
```
CloudFrontを利用していてDNS切り替えをしても狙った所にアクセスできない時の対応

# はじめに
ドキュメントを読めば、きちんと書いてありますが逆引きで事象から必要となる対応、チェックすべき所はコレだ！ってのは中々ないとの、自分がハマったことなのでメモ書きします。

# 大前提
社名は出しませんがCRMサービス（AWSを利用してる他社サービス）から自社のCloudFrontに移行しようとした時に、DNSレベルでは切り替わってるハズなのに、CloudFrontを通過すると、昔のサイトに行ってしまうという事象が発生しました。

# 原因

https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/CNAMEs.html

ここにバッチリ記述されています。

> **重複する代替ドメイン名**
AWS アカウントが他の CloudFront ディストリビューションを所有している場合でも、同じ代替ドメイン名が別のディストリ CloudFront ビューションに既に存在する場合、代替ドメイン名をディストリビューションに追加することはできません。
>
> ただし、*.example.com のようなワイルドカード付きの代替ドメイン名を追加できます。これには、www.example.com のような非ワイルドカードの代替ドメイン名を含む (つまり重複している) が含まれます。2 つのディストリビューションで代替ドメイン名が重複している場合、 は、DNS レコードが指すディストリビューションに関係なく、より具体的な名前が一致するディストリビューションにリクエスト CloudFront を送信します。例えば、marketing.domain.com は *.domain.com より具体的です。

# 状況
上記の例に当てはめると、CRMサービス（AWSを利用してる他社サービス）でmarketing.domain.com（具体的ドメイン）、自社側CloudFrontで*.domain.comを、CloudFrontのCNAMEに登録しており、DNSレベルでは、自社側CloudFrontを向いてるのに、CloudFrontのCNAMEの登録状況によって、CRMサービス（AWSを利用してる他社サービス）の方に転送されていたという事でした。

DNSより、**CloudFrontのCNAMEの登録状況の方が優先される**というのは、結構ポイントです。

# AWSの相談・お困りごとありましたら、、、

AWSの活用方法や、お困りごとの相談、随時、お仕事の受付しております。
AWSのLambda開発関連で、ライトな開発や、ちょっと、こんな事を自動化したい！等も、お気軽に問い合わせください。

https://www.cs-cloud-aid.com/
SageMaker Studioでカスタムイメージを使用する

# はじめに

Amazon SageMaker Studioにカスタムイメージを適用する際に苦労したので備忘録です。


# Cloud9のセットアップ
今回はCloud9を使用します。ローカルにAWS CLI環境が構築されている場合はそちらでも構いません。

### 環境を作成
1. コンソールから [Create environment] をクリック
2. [Additional instance types]からinstance typeをt2-mediumに変更
※後のイメージ作成の際にt2-microだとエラーになるため
3. その他の設定は任意で[Create]をクリック

### ストレージサイズを変更

デフォルトの5GBだとイメージ作成に足りないため、拡張します。

1. Cloud9が動いているEC2を停止
2. アタッチされているEBSのSizeを増やします。とりあえず30GiBくらい。
※増やすことはできるが、後から減らすことができない。
![EBSVolume.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2986680/48432608-ecc7-feda-242a-03ce032208dd.png)
3. 再度Cloud9を起動


# カスタムイメージの作成

イメージの作成は以下を参考にしてます。
[AWS 公式ドキュメント - カスタムイメージへのアクセス権をユーザーに提供する - ](https://docs.aws.amazon.com/ja_jp/sagemaker/latest/dg/studio-updated-jl-provide-users-with-images.html)


手順をまとめて自動化した [リポジトリ](https://github.com/ka70/sagemaker-custom-image-template/tree/main)を作成しました。一通りのデプロイを試すにはこちらを使用すると良いです。

### リポジトリをクローン
```bash 
git clone https://github.com/ka70/sagemaker-custom-image-template.git
```
```
cd sagemaker-custom-image-template
```
カスタムイメージはECRにイメージを保存してSageMakerで使用します。
image_push.shでリポジトリの作成、イメージの作成、プッシュを行います。

### 各種設定
image_push.shを開いて、変数を設定します。
```
REPOSITORY_NAME="smstudio-custom"
ACCOUNT_ID=<ACCOUNT ID>
REGION="ap-northeast-1"
TAG_NAME="latest"
```
requirements.txtを開いて必要なライブラリを追加します。

### 実行
```
chmod +x push_image.sh
```
```
./push_image.sh 
```
ECRにイメージが登録されているか確認してください。

# イメージをSageMakerに登録
コンソールからカスタムイメージをSageMakerに登録します。
基本的に公式ドキュメントのやり方に沿って行います。
>1. SageMaker コンソールを開きます。
>2. 管理者設定 で、ドメイン を選択します。
>3. ドメイン のリストから、ドメインを選択します。
>4. 環境 タブを開きます。
>5. 個人用 Studio アプリのカスタムイメージ で、イメージのアタッチ を選択します。
>6. イメージソースを指定します。
>7. [次へ] を選択します。
>8. [送信] を選択します。

注意点は以下です。
- 6でアタッチするイメージは作成したURIを使用
![attach_image.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2986680/89d70a85-5b72-85db-aecf-5a121a2b09ed.png)


- IAMロールはAmazonSageMakerFullAccessがついているものを使用


- "8. [送信] を選択します。"の前にimage typeで使用するapplication typeをクリックしておく
![image_type.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2986680/f0d9118b-dddd-75a6-eb78-072c0b32d1cc.png)

# Spaceでカスタムイメージを使用する
SageMaker Studioを起動します。spaceを起動する際に作成したカスタムイメージを選択します。無事起動できれば完了です。Congratulation !!

**※カスタムイメージが起動できない事象がありました。**
[SageMaker Studioでカスタムイメージが起動しない](https://qiita.com/unpipipi/items/a4c0f4f34becb677c521)

# もっと頑張りたい方へ


### Dockerfile
私が作成したDockerfileでは雑にpipでインストールしています。
厳密にパッケージ管理をしたい方は、必要に応じてcondaやその他のパッケージ管理システムに書き換えてください。

また、Dockerfileの仕様例としてはAmazon Linux 2 イメージとAmazon SageMaker ディストリビューションイメージの2つがあります。([AWS 公式ドキュメント - カスタムイメージへのアクセス権をユーザーに提供する - ](https://docs.aws.amazon.com/ja_jp/sagemaker/latest/dg/studio-updated-jl-provide-users-with-images.html))SageMaker ディストリビューションイメージは機械学習やデータサイエンスに使用するパッケージがあらかじめインストールされているため、追加の手間が少ないです。今回もSageMaker ディストリビューションイメージを使用しています。

一方で、一からカスタムしたいという場合はAmazon Linux 2 イメージを使用するといいでしょう。

Linuxディストリビューションについても以下の違いがあるそうです。
・Amazon Linux 2 テンプレート: Amazon Linux
・SageMaker ディストリビューションイメージテンプレート: Ubuntu
Next14のサーバーサイドコンポーネントでURLパラメータを取得する方法

# はじめに
Next14で開発をしているときにURLパラメータを取得したかったのですが、検索をしてもフック(use~~)を使うものが多く、クライアントコンポーネントだと自分には都合がよくなかったので別の方法を紹介します。

# 問題
フックを利用する( == トップレベルに"use client"と書く )とクライアントコンポーネントになるが、それを避けたい。

# 解決策
以下のようにしてURLパラメータ(パスとクエリの両方)を取得することが可能です。
```tsx:page.tsx
import { Sidebar } from "../components/layout/Sidebar";
import { Card } from "../components/ui/Card";
import { getBlogs } from "../lib/getBlogs";

export default async function SearchPage(props) {
  const {params, searchParams } = props;
  return (
    // 省略
  );
}
```

- URLパスパラメータを取得したい場合
(page.tsxの属するディレクトリが <font color="red">**[id]**</font> のとき)
    ```ts
    params.id
    ```

- URLクエリパラメータを取得したい場合(urlに?q=値)
    ```ts
    searchParams.q
    ```


# 終わりに
このpropsのことは少し前にたまたま発見していたので正直ラッキーでした。公式にも記載されてはいたので載せておきます(検索にヒットしなかった泣)。
検索の仕方がまだまだなのかなぁと思います。

# 参考

https://nextjs.org/docs/app/api-reference/file-conventions/page

# ✨About Me✨
友達になってください！！
- X(Twitter)

https://twitter.com/shunii_hack
StepFunctionsでいろいろ詰まったこともあったのでまとめておく

## 前提（困ったこと）
プロダクト開発でAWSのサービスを中心に組み上げていく中で、

・API Gateway
・StepFunctions
・Lambda

の3つを使うことになったが、

API Gateway + StepFunctions
と
API Gateway + Lambda
で微妙にcontextの内容が違ったので難儀したケースがあった。

## 使用サービス
・Lambda
・StepFunctions
・API Gateway
・Keycloak（AWS外）

## どうしてこうなった
最初はLambda中心に開発しており、StepFunctionsもいつかは使おうと考えてはいつつも後回しにしていた。
ある程度落ち着いたタイミングで、StepFunctionsを使ってこれまで作ったLambdaを組み合わせて実装を進めていたが、想定していた挙動にならない。

具体的にはAPI GatewayのAuthorizerにLambdaを使って、そのLambda内で外部のKeycloakを呼んでcontextのauthorizerに含めるという仕組みにしていたのだが、これをStepFunctionsに渡るとauthorizerの内容が消えてしまうというものだった。

~~~
  "requestContext": {
    "context": "{resourceId=4blf96, authorizer=, resourcePath=/xxxxx/xxxxx, httpMethod=POST, extendedRequestId=xxxxxxx, requestTime=07/Feb/2024:03:32:07 +0000, path=/xxxxx/xxxxx, protocol=HTTP/1.1, requestOverride=,}",
~~~
（authorizerの値に何も入らない）

そもそもStepFunctionsはcontextは取りづらい仕様（取ることを想定してない？）みたいだったので、いくつかの制約があるのは理解していた。ただ、カスタムしたcontextが完全に消されるとは思っていなかった。

## どう対処したか
API Gatewayからcontextのauthorizerが取れないなら、そもそも取れるLambdaで取った方が速い。

ということで
~~~
API Gateway
> コントロール用Lambda
> boto3でStepFunctions呼び出し
> 実際に動かしたいLambda（StepFunctionsで呼ばれる）
~~~
に変更し、StepFunctionsの引数にauthorizerを編集して渡すことにした。

Lambdaのコードに書くと以下のようになる。
~~~
    client = boto3.client('stepfunctions')
    response = client.start_execution(
        stateMachineArn = <実行するStepFunctionsのARN>,
        input = json.dumps(input_json)  # 入力データ
    )
~~~
input_jsonにはLambdaのcontextに含まれるauthorizerを編集して設定。
引数のinputには文字列を渡す必要があるのでjson.dumpsを挟む。
StepFunctionsのARNはSAMのtemplate.yamlに書いてあるのでそこから取得。

## 振り返り
boto3からのStepFunctionsの実行自体は通常の仕様としては問題ないが、果たしてこういう実装でいいのかというものは残る。

当初はStepFunctionsを使わない想定でLambdaを組んでいたので、既存資産の活用（という名の手抜き）をうまくやるには結果としてこの方法になった。

とはいえStepFunctionsを最初から使う想定であればこのような実装にはなっていないので、AWSのそれぞれのサービスの良さはちゃんと踏まえた上で設計をすべき。

でも「どうしてもトンチを効かせて、StepFunctionsをうまく使いたいのだ」みたいな場合には、少なからず役に立ってもらいたいなとは思う。

あとboto3は便利。便利だけど、使いすぎ注意というのもあるかも（コードが煩雑になる）。
ログイン後ページ直行を実装【Laravel】

# はじめに
未ログインの状態で、ログイン後のページのURLを踏むと、ログイン後にトップページに遷移するようになってしまっていたため、ログイン後に該当のページに遷移するように実装いたしました。

# 実装したコード

```php: App/Http/Controllers/Auth/LoginController.php
    public function showLoginForm()
    {
        if (empty(session('url.intended'))) { // この部分を追加
            session(['url.intended' => route('index')]);
        }
        return view('auth.login');
    }
```

```php: App/Http/Middleware/Authenticate.php
   protected function redirectTo($request)
    {
        if(!$request->expectsJson()) {
            $check = false;
            $url = url()->current();
            $whiteList = [
                // 名前付きルートを記述
            ];
            
            // ルートが存在しているかどうか確認
            foreach($whiteList as $targetname){
                $routeURL = route($targetname);
                $exists = mb_strpos($url,$routeURL);
                if($exists !== false){
                    $check = true;
                    break;
                }
            }

            // ルートが存在しており、ホワイトリスト内のルートであれば、ログイン後ページ直行
            if($check){
                session(['url.intended' => url()->current()]);
            }else{
                session(['url.intended' => route('index')]);
            }

            return route('login');
        }
    }
```
macでbashを使ったまま下記のメッセージを出さない方法  The default interactive shell is now zsh. To update your account to use zsh, please run `chsh -s /bin/zsh`. For more details, please visit https://support.apple.com/kb/HT208050.

# macでbashを使うと出てくる`zsh`使えと催促してくるメッセージを表示させない方法

下記のメッセージが出てくる、お馴染みである。
これを出さない方法を記載します。

```
The default interactive shell is now zsh. To update your account to use zsh, please run `chsh -s /bin/zsh`. For more details, please visit https://support.apple.com/kb/HT208050.
```

## 解決方法

`~/.bash_profile`に下記を追加
```bash
 export BASH_SILENCE_DEPRECATION_WARNING=1
```

下記を実行し、設定を反映させます。

```bash
source ~/.bash_profile
```

以上
ブックデザインについて学んだこと3

知識ゼロから本を１冊作ることになりました。
私が本を作るために学んだことを書いていきます。

前回は、一つの原稿が書籍となり、知らない誰かが手にして読むという過程から湧いた疑問「本のカバーデザインや本文レイアウトで大切なこと」について考えました。
その結果、本のジャンルによって、本のレイアウトの中で配慮すべきポイントは違うことが分かりました。今回から実際の依頼内容をもとに具体的にジャンルやブックデザインのコンセプトを考えていきます。
特に、コンセプトは書籍を作る上で関わる人とも共通した認識を持つことが大切になるので、この辺りも意識して、まとめます。

## 実際の依頼内容をもとに整理する

今回の依頼は、詩集です。ジャンルは文芸。
詩集と言われると、谷川俊太郎さんの『二十億光年の孤独』など思い浮かべるかもしれません。

今回は、フランスの詩人　アルチュール・ランボーの自由訳した詩集を制作します。
その前に、ランボーがどんな詩人だったのか？
新潮社に彼の短い生涯と詩人としての人柄のわかるプロフィールがあります

https://www.shinchosha.co.jp/writer/448/

ランボーが活躍した時代は、ゴッホやゴーギャンが活躍した時代と重なります。
また日本では、ランボーの詩集を堀口大學や中原中也など複数の作家が翻訳をしています。
岩波書店のサイトによると中原中也は短い生涯の間に３冊も翻訳詩集を出しており、ランボーの影響強く受けた詩人の1人です。

https://www.iwanami.co.jp/book/b249367.html

今回制作する詩集について依頼内容をもとに情報を収集してみると
翻訳する詩人について、そして日本語に翻訳した人、活躍した時代などが把握できました。

### ジャンルの特性から言えること
文芸書の特性を踏まえて、書体や構成、レイアウトを考える必要はあります。今回は翻訳対象の詩人、翻訳方法に特徴があるので、ブックデザインを考える上ではここも大きな要素になります。

### コンセプトについて考える
本の制作をする上でコンセプトをしっかり決める意味は二つあります
- デザインの方向性を決め、本全体を統一したものにする
- 制作に関わる人の考え、意図をできる限り一致させる

このことを踏まえて、コンセプトを決めるために考えた項目は以下の通りです。

1\. 本の目的
2\. ターゲット層
3\. 読者に伝えたいメッセージや主張は何か
4\. メッセージをどんなデザインで可視化するか
5\. 装丁に求めるポイント
6\. 本全体の構成において重視したいこと
7\. 世界観やテーマ
8\. ブランディング


## 　次回
### コンセプトをもとに考えたテーマ、デザインについて
次回からは、制作役割や作業の流れを記載していきます
Create使ってみた

## はじめに
　Webサイトを簡単に作れると話題のcreateを使ってみました。
  こちらを参考にしています→　[詳しい記事](https://note.com/chaen_channel/n/ndd2bd6edb8d4#61f9d83b-7c6e-4749-bdd7-2e682d28ea84)

## 使ってみた
早速ですが、適当に作ってみました。
細かい使い方は[詳しい記事](https://note.com/chaen_channel/n/ndd2bd6edb8d4#61f9d83b-7c6e-4749-bdd7-2e682d28ea84)のほうを参考にしてもらって、下のような画面で右側に命令を書くとウェブサイトを作ってくれます。
![スクリーンショット (63).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3680875/183ae241-41c4-c07e-8f33-a6f06f85fc81.png)
そして、赤丸で囲ってあるDemoに切り替えると、実際に触って動きを確かめられます。
また、赤丸２つ目のAdd-onsから、ChatGPTやWeb Scraperなどの機能を加えられるようです。

今回は短いですが、以上です。




```ruby
```
学び始めて1年

とあるゲーム専門学校に入って一年が経ちこれから２年生だ。まずは今のスキルとこれからの目標をまとめていく。
まず今の実力ですが、C++とC#を学んだ。C++は軽く理解できたけどC#の方がまだまだ不安でたまらない。わからないところは周りに聞くがその言っていることが出来ないことが稀にある。アルゴリズムやデザインパターンについては苦手である。他の科目として数学などの計算は得意であるが英語が苦手だ。
これからの目標としては、C++とC#の知識を固めること。C++は多くの制作で使用するから完璧にしていきたい。C#も強くしていきたいが、スマホアプリを制作したいと思っているので、Javaなども視野に入れていきたい。他の科目にも力を入れないようにする。
最後にこれから新たにゲームの方の制作状況も上げつつ授業で学んだことなどまとめていきたい。応援の方お願いします。
ZED SDK の実行時のlogファイルを出力させる

# 想定する読者
stereolabsのzed2, zed mini, zed x などのステレオカメラの利用者
いまどきのステレオカメラは何ができるのかを知りたい人

# 前提
ZED SDK 4.0
Ubuntu 20.04
ZED2i
Python 版のAPI

## 解決方法
```python:
init = sl.InitParameters()
init.sdk_verbose_log_file = "zed-sed.log"
init.sdk_verbose = 1

status = zed.open(init)
```
【flutter】initStateを使ってウィジェットを初期化したい

こんにちは！
今回はinitStateを使ってWidgetを初期化する方法について紹介いたします！
最後まで読んでいただけたら、嬉しいです！

## 1. initStateとは？
initStateは、対応するオブジェクトが最初に作成されたとき実行されます。また、Widgetの初期化やセットアップに関連されるものであり、通常は一度だけ実行されます。

## 2. initStateの使い方
initStateは、Widgetのライフサイクルで最初に呼び出されるため、通常はWidgetの初期化に関連する作業を行います。以下は、initStateを使用してWidgetを初期化する基本的な例です。
```php
class MyWidget extends StatefulWidget {
  @override
  _MyWidgetState createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget> {
  @override
  void initState() {
    super.initState();
    // ウィジェットの初期化処理をここに記述します
    // 例: 変数の初期化など
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      // ウィジェットのビルド処理
    );
  }
}

```

## 3. 実際のアプリケーションでの使用例
### ・ データのロード
ウィジェットが表示される前に、データベースやAPIから必要なデータをロードすることができます。

### ・コントローラの初期化
テキストエディターやアニメーションコントローラーなどのコントローラを初期化する場合に便利です。

### ・ユーザーの登録
ウィジェットが表示される前に、ストリームやイベントのユーザーを登録することができます

## 4.終わりに
今回の記事は以上になります！
今回も最後まで見ていただきありがとうございました！
では、また次の記事で〜！
ゼロ知識証明フレームワーク

![1710620007329.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618478/df7b4082-275f-802f-bd20-34796ef2d88a.png)


1年半に渡り携わってきたDARAPA（米国国防高等研究計画局）が胴元となった[SIEVE（Securing Information for Encrypted Verification and Evaluation)プロジェクト](https://www.darpa.mil/program/securing-information-for-encrypted-verification-and-evaluation)が幕を閉じました。



このSIEVEはゼロ知識証明のフレームワークとなるもので、端的に言えば、証拠を公表せずに証明を実施できるという代物です。私自身は、プロジェクト内で作られるフレームワークの応用面の開発に重点を置いて携わりました。

例えば、アップルはiCloud上の児童ポルノ画像への規制策を発表しており（現状延期されているようですが）、NCMEC（National Center for Missing & Exploited Children）と呼ばれる児童保護団体が提供する規制対象の画像に一致・類似する画像をiCloudに保有していた場合、摘発の対象になるというものです。

摘発時には、その画像がNCMECや法的機関に公表されることになるため、ある意味個人情報の漏洩に繋がります。正しい摘発なら良いのですが、エラーであったり、恣意的な間違いがあることも可能性としては否みようがありません。そもそも本当にNCMECから来た画像だけを対象に、iCloud上で照合しているのかすら不明なわけです。そこで、今回SIEVEプロジェクトで開発されたフレームワークを使えば、アップル側のサーバーでNCMECの画像のみを使って正しく照合がなされたということを、NCMECの画像もiCloud上の画像も誰にも見せることなく、その照合過程が正しいものであったと証明することが可能です。

同様に、裁判での証拠書類の検証や著作権侵害なども著作物や証拠書類を開示することなく、その真偽を証明することができ、実社会における応用範囲の裾野の広いフレームワークとなっています。

**ゼロ知識証明はどのような仕組みか**

ゼロ知識証明自体は名前からして難解ですが、簡素化すれば容易に理解できます。

昔どこかのレストランで食べた忘れられない味（例えばオニオンスープ）をイメージしてみてください。
誰が作ったのか、どんな材料が入っていたのか、どーしても思い出すことができませんが、是非ともまた食べたい。

そんなあなたの目の前に「あの時作ってたのは私だ」と名乗り出るシェフが現れます。自信満々の様子ですが、レシピは極秘情報だと言って聞きません。

さて、どうしましょう。このシェフを信じたくても信じる根拠がありません。

もし仮に、必要な材料をあなたには見せないものの、あなたのよく知る家のキッチンでこのシェフがあの味を再現できたなら、皆さんはこのシェフを信じざるを得ないのではないでしょうか。

シェフが証明者であり、あなたが検証人で、材料（インプット）は秘密ですが、あなたのキッチンという環境であなたの知る機材を使って（調理過程が既知）、「あの味」（アウトプット）を完成させたわけです。

専門的なことはさておき、これがゼロ知識証明システムの簡単なイメージで、これをプログラムとして実装します。この[GitHub Repo](https://github.com/hicsail/zk-Oracles)にて、実際に作成したPythonプログラムを公開していますので、ご興味ある方はご参考下さい。


**あとがき**

この最先端の分野におけるソフトウェア開発の進化する需要に対応し、プロジェクト完遂のためたくさんの読書とリサーチをしましたが、その中で主任教授である[Mayank Varia教授](https://www.bu.edu/cs/profiles/mayank-varia/)（およびその博士課程学生の[Julie Ha氏](https://www.hajulie.com/)）や[picozk](https://github.com/uvm-plaid/picozk)の作者である [Joseph Near教授](https://www.uvm.edu/~jnear/)から貴重なサポートを受けました（picozkは我々の作成したアプリからIR（中間）ファイルを生成するのに必要なLibrary）。また、生成したIRファイルを用いて証明プロセスを実装するのに不可欠だったバックエンドやテストシステムの提供をしてくれた[GALOIS社](https://www.linkedin.com/company/galois-inc-/)、[Stealth社](https://www.linkedin.com/company/stealth-software-technologies-inc/)、[MIT Lincoln Lab](https://www.linkedin.com/company/mit-lincoln-laboratory/)にもこの場を借りて感謝の意を表したいと思います。
OOC2024に行ってみて

# はじめに
OOC2024(Object Oriented Conference)に初参加してきました。
このような講習を受ける場というのには初めての参加ですが、その感想を初心者ながらまとめていきたいと思います。

# [現実世界の事象から学ぶSOLID原則](https://speakerdeck.com/h0r15h0/xian-shi-shi-jie-noshi-xiang-karaxue-busolidyuan-ze?slide=3)(ほりしょーさん)

ほりしょーさんの講義は、初心者の私にもわかりやすくSOLID原則を説明してくださってとても助かりました、とくに、`現実世界の事象から学ぶSOLID原則`というタイトルに基づいた説明で、説明自体も農場を基準とした説明でとてもわかりやすかったです。
ただ、SOLID原則の最後まで詳しく聞けなかったのは少し残念でした。
あと一時間続いていても退屈しないような内容だったため、その分貴重なお話をお聞きできなかったのは残念でした。

# [クソコード動画『カプセル化 Mk-II』で考える、上手くカプセル化できない理由](https://speakerdeck.com/minodriven/encapsulation2)(ミノ駆動さん)

ミノ駆動さんの説明はまず、[カプセル化 Mk-II](https://twitter.com/MinoDriven/status/1771763728234537310?t=heyogTKNO4grefSmVawecg&s=19)
の動画を披露してくださっていて、その動画の問題について話をなさってくださいました。
カプセル化というのも、単純にデータクラスにgetterをつければ良いという訳ではなく、オブジェクト指向よくできたな、と思っていても壊されてしまう原因について話してくださいました。
主な原因としては、状況により必要なデータ、不必要なデータが違うということだったり、予期しない変更が生じる、変化に弱いなどを挙げていました。
その中でもいちばん大事なのは`目的`であり、その目的のあり方について話していました。
私自身も、今後オブジェクト構成を考えるときには目的と手順の関係性を大事にしようと思いました。


# [オブジェクト指向宗教史](https://speakerdeck.com/tanakahisateru/obuziekutozhi-xiang-zong-jiao-shi)(田中ひさてるさん)
田中ひさてるさんの講習自体はオンラインでも見たことありましたが、面白おかしく、楽しく説明してくださるので講義自体も退屈せず、今回は宗教に基づいた講習でしたが他のパターンもあるなら是非聞いてみたいなと思いました。


# [せっかくモデル図描くのなら、嬉しいことが多い方がいいよね！](https://speakerdeck.com/kuboaki/setukakumoderutu-miao-kunonara-xi-siikotogaduo-ifang-gaiiyone)(久保秋 真さん)
久保秋さんの講義はタイトルと少し違って、モデル図の歴史のようなことを話されていました。
どのようなことが嬉しいのかというとお聞きしたかったので少し残念でしたが、歴史を知れたので良い勉強になったなと思いました。私自身もモデル図とまでは行きませんが図を書いてわかりやすく理解するようにしていることもあるので、是非astarさんのアプリも使用してみたいなと感じました。

# [設計の知識と技能で駆動するソフトウェア開発](https://speakerdeck.com/masuda220/software-development-driven-by-design-knowledge-and-skills)(増田 亭さん)
増田さんの講義では、難しい言葉が多く初心者の私には少し難しい講義でした。ですが、ポート&アダプタアーキテクチャの部分についての説明は図も着いていて説明もわかりやすかったため、私でも多少ですが理解できました。
もう少し勉強してまたこのスライドを見たらまた違う感想が浮かぶのだろうなと感じました。


# [オブジェクト指向は必要なのか](https://speakerdeck.com/kishida/is-object-oriented-needed)(きしだ なおきさん)
きしだなおきさんの講義は、実際のコードを用いて説明される描写が多く、理解もしやすかった印象です。中でも一番面白かったのが、ほとんどのオブジェクト指向がソフトウェア工学でできているもの。という事実でした。
昔オブジェクト指向という言葉自体がすごい広まっていてホントはソフトウェア工学なのにその名前で本を出すと売れないから、オブジェクト指向という名前で売ってたといことに衝撃を受けました。
だからオブジェクト指向っていっても色々な考え方が存在するのかなと感じました。
他にもオブジェクト指向は継承プログラミングという話も他の人とは違った視点で話されていて聞いていて楽しかったです。

# まとめ
今回このようなオフラインのカンファレンスイベントに参加するのは初めてで、初心者の私にとっては難しいことばかりなのかなと思っていたのですが、実際に参加してみるとそうでもなく、もちろん難しい言葉や理解ができないことはありましたが、初心者にも優しめなイベントだなと感じました。
他にもイベントブースに行ってみたのですが、予想以上の賑やかさがあり、色々と参加して見たかったのですが混み合っていてあまり参加できませんでした。ですがForkwellさんのおみくじで大吉(amazonカード5000円分)が当たりました！！
こんなこともあったので講義以外にも楽しめる場があり充実した一日になりました。
次回は4年後かもしれないとクロージングで聞いたのですが、4年後の成長した自分でまた参加してみたいなと思いました！！
GitHub Actions イシュー、プルリク作成時にアサインを自動付与する

![ScreenShot 2024-03-11 0.02.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52879/79c4a29d-9aec-3ba3-1594-6f675f59377c.png)

## 概要

IssueやPull Requestの作成時にアサインを指定忘れることないでしょうか？
Assigneesが未指定の場合は作成した人がアサインされるようにする方法をご紹介します。

## Gitシリーズ記事まとめ

https://qiita.com/ucan-lab/items/33c63a402f533aa92f3e

### GitHub Reviewer と Assignees

https://docs.github.com/ja/issues/tracking-your-work-with-issues/assigning-issues-and-pull-requests-to-other-github-users

GitHubのIssueおよびPull Requestは `Assignees` を設定できます。
Pull Requestは `Reviewer` を設定できます。

Reviewerはコードをレビューして欲しい人を指定します。
必ずしもその領域の責任者やコミットのマージに責任を負う人ではありません。(今回のワークフローでは特に関係ないですね)

`Assignees` はPRの作成者や現在の担当者を意味したりしますが、プロジェクトのルール次第なところがあり厳密な定義はありません。

アサインの運用の一例をご紹介します。

1. PR作成時は `Assignees` に作成者をアサインする(ここを忘れ防止のため自動化してます)
2. レビュー依頼時は `Assignees` を外して空の状態にし、 `Reviewer` を指定する(複数人可)
3. レビューに着手する時は `Assignees` にレビュワーを設定してしてボールを持っていることを明確化します
4. レビューが終わったら `Approve` または `Request Changes` を送信し、 `Assignees` から自分を外してPR作成者へボールを返します
5. レビューで `Approve` 貰えたらPR作成者が責任を持ってマージします。 `Request Changes` の場合は 2〜4 を繰り返します

今までやってきたプロジェクトで、理に適ったアサイン運用をしていたものを参考にさせていただきました。
アサインの運用はプロジェクトによるため、1番のみで運用されていたり、マージ権限を持つ人が最終的なアサインとなる場合もあります。

後からPRを検索する時にアサインが設定されていると目的のPRを検索しやすくなるので、1番の運用をするだけでもオススメです。

## 利用ツール

https://github.com/technote-space/assign-author

便利なActionがすでにあったので使わせていただきます。

## 実装

### .github/workflows/assign-author.yaml

```yaml:.github/workflows/assign-author.yaml
name: Assign Author
on:
  issues:
    types: [opened]
  pull_request:
    types: [opened]
jobs:
  assign-author:
    if: ${{ ! contains(fromJson('["renovate[bot]", "dependabot[bot]"]'), github.actor) }}
    permissions:
      issues: write
      pull-requests: write
    runs-on: ubuntu-latest
    steps:
      - uses: technote-space/assign-author@v1
```

## 補足

Botが作成したものはスルーします。
`types: [opened]` なので作成時のみ実行されます。
`permissions` で書き込み権限を与えないとエラーになります。
片方だけで良い場合は、`on` と `permissions` で不要な方削除して使ってください。

## 業務改善度: ★★☆☆☆

星2つです。
地味に忘れることがあるので地味に嬉しい機能です。

なくて困る訳でも、あってめっちゃ嬉しい訳でもないですが、IssueやPR作成されるたびに活躍してくれる便利なワークフローです。

これはyamlファイルを1つ配置するだけで良いので導入しやすいです。

## 参考

https://docs.github.com/ja/actions

https://stackoverflow.com/questions/41087206/on-github-whats-the-difference-between-reviewer-and-assignee
条件に合う配列のみをプルダウンに表示する方法

Railsで関連付けられたレコードの一部だけをフォームのセレクトボックスに表示する方法を紹介します。この例では、`Company` が複数の `Staff` を持ち、`Staff` は `Schedule` と関連付けられています。特定の日に勤務している（`at_work` カラムが `true`）スタッフのみをプルダウンに表示します。

## モデルの関連付け

まず、`Company` モデルと `Staff` モデル、`Schedule` モデルの間には以下のような関連付けが定義されているとします。

```ruby
class Company < ApplicationRecord
  has_many :staffs
end

class Staff < ApplicationRecord
  belongs_to :company
  has_many :schedules
end

class Schedule < ApplicationRecord
  belongs_to :staff
end
```

## Company モデルでのメソッド定義

特定の日に勤務しているスタッフを取得するために、`Company` モデルにメソッドを定義します。

```ruby
class Company < ApplicationRecord
  has_many :staffs

  # 勤務しているスタッフのみを取得するメソッド
  def working_staffs(date)
    staffs.joins(:schedules).where(schedules: { date: date, at_work: true })
  end
end
```

## コントローラーでのデータ取得

コントローラーでは、`@working_staffs` を設定して、ビューで使用できるようにします。

```ruby
class SchedulesController < ApplicationController
  def quota_index
    @reservation = Reservation.find(params[:reservation_id])
    @working_staffs = @company.working_staffs(@reservation.date)
  end
end
```

## ビューでのプルダウンの設定

ビューでは、`form_with` ヘルパーを使用してフォームを作成し、`collection_select` ヘルパーで `@working_staffs` をセレクトボックスに表示します。

```erb
<%= form_with model: some_model, local: true do |form| %>
  <%= form.collection_select :staff_id, @working_staffs, :id, :name, {include_blank: true}, {id: 'staff_select'} %>
<% end %>
```

これで、特定の日に勤務しているスタッフのみがプルダウンに表示されます。この方法はビューをシンプルに保ちつつ、必要なデータのみをユーザーに提示するために非常に効果的です。
M2 / M3 mac MySQLコンテナ問題【私の場合】

# はじめに


参考・詳細はこちら

https://zenn.dev/yuzunosk55/articles/bbadf17044812e

簡単に問題の概要を説明すると、
「M2macで`docker compose up`したタイミングですぐコンテナが落ちてしまう（`db-1 exited with code 139`が発生）」
です。

元記事は種々説明してくれてるので、「その中のこれでうまくいったよ」という記事です。
# 解決方法


**qemuではなくRosettaを使用する**

https://zenn.dev/yuzunosk55/articles/bbadf17044812e#8.-qemu%E3%81%A7%E3%81%AF%E3%81%AA%E3%81%8Frosetta%E3%82%92%E4%BD%BF%E3%81%86%E3%82%88%E3%81%86%E3%81%AB%E8%A8%AD%E5%AE%9A%E3%82%92%E5%A4%89%E6%9B%B4%E3%81%99%E3%82%8B

1. `git ps -a`で落ちたコンテナのIDを確認  
2. `git logs コンテナID`でログを確認  
すると、qemuが対応していない的なログ、その後セグメンテーションエラーによりコンテナがダウンのログが確認できました。
3. QemuからRosettaへの切り替え  
注意点として、（元記事にもあるように）Docker デスクトップからインストールするのはダメでした。
なので、先に手動でインストールしました。
その後チェックを入れ、左下の表示が黄色ではなく緑なら成功です。
`docker compose up`しましょう。

# おわりに

人によってエラーになったりならなかったりしてるようです。なんでだろう・・・
手元のM3mac airではエラーになりませんでした。

わかる方いたら教えてください。

次は何を書こうかしら・・・
displayの役割と要素の表示方式について

今回入社した際に、最初はフロントエンドのコーディングをするとのことだったため、よく使う「displayの使い方」を改めて勉強した内容をまとめます。

## displayとは？
displayとは、CSSのプロパティの1つで、要素の表示方式を制御します。主な値にはblock、inline、inline-block、flex、noneがあり、レイアウトの構造と見た目を調整できます。

![スクリーンショット 2024-04-02 9.16.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3670873/f4d8d81a-5b90-b7a9-9e14-3eaa8dc0fba2.png)
参照：[【CSS】displayの使い方を総まとめ！inlineやblockの違いは？](https://saruwakakun.com/html-css/basic/display#section1 "displayの使い方についての記事")

## デフォルトの値
displayはCSSで明示的に指定しなくても、タグを設定した時点でデフォルトの値が適応されています。

block・・p、div、ul、h1〜h6などのタグ
inline・・a、span、imgなどのタグ
inline-block・・デフォルト×
flex・・デフォルト×
none・・デフォルト×

## 「block」、 「inline」、 「inline-block」、「flex」の違い

並び方
「block」・・縦並び
「inline」「inline-block」・・横並び
「flex」・・縦横どちらも可能

幅と高さ
「block」「inline-block」「flex」・・指定可能
「inline」・・指定不可

余白
「block」「inline-block」「flex」・・上下左右ともに指定可能
「inline」・・横幅だけ指定可能

text-alignとvertical-align
「block」・・指定不可
「inline」「inline-block」・・指定可能
「flex」・・text-alignプロパティは、Flexboxの直接の子要素（フレックスアイテム）には影響しませんが、フレックスアイテム内のインラインコンテンツやテキストの水平方向の配置には使用できます。（ChatGPT参照）

※text-alignのイメージ
![スクリーンショット 2024-04-02 9.46.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3670873/a5e75fd0-ad34-d208-0969-4a987c555766.png)
参照：[【CSS】displayの使い方を総まとめ！inlineやblockの違いは？](https://saruwakakun.com/html-css/basic/display#section1 "displayの使い方についての記事")

※vertical-alignのイメージ
![スクリーンショット 2024-04-02 9.57.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3670873/774a14af-68ee-4260-3f8c-4fe45cf4ddb4.png)
参照：[【CSS】displayの使い方を総まとめ！inlineやblockの違いは？](https://saruwakakun.com/html-css/basic/display#section1 "displayの使い方についての記事")

## 「flex」の役割
ここまで見てきて「block」、 「inline」、 「inline-block」で一通りのことは再現できると思います。ではなぜ「flex」というものがあるのでしょうか？

ChatGPTで調べたところ下記の回答がありました。

>ChatGPT：
>Flexboxは、従来のblock、inline、inline-blockでは難しかったレイアウト課題に対応するために開発されました。レスポンシブデザインの容易化、要素の垂直中央揃え、スペースの均等分配、アイテムの順序変更、複数行フレックスアイテムの管理など、柔軟なレイアウトを簡単に実現できます。コードの簡素化と保守性の向上も大きな利点です。これにより、ウェブ開発者はより複雑なレイアウトを簡易かつ効率的に構築できるようになりました。

要するに従来のblock、inline、inline-blockを使ってデザインするより、「要素のレイアウトが格段にやりやすくなりました。」ということです。

実際にポートフォリオを作るときに調べていても、どのサイトもflexを使用している印象でした。
使っていてもシンプルでわかりやすく、直感的に使いやすい印象でした。

Flexboxの使い方は改めて投稿したいと思います。
→[display:flexの使い方](https://qiita.com/sinke_123/items/1c2765662e84c37e1562 "フレックスボックスの使い方についての記事")


## 参考文献
[【CSS】displayの使い方を総まとめ！inlineやblockの違いは？](https://saruwakakun.com/html-css/basic/display#section1 "displayの使い方についての記事")
[【初心者向け】フレックスボックスとは？display:flexの使い方（基礎編）](https://www.asobou.co.jp/blog/web/flex-box "フレックスボックスの使い方についての記事")
[vertical-align - CSS: カスケーディングスタイルシート | MDN](https://developer.mozilla.org/ja/docs/Web/CSS/vertical-align "displayの使い方についての記事")
ジュニアエンジニアに伝えたい！テスト仕様書の重要性

# ■ はじめに
　この記事を書こうと思ったきっかけは、テスト仕様書の重要性を再認識したことです。シニアエンジニアの方からテスト仕様書の書き方を学んだ際、テスト仕様書を軽視してはいけないということを痛感しました😇
 
　開発段階でエラーやバグをほとんど排除できていると思っていたため、テストは大体のことが確認できれば問題ないと思っていました。しかしながら、このような考えが大きな問題を引き起こす可能性があることを学びました。
 
　まだ実務経験が浅い私にとって、テスト仕様書は唯一会社に貢献できる業務だと学びました。プロジェクトに参加できないからこそ、テスト仕様書を通じて自分の価値を示したいと考えています。

# ■ テスト仕様書を作成する目的
　テスト仕様書は、どのようなテストを行ったのかをクライアントや第三者に伝える重要なドキュメントです。言い換えると、テスト仕様書に記載された項目は全てテストしたことを示し、記載されていない項目はテストを行っていないことを示します。

# ■ テスト仕様書を書く際の注意
　第三者が同様のテストを行っても同じ結果が得られるように、**具体性と端的さ**を心がけることが重要です。自分だけが理解できるような省略した記載は避け、できるだけ明確な記述を心がけましょう!
　
例えば、予約入力フォームの`予約する`ボタンを押すとページ遷移し、入力内容確認画面が表示されることについてテスト検証内容を記載してみます。

:::note alert
悪い例
操作：予約ボタン押下時
検証内容：入力内容確認画面に予約フォームで入力した内容が表示されること
:::
テスト項目は、どのような操作を行った結果どのような挙動が期待されるかを具体的に記述することがポイントです！
また、操作や検証内容を端的に記載することで、第三者が理解しやすくなります。


:::note info
良い例
操作：予約入力フォームの名前欄に山田太郎と入力の上、予約ボタン押下時
検証内容：入力内容確認画面の名前欄に山田太郎と表示されること
:::

# ■ テスト中の「ん？」は見逃さないで✋🏻
テスト中に**気になる点**や**疑問**があれば、すぐに開発者に確認することをオススメします！
テスト中に気付いた問題点を放置せず、積極的に開発者とコミュニケーションを取ることが重要です。テスト中に起きた問題を放置すると、後に**大きなエラー**や**バグ**が発生する可能性があります。
だからこそ、テスト仕様書を作成する際は、触ってないルート、通ってないルートがないようにテスト項目を作成することが重要です。

# ■ テスト仕様書を書く前に行うこと
　テストを行う前に、**気になる点**や**不明な点**を洗い出し、開発担当者に確認しておきましょう！また、アプリケーションの設計やFigmaのデザインを確認し、実際にローカル環境でアプリを操作してみることも重要です。そうすることで、テスト項目をより具体的に記述することができます。


# ■ 最後に
　テスト仕様書を作成し、その内容を元にテストを繰り返し行い、問題がなければリリースすることを学びました。**小さな怠り**や**抜け漏れ**が大きなエラーやバグを引き起こす可能性があることを認識し、テスト仕様書を丁寧に作成、かつテストを綿密に行うことの重要性を理解しました。

　もし、ジュニアエンジニアの方でテスト仕様書書くことが面倒だなと思う方がいらっしゃったら、テスト仕様書を書く目的や書く作業を行う中で気づくことがあるかもしれません。例えば、どのようにアプリが開発されているのかや、どのような仕組みなのかをより理解することができます。そのため、会社に貢献しつつ、**自身の成長**と**将来の開発活動に役立つ勉強**と捉えて取り組むことをオススメします✨
LTI対応の学習アプリケーション開発

# 概要
[日本1EdTech協会](https://www.1edtechjapan.org/ "日本1EdTech協会")では[1EdTech Consortium Inc.](https://www.1edtech.org/ "1EdTech Consortium Inc.") が策定している[LTI](https://www.1edtech.org/standards/lti "LTI")  (Learning Tools Interoperability)、[OneRoster](https://www.imsglobal.org/activity/onerosterlis "OneRoster")、[QTI](https://www.imsglobal.org/activity/qtiapip "QTI") (Question Test Interoperability)等の学習エコシステムを形成するための標準を国内に普及することを主なミッションとしています。
ここ数年、これらの標準を取り入れたMEXCBTや学習eポータル関連の実装が進み、多くのベンダーが開発に関与しています。日本1EdTech協会では、こうした開発に関与した技術者が得た知見をQiitaで公開することにしました。
まずLTI関連の4本の記事が投稿されたことから、これらの記事のまとめサイトとして投稿します。


# 投稿記事
### ① LTIのキャッチアップ一歩目のための概要と仕様書読み解きのガイド
https://qiita.com/kazuki_noritake/private/db69ef1aa8cec1d577af

LTIの理解やキャッチアップには一定のハードルがあり、その原因の一つとしてドキュメントが点群のように存在していることが挙げられます。そのため、この記事は新たにLTIに係る技術者を対象に、LTIのキャッチアップの一歩目を踏み出せるよう概要や仕様書の読み解き方のガイドを記載しています。

### ② LTIのおすすめ学習ステップ（初心者向け目次）
https://qiita.com/mkubo/private/d2cb2e9d2be603394f0c

このQiitaでは、LTIについて初学者の技術者が触りながら理解していくときのおすすめ学習ステップを記述しています。「そもそもLTIって何なの？」といった概念的なところは何となく理解したが動かした経験はない、という技術者を対象としています。大きく「触ってみる」パートと「仕様ドキュメントを読んで理解する」パートに分けて、それぞれこんなステップで学習を進めていくといったLearning Pathを記述しています。

### ③【LTI】Chrome拡張機能「LTI Debugger」のすすめ
https://qiita.com/Hiroki_Kobari/private/3e0cfcb1888deb55b2e7

本記事ではLTIを使った通信の内容を確認するためのツールの1つとして、Chromeの拡張機能「LTI Debugger」について紹介しています。この機能を追加することで通常のデベロッパーツールより通信内容の確認を簡単に行うことができるようになります。

### ④ LTI実装のテスト工程を経験して考えたこと
https://qiita.com/ryu-imamura_1EdTech-Japan/private/d27466da6ca3c1b9d5a1

LTIはシステム間連携のための技術であるため、システム単体でのテストは難しかったり、認証系なのでプログラム品質にはそれなりに気を使う必要があったりと、開発フローの中でもテスト工程は多くの開発工数を必要とします。この記事ではLTI開発時のテストフェーズに携わりそこで得られた知見をTIPSとしてまとめ、LTI対応のシステム開発におけるテスト工程とベストプラクティスについて記述しています。
journaldについて

## 環境
Ubuntu20.4

## はじめに

OSのログはjournaldとrsyslogdの両方で取得されます。ログを参照したい場合、どっちで見てもいいのですが、rsyslogdは古株でjournaldが新参者であることから、**journald**の方を見た方がいいでしょう。

rsyslogdは**SysVinit**の時代に採用していた仕組みでしたが、**systemd**が出てきてからjournaldが登場しました。

systemdが登場したのは、CentOSは7からで、Ubuntuは15.04からです。

## デーモンの確認

journaldのデーモンを確認しようとして、次のコマンドを実行しても出てきません。
```
$service --status-all | grep journald
```

次のコマンドを実行すると動いていることが分かります。
```
$systemctl status systemd-journald
```

journaldといった独立したデーモンとして存在しているのではなく、**systemd-journaldsystemd**のコンポーネントとして組み込まれているようです。systemdが起動すれば、journaldもバックで動作しているということです。

journaldのコンフィグファイルは下記になります。
```
/etc/systemd/journal.conf
```

中身を見ると全ての設定がコメントになっています。コメント値がデフォルト値として有効になっています。

## コンフィグの設定（その１）

次の設定を行うと、journaldのログは全てrsyslogdに転送されるようになります。つまり、journaldのログがrsyslogdでも見れるようになります。
```/etc/systemd/journal.conf
ForwardToSyslog=yes
```

## コンフィグの設定（その２）

journaldのログの保存場所を指定する設定です。autoになっていれば、保存場所は自動的に決定されます。**/var/log/journal**があれば、ここに保存し、なければ、**/run/log/journal**に保存されます。

両方のディレクトリが存在すれば、両方に保存されるということはありません。
```/etc/systemd/journal.conf
Strage=auto
```

/runは特殊なディレクトリです。次のコマンドを実行すると、/runのファイルシステムが**tmpfs**となっていることが確認できます。tmpfsは揮発性なメモリ上に作成されるファイルシステムです。OSがシャットダウンされると消えてしまいます。

つまり、/run/log/journalにログを保存すると、次回起動したときに、前回のログが消えてしまうことになります。ログを残しておきたい場合は、/var/log/journalに保存することになります。
```
$df -T
```

## コンフィグの設定（その３）

rsyslogdはlogrotateでログローテされますが、journaldにはログローテする仕組みがありません。では、ログがずっと肥大化し続けるのかといえば、そんなことはありません。次の設定でログの容量が一定の大きさになれば、古いログを削除してくれます。デフォルトでは空白になっています。デフォルトの場合、ディスク容量の10%に達したら、古いログを削除されるといった仕組みになっています。ただし、上限4GBという制限があります。10%で4GBであればディスク容量が40GB以上の場合は、4GB以上のログを貯めることはできないということになります。
```/etc/systemd/journal.conf
SystemMaxUse=
```
.gitignoreファイルの作成方法

# はじめに
.gitignoreファイルを手書きで作成したことがありましたが、さすがに面倒だったので簡単な作成方法についてまとめます。
ここではVisualStudioで開発するプロジェクトの.gitignoreファイルを作成してみます。

# .gitignoreファイルとは
具体的な作成方法の説明の前に.gitignoreファイルの説明をします。
.gitignoreファイルは、Gitにおいて追跡不要なファイルやディレクトリを指定するために使用されます。
このファイルにリストされた項目は、Gitの操作によって無視され、リポジトリにコミットされることはありません。
↓Gitで管理しているフォルダでよく見るやつですね。

![9b044e83-f7ad-f796-56b5-ad9651b608a5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3726673/262229a1-8797-4a7c-0d00-632061337a61.png)

例えば、以下の例ではビルド結果、Visual Studio の設定ファイル、NuGet パッケージのファイルやディレクトリがGitの追跡から除外されます。

```.gitignore
# ビルド結果
bin/
obj/

# Visual Studio の設定ファイル
.vs/

# NuGet パッケージ
*.nupkg
packages/
```

以降で作成方法を見ていきましょう。

# 作成方法1：GitHubで作成
プロジェクトの開始時にGitHubでリポジトリを作成すると思いますが、そこで.gitignoreファイルを自動的に追加する"Add .gitignore"オプションを活用する方法です。
これが一番簡単だと思います。
"Add .gitignore"ドロップダウンで"VisualStudio"を選択しそのままリポジトリを作成するだけです。

![70015294-f70c-04cb-c707-668dee98bc32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3726673/39abf9d9-a2f2-ffd7-0870-85880b078d99.png)

![f60e1fbc-ea64-561e-958f-be411955a046.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3726673/a0331dbf-bab6-7bb5-41e8-c8403069ef09.png)

# 作成方法2：コマンドプロンプトから作成
GitHubで設定を忘れた場合や、既存のプロジェクトに.gitignoreを追加したい場合は、コマンドラインを活用する方法が便利です。

コマンドプロンプトを起動し以下のコマンドを実行するだけです。
実行するとカレントディレクトリに.gitignoreファイルが生成されます。
```
dotnet new gitignore
```

# 作成方法3：生成サービスから作成
gitignore.ioというWebサイトから作成する方法です。
こちらも非常に簡単に作成できます。

https://www.toptal.com/developers/gitignore/

ブラウザで上記のサイトにアクセスし、VisualStudioと入力すると候補がリストとして出てくるのでクリック。
そのまま作成ボタンを押すとテキストファイルが記述されてあるページに遷移します。

![cac5f5f3-4011-0389-4151-50c43e9f57a3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3726673/98879f9e-c200-4f17-98c8-31550f082050.png)

![db729f00-c900-ca98-f447-d6bcb593c00b.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3726673/a2373714-425d-b569-a843-dc512b8a2c45.png)

これをこのまま.gitignoreファイルとして保存するだけです。

# まとめ
.gitignoreファイルは、手書きではなくツールで生成するものだと理解しました。
[解決]JenkinsのGitでPruneするのに手こずった

結論から言うと、Jenkins with Git Pluginの環境でPruneを行う場合には、

```
extensions: [[$class: 'CloneOption', depth: 0, noTags: false, reference: '', shallow: false, timeout: 60], [$class: 'PruneStaleBranch']] 
```

こんな感じで、checkout関数のextentionsにPruneStaleBranchオプションを与えてあげればOKです。

# 何故ハマったか

何故この程度のことに手こずったかというと、JenkinのPruneに関する情報を調べるとトップに出てくる公式ドキュメントに従っていたから。

https://www.jenkins.io/doc/pipeline/steps/workflow-scm-step/

Jenkinsプラグインの文法仕様が新しいバージョンでは少し変わったみたいですね。
(Version 5系からcheckout scmGitという文法に変わったみたい。ちなみに私はVersion 4系)

https://community.jenkins.io/t/testing-git-plugin-5-0-0-and-git-client-plugin-4-0-0/5014

私の環境は諸事情でPluginのアップデートができず、文法が異なっておりエラーにハマっておりました。
pruneTagsは使えないのです。

で、色々と四苦八苦していたところ、以下のページに出会い。

https://www.jenkins.io/doc/pipeline/steps/git/

そうか！Snippet Generatorがあったよ！

ということで、JenkinsのSnippet Generatorにアクセスし、オプションを探す・・・あった！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267148/c05fe60b-f9b7-f2dd-fde7-e8073b21fe42.png)

これでGenerateするとextentionsにオプションが追加されて無事解決。

たったこれだけのことでした。おしまい。
Unable to call lifecycle method [updatedhonyarara] directly on component: [hogehoge.index]

Livewireを使ってるとたまにわけが分からないエラーにぶち当たる

今回はこれ
```Unable to call lifecycle method [updatedhonyarara] directly on component: [hogehoge.index]```


ソースはこんな感じ

```
<button wire:click="updatedhonyarara" class="btn btn-primary">処理処理</button>
```

```
public function updatedhonyarara()
{
   ;
}
```

全く問題がないがあかんと言われる。

で、ゴソゴソしていったら
```updated```
が予約語？なんじゃないかとふと気が付いて

updatedhonyarara
を
updatehonyarara
と
書き換えたら動いた。

うーん、意味がわからないがそういうことらしい。
PythonでExcelファイルをjson形式へ変換

# やりたいこと
エクセルファイルに中にあるテーブルデータをjson形式へ変換したい

こんな感じのエクセルデータから
| Left align | Right align | Center align |
|:-----------|------------:|:------------:|
| This       | This        | This         |
| column     | column      | column       |
| will       | will        | will         |
| be         | be          | be           |
| left       | right       | center       |
| aligned    | aligned     | aligned      |


こんな感じのjsonにしたい
```
[{"Left align": "This", "Right align": "This", "Center align": "This"}, その他データは省略]

```

# やり方
さっそく調べた結果をソースコードにしました！

```ruby:convert.py
import json
from openpyxl import load_workbook
import sys

# コマンドからエクセルファイル名を読み取る
args = sys.argv
path = "｛path｝"+args[1]

# ワークシートを取得する
sheet = workbook.active

# Excelデータのカラム名を読み込む
column_names = []
for row in sheet.iter_rows(max_row=1, values_only=True):
    for column_name in row:
        column_names.append(column_name)

# ExcelデータをJSONに変換する
records = []
for row in sheet.iter_rows(min_row=2, values_only=True):
    # ここではfor文とかで回したりするほうがもっと賢明ですね～
    # まあ、いったんイメージとして書く、、、
    record = {
        column_names[0]: row[0],
        column_names[1]: row[1],
        column_names[2]: row[2],
    }
    records.append(record)

#変換後のファイルを出力
with open("｛パス/jsonファイル名｝", "w", encoding="utf-8") as output_json:
    output_json.writelines(json.dumps(records, ensure_ascii=False))

```

実行時はこのコマンドで

```ruby:
python convert.py エクセルファイル名
```

# 終わりに
今回はopenpyxlの公式サイトを見て各パラメータの意味合いを理解しながらソートコードを作りました！
iter_rows以外には、iter_colsなどカラムを処理する場合のメソッドが用意されていますので、今後はエクセル読み込み時の要件に合わせて適切にメソッドを選定してデータを処理したいと思います～


# 参考サイト
公式ドキュメントです～

https://openpyxl.readthedocs.io/en/stable/api/openpyxl.worksheet.worksheet.html#openpyxl.worksheet.worksheet.Worksheet.iter_cols
alternativesコマンドでfailed to read linkが出たときの対処法

# はじめに

alternativesでjavaの設定をしているときに`failed to read link`が出力されて、コマンドの削除も上書きもできなくなったことがあったので、その対処法を書き残しておきます。


# 原因
`alternatives --install`でコマンドを登録するときに、存在しないディレクトリをリンク先に設定してしまった場合に発生するようです。

```shell
sh-4.4# alternatives --install /HOGE/java java /usr/lib/jvm/jre-17/bin/java 100
failed to link /HOGE/java -> /etc/alternatives/java: No such file or directory
```

一度存在しないリンク先で登録してしまうと、`--remove`オプションで削除しようとしても、`--install`オプションで正しいパスの設定で上書きしようとしても発生してしまいます。
```shell-session
# 削除
sh-4.4# alternatives --remove java /usr/lib/jvm/jre-17/bin/java
failed to read link /HOGE/java: No such file or directory

# 正しいパスで上書き
sh-4.4# alternatives --install /usr/bin/java java /usr/lib/jvm/jre-17/bin/java 100
failed to read link /HOGE/java: No such file or directory
the primary link for java must be /HOGE/java
```


# 対処法

`/var/lib/alternatives`(administrativeディレクトリ)に存在する、間違えて登録したリンク名のファイルを削除します。削除すると再びコマンドを登録できるようになります。

```shell-session
sh-4.4# ls
java  python  python3
sh-4.4# rm java
sh-4.4# alternatives --install /usr/bin/java java /usr/lib/jvm/jre-17/bin/java 100
```

# おわりに
最初からパスを間違えないで設定していれば...と思いました。
Add Business Logic to a Travel Approval App


https://trailhead.salesforce.com/content/learn/projects/add-business-logic-to-a-travel-approval-app?trail_id=build-a-travel-approval-app


# "This approval request requires the next approver to be determined by the Manager field. This value is empty. Please contact your administrator for more information

+ [Add Business Logic to a Travel Approval App - link test your approval process](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007I5y5S)

:::note
Please check Manger on your login user. If Manager is blank then it will give same error.
Check you user detail

https://developer.salesforce.com/forums/?id=906F0000000D6RhIAK
:::


# Test Your Approval Process

+ [Test Your Approval Process (on Add Business Logic to a Travel Approval App)](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007bKyP8)

メールは届かないけど合格できた
Spotify APIを使って楽曲を分析してみた

Spotify APIを使って曲の分析をできることを知りました

特に業務で使うものではなかったのですが、音楽好きなものとして使ってみたくつかってみることにしました


### 事前準備

APIを使用するには、Spotifyでアプリを作成する必要があります　

1. [Spotify developer](https://developer.spotify.com/)ページにアクセスしログイン
2. 右上のユーザー名クリックでメニューを開き[Dashboard]からダッシュボードに移動
3. [Create App]からアプリを作成します、入力欄にそって必要なものを入力
4. 作成できたらアプリ名をクリックし、settingから設定に移動します
5. Client ID　とClient secretは実装時使用するのでメモしておいてください
![スクリーンショット 2024-02-21 20.10.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276326/6e1459e4-3b2e-e3b2-5be3-97de79a4c799.png)

### データ取得して

楽曲のデータを取得してみます
Spotifyを開いて曲検索すると、URLの末尾がランダムな文字列になっております
こちらを使用します、今回私が大好きなBUMP OF CHICKENの天体観測を使います

![スクリーンショット 2024-03-20 23.43.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276326/324b73cc-a4d2-d251-1df0-ed13e8d8d3b4.png)

api.py
```
import spotipy
from spotipy.oauth2 import SpotifyClientCredentials


my_id = 'API Client ID'
my_secret = 'API Client secret'

ccm = SpotifyClientCredentials(client_id = my_id, client_secret = my_secret)
sp = spotipy.Spotify(client_credentials_manager = ccm)

music_id = "3hRRYgBeunE3PTmnzATTS0" # 天体観測のmusic_id
result = sp.audio_features(music_id)

print(result)
```

返り値
```
[
	{
		"danceability": 0.366,
		"energy": 0.949,
		"key": 1,
		"loudness": -3.552,
		"mode": 1,
		"speechiness": 0.11,
		"acousticness": 0.381,
		"instrumentalness": 0,
		"liveness": 0.0902,
		"valence": 0.467,
		"tempo": 164.979,
		"type": "audio_features",
		"id": "3hRRYgBeunE3PTmnzATTS0",
		"uri": "spotify:track:3hRRYgBeunE3PTmnzATTS0",
		"track_href": "https://api.spotify.com/v1/tracks/3hRRYgBeunE3PTmnzATTS0",
		"analysis_url": "https://api.spotify.com/v1/audio-analysis/3hRRYgBeunE3PTmnzATTS0",
		"duration_ms": 263600,
		"time_signature": 4
	}
]

```

| パラメータ          | 説明                |
|:-----------------|--------------------:|
| danceability     | ダンスに適しているか     | 
| acousticness     | アコースティック感       | 
| popularity       | 相対的人気度          | 
| energy           | エネルギッシュ度        | 
| instrumentalness | インスト感（歌声がない割合)|
| liveness         | ライブ感（聴衆がいるか）   |
| valence          | 曲の陽性度            |
| tempo            | テンポ               |


 #### 応用

Spotifyでは１曲単位でなく、プレイリスト、または、アルバムのURLから曲一覧を取得することができます。

アルバムから曲一覧を取得し、分析データをCSVに出力するサンプルを作成しました
※ソース内の#プレイリストからに切り替えたら、プレイリストからも作成できます

https://github.com/merika427/spotify-py/blob/main/api.py

 #### 感想

思いの外手軽に楽曲情報を取得できて驚いた

こういう情報をもとに、Spotify側で自身の好みなどに合わせておすすめ出してくれてるんだろうか？

これをどう使うか、活用事例が浮かんだらまたやってみようと思います
wslで、最小のカーネルをコンパイル その44

# 概要
wslで、kernel.elfのコンパイル、やってみた。
ここまでのkernel比較。

# ここまでのkernel比較。

|kernel|my kernel|gazos|HariboootOS|Haribotelinux|
|:-|:-|:-|:-|:-|
|イメージ|elf|elf|floppy|floppy|
|キーボード|o|o|o|o
|ファイルリード|x|o|o|o
|ファイルライト|x|o|x|o
|浮動小数点演算|x|x|x|o
|GUI|x|x|o|o
|マウス|x|x|o|o
|俺言語移植|o|o|o|x
|シスコール|x|x|x|o
|マルチタスク|x|x|x|o
|qemu動作安定性|o|x|o|x







以上。