OmniAICreator/Qiita-1.07M huggingface dataset:
Ubuntu 22.04 カーネルビルド手順

Raspberry Pi 5を、改造しやすい(？)Ubuntu22.04でいろいろ制御してみあたい。
カーネルビルドに関して、個人的にはマスターしたい苦行ポイントが4つある。

* カーネル設定ファイルを正しく設定したい
* カーネルが起動しないとき、速やかに解決できるようになりたい
* 既存デバイスの動作をカスタマイズしたい
* 新規デバイスを開発して、Linuxで動かしたい

### A. カーネルコードを取得

* Ubuntu 22.04に近いカーネルコードを探す。極端にバージョンに差があると、カーネル以外のものが動かなくなるかも。

* [カーネルコード](https://mirrors.edge.kernel.org/pub/linux/kernel/v6.x/)
* Ubuntuサイトから取得したカーネルコードはビルドできなかった（なんで？）

```
# uname -r
6.5.0-21-generic
# cd /home
# wget https://mirrors.edge.kernel.org/pub/linux/kernel/v6.x/linux-6.5.13.tar.xz
# tar xvf linux-6.5.13.tar.xz
# cd linux-6.5.13/
```

### B. カーネル設定ファイルを編集

```
# cp /boot/config-6.5.0-21-generic .config
# vi .config
```

##### 変更前

```
CONFIG_SYSTEM_TRUSTED_KEYS="debian/canonical-certs.pem"
CONFIG_SYSTEM_REVOCATION_KEYS="debian/canonical-revoked-certs.pem"
```

##### 変更後

```
CONFIG_SYSTEM_TRUSTED_KEYS=""
CONFIG_SYSTEM_REVOCATION_KEYS=""
```

### C. ビルド環境を準備

```
# apt install make gcc flex bison libssl-devel libelf-dev
```

### D. カーネル設定ファイルを適用する

* 途中、対話があったら、[ENTER]する
  * ちゃんと理解して、正しく編集するべき【苦行ポイント1】

```
# make localmodconfig
```

### E. メイクしてインストールする

```
# make
# make INSTALL_MOD_STRIP=1 modules_install
# make INSTALL_MOD_STRIP=1 install
```

* INSTALL_MOD_STRIP=1を付けないと、大量のデバッグシンボルでramdiscがパンクして起動できないことがある

* INSTALL_MOD_STRIP=1は初回のビルド時だけでよい？(不明)

### F. 起動してみる

* メイクとインストールが完了したら、再起動してみる
* 新しいカーネルで動作していることを確認する

```
# uname -a
Linux ubu22.morifuku.com 6.5.13 #1 SMP PREEMPT_DYNAMIC Sat Mar  2 08:25:34 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux
```

* 起動しなかったら、
  * 強制リブートして、起動オプションで「最終正常起動カーネル」を選択し、起動する
  * 問題点を自力で直す【苦行ポイント2】

### G. カーネルコードをいじってみる

* ソースコードを変更したら、手順E〜手順Fを行う

### H. なぜカーネルコードをいじるのか

* カーネルの動作内容を詳細に観察するためのprintk文を挿入する（初級者）
* 既存デバイスの動作をカスタマイズする（中級者）【苦行ポイント3】
* 新規デバイスを開発して、Linuxで動かす（上級者）【苦行ポイント4】

以上
【Java】初心者必見、Javaの基礎！！

# Javaの基本的な書き方

絶対に覚えておくべき知識をソースコードとして共有致します。
是非、勉強の参考にしてください。

コード自体を共有するので書き方を覚えてください。

## ソースコード共有

```java
import java.util.Scanner;

/**
 * Javaの基本的な記載方法
 */
class Sample{
	public static void main (String args[]) {
		System.out.println("Hello"); // 文字出力
		
		String s = "こんにちは"; // string型
		int n = 20; // int型
  
		System.out.println("〇〇さん、" + s + "。〇〇さんの年齢は" + n + "歳です。");
		
		showMessage(); // メソッド呼び出し
		
		imputNumber(); // 入力やif文の例
  
		Kuku kuku = new Kuku(); // クラスのインスタンス化		
		kuku.display(); // Kukuのクラス内にあるメソッド呼び出し
	}
	
	// メソッドの作成
	public static void showMessage() {
		System.out.println("メソッド呼び出し");
	}
	
	// 数値を判断するプログラム
	public static void imputNumber() {
		System.out.print("数値を入力⇒");
		Scanner inputNum = new Scanner(System.in);
		
		int num = inputNum.nextInt(); // 数値受け取り
		
		// 数値を判断するif文
		if (num == 0) {
			System.out.println("数字は0です");
		}else if (num % 2 == 0) {
			System.out.println("偶数です。");
		}else {
			System.out.println("奇数であり、数値は0以外です。");
		}
		
		inputNum.close();
	}
}

/**
 * クラスの使用、for文、二重for文の記述方法。
 */
class Kuku {
	public void display() {
		for (int i = 1; i <= 10; i++) {
			System.out.print(i); // iの変数を表示
			System.out.println(" ");
		}

		System.out.println("--------九九を表示---------");

		for (int j = 1; j < 10; j++) {
			for (int k = 1; k < 10; k++) {
				int ans = j * k;
				if (ans < 10) {
					System.out.print(ans); // iの変数を表示
					System.out.print("  ");
				} else {
					System.out.print(ans); // iの変数を表示
					System.out.print(" ");
				}
			}

			System.out.println();
		}
	}
}
```

## プログラム実行時
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2759758/465adf3d-a8e5-0934-94c0-8bf56252784a.png)
開発者さまへ、権限はありますか?

# Dear developer, do you have permission?

なんとなく、載せろと感じた。

**Pictures**　右クリックメニュー　**property**
![スクリーンショット 2024-03-02 172723.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625232/8b52f088-978f-2a86-37d5-7edca9d37462.png)
![スクリーンショット 2024-03-02 172756.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625232/ff328004-7d00-adfd-e664-c7ad42d246f0.png)
![スクリーンショット 2024-03-02 172845.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625232/a48eb603-b67d-c158-1777-20edd469d651.png)
![スクリーンショット 2024-03-02 172912.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625232/13574506-1431-c40a-a375-6389e689611a.png)
![スクリーンショット 2024-03-02 172941.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625232/183f7a3f-1b06-ce7d-847d-1d18f17ab236.png)
![スクリーンショット 2024-03-02 173001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625232/2a831c4a-6c1d-1577-bd3b-dd735200d683.png)

権限が無ければファイルは変えられない。
Rubyの基本（クラス・インスタンス）

# クラスの定義
「クラス」とは、関連する変数やメソッドをまとめて、複雑なデータを扱いやすくするための仕組みである。
クラスの定義通りに作ったデータを、そのクラスの「インスタンス」と呼ぶ。
クラスは設計書、インスタンスは設計書を元に作られたものであるといえる。
```ruby:sample_01.rb
# クラスの定義
class User
  def get_info
    "user name and score here"
  end
end

# インスタンスの生成
user1 = User.new
user2 = User.new

# インスタンスメソッドの呼び出し
puts user1.get_info
puts user2.get_info
# user name and score here
# user name and score here
```

# `initialize`メソッド（イニシャライザ）
`initialize`メソッド（イニシャライザ）とは、インスタンス生成と同時に呼び出せる特殊なメソッドである。
以下に使い方の一例を示す。
```ruby:sample_02_01.rb
class User

  attr_accessor :name, :score

  def initialize(name, score)
    self.name = name
    self.score = score
  end

  def get_info
    "#{self.name} #{self.score}"
  end
end

user1 = User.new("Taro", 70)
user2 = User.new("Jiro", 90)

puts user1.get_info # Taro 70
puts user2.get_info # Jiro 90
```
上記の例では、メソッドの外側でインスタンス変数を定義し、`self`を使ってインスタンスメソッドの中で使える
ようにした。

インスタンス変数の定義方法は他にもあり、`@`を使うことでインスタンスメソッドの中でインスタンス変数を定義することもできる。
以下に一例を示す。
```ruby:sample_02_02.rb
class User

  def initialize(name, score)
    @name = name
    @score = score
  end

  def get_info
    "#{@name} #{@score}"
  end
end

user1 = User.new("Taro", 70)
user2 = User.new("Jiro", 90)
puts user1.get_info
puts user2.get_info
```

# インスタンス変数へのアクセス
インスタンスから実行できるのはインスタンスメソッドのみで、インスタンス変数は実行できない。
インスタンスから変数にアクセスする場合は、そのためのインスタンスメソッドを定義する必要がある。
また、インスタンスからインスタンス変数を更新する場合は、別にそのためのインスタンスメソッドを定義する必要がある。
インスタンスからインスタンス変数にアクセスするためのインスタンスメソッドを「getter」、インスタンスから インスタンス変数を更新するためのインスタンスメソッドを「setter」と呼ぶ。
```ruby:sample_03.rb
class User
  def initialize(name, score)
    @name = name
    @score = score
  end

# getter
  def name
    @name
  end

# setter
  def name=(new_name)
    @name = new_name
  end

  def get_info
    "Name: #{@name}, Score: #{@score}"
  end
end

user1 = User.new("Taro", 70)
user2 = User.new("Jiro", 90)

# インスタンス変数の更新
user1.name = "TARO"

puts user1.name # TARO
```
「sample_02_01.rb」において、`attr_accessor`を使ってインスタンス変数を定義したが、これによって「getter」と「setter」の両方を定義したことと同じことになる。
これからはJavaScript勉強しよう 1回目

https://www.canit.jp/intro/javascript/javascript1-9.html

次回はCSVファイルを読み込んでみる

```html
<!DOCTYPE html>
<head>
<title>テスト画面</title>
</head>
<body>
<form name="myform">
<input name="myfile" type="file">
</form>
<script>

var form = document.forms.myform;

form.myfile.addEventListener( 'change', function(e) {
    // ファイルを取得する
    var result = e.target.files[0];

    // ファイルを読み込む
    var reader = new FileReader();
    reader.readAsText(result);

    // ファイルが読み込まれた後の処理
    reader.addEventListener('load', function() {
        document.write(reader.result);
    })

})
</script>
</body>
</html>
```
Webアクセシビリティ（１）

# はじめに

この記事では話題になっているWebアクセシビリティに関して知り、取り組めるようになることが目的です。
まずは、Webアクセシビリティとはなんなのかについてまとめていきます。

## アクセシビリティ(Accessibility)の概要

アクセシビリティとは、「利用可能な状況の幅広さ」を意味し、`Accessibility = Access(アクセスする) + Ability(できること)`から成り立っています。すなわち、さまざまな状況の人々が製品やサービス、環境を利用しやすくすることを指します。

### ユーザビリティとの違い

ユーザビリティは「使いやすさ」を指し、特定のユーザーや状況下での利用のしやすさを意味します。一方、アクセシビリティは様々なユーザーの状況を考慮した利用可能性の幅を表します。

## Webアクセシビリティの概要

Webアクセシビリティは、Web上のコンテンツやサービスが幅広いユーザーにとって利用可能であることを意味します。

### アクセシブルなWeb

Webは、通信環境と端末があれば、どのような時間や場所、デバイスからでもアクセス可能です。これにより、様々な状況の人々がオンラインで買い物や学習、仕事、情報収集を行うことができます。

### Webコンテンツの柔軟性

Web上のコンテンツはユーザー側で表現を変更できるため、さまざまな状況のユーザーに対応可能です。例えば、文字の大きさや色の変更、スクリーンリーダーを通じた音声読み上げなどが可能です。

## Webアクセシビリティと「障害」

アクセシビリティを考える際、障害の有無だけでなく、様々な利用状況を考慮する必要があります。

### 障害の種類と対応

- **視覚障害**: スクリーンリーダーや文字サイズの調整、コントラストの変更などで対応可能
- **色覚特性**: カラーフィルタを使用して色を認識しやすくする
- **聴覚障害**: 音声情報をテキストに変換することでアクセスを容易にする
- **上肢障害**: キーボードのみでの操作や音声コントロールなど、様々な入力方法を提供する
- **認知・学習障害**: 分かりやすい言葉の使用や補助的なグラフィック、シンボルの利用など

### 加齢と障害

加齢によっても、視覚や聴覚、認知能力などに変化が生じるため、アクセシビリティの考慮が必要です。

### 一時的な障害

一時的な状況（メガネを忘れた、手が塞がっているなど）もアクセシビリティの観点から考慮する必要があります。
Github Copilot 質問と回答(q: & a:) Tips

Github Copilot を利用して、VSCodeで簡単に質問できる。

q:と質問を叩くと、a:入力すると、自動に回答してくれる。

使い方

```text
q: {質問}
a: {回答}  
```

例

golang のDBマイグレーションツールについて聞きたいです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155256/0ead9aa1-1dc7-9efe-83d8-d9e7a24f6ccf.png)
AWS S3のオブジェクトロックにおける、ガバナンスモードとコンプライアンモードの違いについての備忘録

### ガバナンスモードとコンプライアンスモードの違いを簡単に説明すると

ガバナンス＝管理者が設定した期間過ぎたら削除、変更が可能＝ちょい厳格オヤジ設定
コンプライアンスモード=管理者でさえ削除、変更無理＝超厳格オヤジ設定


### 違いについて

#### コンプライアンスモード（Compliance Mode）:

コンプライアンスモードでは、設定された保持期間中はオブジェクトの削除や変更を防止することができます。
このモードでは、保持期間を終了するためにAWSのカスタマーサポートとの連絡が必要であり、削除や変更を回避するための厳格なポリシーを適用します。
コンプライアンスモードは、法的要件や業界規制などの厳密なコンプライアンス要件を満たすために使用されます。

#### ガバナンスモード（Governance Mode）:

ガバナンスモードでは、管理者が設定した保持期間内においては、オブジェクトの削除や変更を防止することができますが、保持期間が終了した後は削除や変更が可能です。
保持期間の終了後にオブジェクトを変更できるようにするため、AWSのカスタマーサポートとの連絡は不要です。
ガバナンスモードは、データ管理上のベストプラクティスや内部ポリシーを強化し、データのセキュリティと信頼性を高めるために使用されます。
要するに、コンプライアンスモードは非常に厳格なデータ保持要件を満たすために使用され、保持期間中はオブジェクトの削除や変更ができません。一方、ガバナンスモードは、保持期間中はオブジェクトの削除や変更を防止し、保持期間終了後に変更を許可するような柔軟なポリシーを適用します。
Chrome 拡張機能開発で、manifest.js に登録できるショートカットコマンドは4つまでというエラー

エラー文でググった際に日本語のページが出てこなかったので記事化。

自社サービスの予約フォーム動作テストで毎回フォームに値を入れるのが超面倒なので、プライベートで [Copy Paste Form Value](https://chromewebstore.google.com/detail/copy-paste-form-value/nioncldhiahbgjglohpeeanmblncdceb) というフォームの値をコピペ出来るツールを開発してます。

<br>

直近で **コピーした情報（※クリップボード）を削除する機能** を作っていたのですが、manifest.json に新しくショートカットを追加した際に起きたエラーです。

```bash
Too many shortcuts specified for 'commands': The maximum is 4.
# 「コマンド」に指定されたショートカットが多すぎます: 最大は 4 です。※ DeepL翻訳
```

最初見た時は「command に登録できるのが最大4つなんだな」と認識しましたが、調べてみると **command そのものはいくらでも登録できる**というか特に制限はかかっておらず、単に「suggested_key（※キーボードショートカット）を登録できるコマンドは4つまで」ということらしいですね。

## サンプルとして Copy Paste Form Value の manifest.json
suggested_key は 4つまで登録して、copy-paste-form-value-message というコマンドには登録していません。

copy-paste-form-value-message にはショートカットが割り振られていないので、これは**ユーザーが利用するのではなく、開発者が内部的に呼び出す**というコマンドになります。こういうコマンドはいくらでも登録出来るようです。

```json
  "commands": {
    "copy-paste-form-value-copy": {
      "suggested_key": {
        "default": "Alt+I"
      },
      "description": "__MSG_copyBtnDescription__"
    },
    "copy-paste-form-value-paste": {
      "suggested_key": {
        "default": "Alt+O"
      },
      "description": "__MSG_pasteBtnDescription__"
    },
    "copy-paste-form-value-toggle": {
      "suggested_key": {
        "default": "Alt+P"
      },
      "description": "__MSG_copyPasteBtn__"
    },
    "copy-paste-form-value-remove": {
      "suggested_key": {
        "default": "Alt+D"
      },
      "description": "__MSG_removeDescription__"
    },
    "copy-paste-form-value-message": {
      "description": "__MSG_flashMessage__"
    }
  },
```

ちなみのこの制限を変更することは出来ない模様。残念。

まぁ再現なく登録出来てしまうと、他の拡張機能とショートカットキーが被ってしまう可能性がめっちゃ上がってしまうので仕方ないかも知れないです。

# 紹介

## Copy Paste Form Value 記事
https://qiita.com/kazumacchi/items/e7d50bb0e4da3ae64c8d

## Chrome ウェブストア
https://chromewebstore.google.com/detail/copy-paste-form-value/nioncldhiahbgjglohpeeanmblncdceb

## GitHub
https://github.com/kanagama/copy_paste_form_value
プログラマーと学歴と大企業

## プログラマーになりたい

どうも就職氷河期経験者です。

小学生の将来なりたい職業2023年では、第2位にプログラマーがランクインしました。
こういう事、何年に一回ありますよね。
Youtuberになりたいみたいな。

プログラミングを教えている中で、将来プログラマーになりたいという小学生にも出会います。
そのために、勉強していい大学行くというモチベーションになり親御さんも喜ばれてます。

今回は、プログラマーになるために良い大学、大企業のルートはありなのかどうかが争点になります。

## 就職氷河期

厚生労働省ではバブル崩壊後の1990～2000年代に就職活動を行った時期を就職氷河期とよんでいるようです。
それって20年間就職氷河期が続いたってことでしょうか。
その後も、地方では就職氷河期の余韻は続いていたと思うのですが気の所為だったのかな。

- バブル崩壊から金融危機（1993-2000年卒）
- ITバブル崩壊からリーマン・ショック（2001-2014年卒）
- コロナ禍（2019-2022年卒）

## リストラ

ここ数日のtogatterでも次のようなまとめがありました

https://togetter.com/li/2324595

プログラマー関係ないですが、大企業は関係あります。

悟りを開いた今では、シュレッダーかけるだけで大企業の安定した給与を得られることは最適解なのではないかと思うところです。

ただ、学生時代公務員のアルバイトをした時、1ヶ月以内に辞めたぐらい、若いときは刺激が欲しいものです。

良い大学、大企業に入ったとしても、なかなか難しいものがあります。

https://togetter.com/li/2307602

セールスフォースというと、IT業界ではない方には馴染が少ないことでしょう。

```
株式会社セールスフォース・ジャパン（旧:株式会社セールスフォース・ドットコム）の平均年収は1133万円、年収範囲は400～3200万円です（86人の正社員の回答）。
```

つまり、大企業です。

実際の年収も、円安の影響があり、平均年収も1.5倍になり、1700万円～ぐらいです。

https://en-hyouban.com/company/10025403019/salary/#:~:text=%E6%83%85%E5%A0%B1(0%E4%BB%B6)-,%E6%A0%AA%E5%BC%8F%E4%BC%9A%E7%A4%BE%E3%82%BB%E3%83%BC%E3%83%AB%E3%82%B9%E3%83%95%E3%82%A9%E3%83%BC%E3%82%B9%E3%83%BB%E3%82%B8%E3%83%A3%E3%83%91%E3%83%B3%EF%BC%88%E6%97%A7%3A%E6%A0%AA%E5%BC%8F%E4%BC%9A%E7%A4%BE%E3%82%BB%E3%83%BC%E3%83%AB%E3%82%B9,%E4%BA%BA%E3%81%AE%E6%AD%A3%E7%A4%BE%E5%93%A1%E3%81%AE%E5%9B%9E%E7%AD%94%EF%BC%89%E3%80%82


## 大企業に入っても〇〇

要はリストラがあるので、大企業に入っても〇〇という意見があります。
セールスフォースぐらいの規模になると、リストラされるときも数十ヶ月分の退職金的な何かが支払われます。
そういう意味では、仕事ができる人なら早期退職というか、辞めて数十ヶ月分の退職金をもらえたほうが幸せだと思います。

考え方次第なんです。
仮に24ヶ月分もらえるとしたら、17000*24=40800万円です。

つまり、大企業に入ってもリストラされるからということを考えると、やはり大企業に入ってリストラされて、退職金を上乗せされたほうが良いと思います。

中小企業だとこうはなりません。

https://togetter.com/li/2324574

いろいろ書かれておりますが、資生堂も多分いい条件で上乗せしてくれると思います。
辞めたら転職先も大企業とはいかない人もいらっしゃるかと思いますが、少子化で採用が難しい現状、そのまま大企業にスライド転職も可能です。

## 学歴

1行目を書き出す時、大企業に入ってもリストラあるしー、という論調を考えていましたが、やはり大企業に入ったほうが良いと感じました。

もちろん、大企業に入るためには相当上位の大学を出る必要があると思ってます。
就職氷河期メンバーなのでそういう偏った考え方なのかとおもいつつも、うん、学歴は大切だと感じました。
いや、学歴ではなく新卒で大企業に入っておくと色々余裕が出るんだろうなということです。

論調が変わりすいません。
学歴ではないです。
大企業に入る可能性を高めるのが学歴のちからの一つだということです。

つまり、大企業に入れるのであれば学歴だけではないです。
プログラマーであれば、高専がオススメという結論です。

## まとめ
- 大企業は良い
- プログラマーで大企業なら高専がオススメ
- 学歴は可能性を増やす事ができる
TryHackMe Writeup:tomghost

# はじめに
今回は難易度`Easy`のルーム`tomghost`をやっていきたいと思います．

# ポートスキャン
いつも通りのポートスキャンです．
`sudo nmap -p- -vv -T4 -O -sV 10.10.212.123`
![Pasted image 20240301171231.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3015493/1c3c81c7-034a-5872-2f2d-6fd7de840073.png)
今回はいつもと違って珍しくいろんなポートが開いてますね．
TomcatとかJservとかが動いてますね．

とりあえず8080番でHTTPが動いているので見てみます．
![Pasted image 20240301171939.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3015493/443784a8-4d34-42e5-117b-ba8564eb815b.png)
ルームの最初のほうに脆弱性関連のことが書かれていたので調べてみます．
「Tomcat 9.0.30 vulnerabilities」と調べるとそういう脆弱性があるようです．
参考：https://github.com/Hancheng-Lei/Hacking-Vulnerability-CVE-2020-1938-Ghostcat/blob/main/CVE-2020-1938.md
＊これをそのままクローンして実行したらエラー出ますが少し修正すれば大丈夫です．
```
TypeError: makefile() got an unexpected keyword argument 'bufsize'のエラーはbufsize=0のbufsizeを消せばいけました．

TypeError: sequence item 0: expected str instance, bytes foundは最後のprintのクオーテーションの前にbを付ければいけます．
```
`python3 CVE-2020-1938.py `
![Pasted image 20240301180617.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3015493/6754415e-96a8-eb27-3e34-d2b1030f2abe.png)
第1引数は標的のIPアドレス，-pでJservのポートを指定します．
最初はtskyfuckで試してみましたが`\t`もエスケープシーケンスですね．

これでSSHログインします．
`ssh skyfuck@10.10.212.123`
`find / -name user.txt`で探してみます．
`/home/marlin/user.txt`にあります．

# Privilege escalation
取り合えず`sudo -l`をしてみますが見れません．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3015493/98ea516b-00c9-7829-b908-c0f9b983a42e.png)
`credential.pgp`と`tryhackme.asc`があります．
tryhackme.ascがPGPカギになっているようです．

![Pasted image 20240301183356.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3015493/12330c10-30ef-39e9-2060-95f7dfc1888b.png)
取り合えず復号のためにSCPでコピーしてきます．

`gpg2john tryhackme.asc > hash.txt`
`sudo john hash.txt --wordlist=/usr/share/wordlists/rockyou.txt`
![Pasted image 20240301184724.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3015493/afdd13a0-a308-fff4-f4b9-a7ad8b769150.png)

`gpg --import tryhackme.asc`
`gpg --decrypt credential.pgp`
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3015493/3a91b59a-dff4-7776-99a8-c74a39a2c9f4.png)
ここに先ほど解析したパスワードを入れる．
![Pasted image 20240301184951.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3015493/95b4eaf4-3735-9c59-de02-41af5e79c68f.png)

これでSSHログイン
`ssh marlin@10.10.212.123`
![Pasted image 20240301185145.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3015493/fc376755-ecaa-246c-5cf9-07e3a72c0fc2.png)
`zip`コマンドが使えるみたいです．
[gtfobins](https://gtfobins.github.io/gtfobins/zip/)で調べてみると使えそうなのがあったので試してみます．
![Pasted image 20240301185526.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3015493/8f152cb4-6b7e-65d0-eca9-b943a645d7c4.png)
`root`になれました．
`/root/root.txt`にあります．

# おわりに
gtfobinsのありがたさを感じましたね．
PGPやASCファイルについては全然詳しくないのでこの辺りも勉強したいと思います．
PowerAutomate: Lists の User 列に複数User を登録する

# 背景

以下の投稿にて、質問があったのでやってみた記録、というか回答

https://qiita.com/baku2san/items/6b2ca1c4dd801736e76e#comment-4e64d0d9dcdf32aafc2b

# 結論

@hakidashi_akuma 

これ使えば余裕になってますね・・

https://qiita.com/baku2san/items/107c3cef6cec5e636a8d

# 過去のやり方

まずは普通にやってみた。

やることとしては以下

1. 登録用の User 情報を取得する
1. あとは、単純に更新するだけ

ただ、現状なら、上で紹介した、ResolePerson Action を使えば、User情報を簡単に Automate 内部で利用出来るので、Claimsの意味不明に見える文字列を意識しなくてよくなります。

## User 情報の取得

> {topSiteAddress}_api/Web/SiteUsers

上を使って、OData で User 情報を取得する

で、<d:LoginName> の部分を取得しておく

\<d:LoginName>**i:0#.f|membership|personname@sitename.onmicrosoft.com**\</d:LoginName>

これを複数人分用意。

で、Automateでやるなら、Graph API で Site User 一覧を取得したほうが楽。今回は試行なので手作業取得したけれど

## Create Item or Update Item 等で利用

対象のColumnのところに、以下のように設定するだけ。

```json
[
  {
    "Claims": "i:0#.f|membership|personname1@sitename.onmicrosoft.com"
  },
  {
    "Claims": "i:0#.f|membership|personname2@sitename.onmicrosoft.com"
  }
]
```

:::note info
対象列で複数ユーザーを許可している必要有

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/28517737-76b4-0af7-74e0-3db07ee1caf1.png)


:::

# あとがき

久し振りに触ってみたけど、ローコードツールとしていい感じに進化していってるなぁ・・と感じました。
Copilot で自然言語で自動化が出来るようになるのが待ち遠しいですね、特に会社において・・ :sob:
Amazon Fargate起動タイプを選ぶ時、EKSとECSどっちがいいのか？の備忘録

### Fargate起動タイプについての基本知識
詳細な設定や管理をせずに管理を自動化する必要がある。という場合に選択
マネージドサービス: Amazon EKSのFargate起動タイプは、コンテナの実行環境をサーバーレスにすることで、詳細な仮想マシンの設定や管理が不要です。AWSがインフラストラクチャの管理を自動化し、開発者はアプリケーションの開発やデプロイメントに集中できます。

詳しい説明は省略します。

### オープンソースツールを活用することが求められている場合EKSを選択
Kubernetesはオープンソースのコンテナオーケストレーションツールであり、EKSはKubernetesをベースにしています。そのため、EKS上でKubernetesクラスターを構築し、オープンソースのツールやリソースを活用することが可能です。

#### オープンソースツールとは具体的に何？
Kubernetes: EKSはKubernetesをベースにしており、コンテナのオーケストレーションを行います。Kubernetesはオープンソースのコンテナオーケストレーションプラットフォームであり、アプリケーションのデプロイメント、スケーリング、管理を行います。

Jenkins: CI/CDパイプラインを構築し、ビルド、テスト、デプロイメントなどの自動化を実現するためのオープンソースの継続的インテグレーション（CI）ツールです。

GitLab CI/CD: GitLabに統合されたCI/CD機能を提供するツールであり、ソースコード管理とCI/CDを一元化することができます。

Travis CI: GitHubとの連携が容易なCI/CDサービスであり、GitHubリポジトリからビルド、テスト、デプロイメントを自動化することができます。

CircleCI: ドキュメント指向のCI/CDツールであり、柔軟な設定やDockerコンテナのサポートを提供します。

Spinnaker: Netflixが開発したオープンソースのデリバリープラットフォームであり、マルチクラウド環境でのデプロイメントやパイプラインの管理を支援します。

Tekton: KubernetesネイティブのCI/CDツールであり、Kubernetes上でのCI/CDパイプラインを実現するためのリソースとパイプラインの定義を提供します。
TypeScript5.4で追加される新たなユーティリティ型NoInferを試す

## `NoInfer`
2024年2月22日にTypeScript5.4のRCバージョン(release candidate version)の[アナウンス](https://devblogs.microsoft.com/typescript/announcing-typescript-5-4-rc/)がされました。
アナウンスでは新たなユーティリティ型として`NoInfer`の発表がありました([Beta版](https://devblogs.microsoft.com/typescript/announcing-typescript-5-4-beta/)のアナウンスでも紹介されていました)。
`NoInfer`はTypeScriptの型推論を抑制させるような機能です。

例としてある値がある文字列だけを持つ配列の何番目に含まれているか検知する関数を考えてみます。
```ts
const indexOf = <T extends string>(array: T[], searchElement: T) => {
  return array.indexOf(searchElement);
};
```
この関数は`indexOf(['ruby', 'javascript', 'php'], 'go')`のように呼び出すと`array`に渡した配列も`searchElement`に渡した文字列も`T`を推論するための材料となり、`T`の型は`'ruby' | 'javascript' | 'php' | 'go'`と推論されます。

関数の内部で`T`を活用するために`T`を`array`の構成要素からのみ取得したい場合や、`searchElement`が`array`の一部であることを保証したい場合は`T`が`'ruby' | 'javascript' | 'php'`のようになって欲しいです。つまり、`searchElement`から`T`を推論させるのを止める必要があります。
止めるためには`searchElement`の型を`string`のような雑多な型に当てはめるか、`array`と`searchElement`を別の軸で推論させる必要があります。
```ts
const indexOf = <T extends string>(array: T[], searchElement: string) => {
  return array.indexOf(searchElement);
};

const indexOf = <T extends string, U extends string>(array: T[], searchElement: U) => {
  return array.indexOf(searchElement);
};
```
`searchElement`の型が`array`の一部であって欲しい場合は`U`の制約として`T`の一部であることを示せば良いです。
```ts
const indexOf = <T extends string, U extends T>(array: T[], searchElement: U) => {
  return array.indexOf(searchElement);
};
```
この表現を簡単にするのが`NoInfer`です。`NoInfer`を使うとその部分で推論させることを止められます。
```ts
const indexOf = <T extends string>(array: T[], searchElement: NoInfer<T>) => {
  return array.indexOf(searchElement);
};
```

`NoInfer`を使うと型の推論が行われないので、推論材料が足りない場合は`unknown`として扱われます。
```ts
const sample1 = <T extends any>(arg: T) => {
  return arg;
};

sample1(1);

const sample2 = <T extends any>(arg: NoInfer<T>) => {
  return arg;
};

sample2(1);
```
上記のケースは`T`が`number`と推論されますが、後者は`unknown`となります。

```ts
const useReducer = <T extends any> = (reducer: (prevState: T, action: any), init: NoInfer<T>)
```


## 検証環境

https://www.typescriptlang.org/play?ts=5.4.1-rc#code/MYewdgzgLgBAlmAJgUwB4HkBmBGGBeGAHgGEY0pkkIZoAnBAcwD4AKAQ1trYE8AuGYgG0AugBoayDsAAWAUQA2yALaUo-YgEp8TGAG8AUDBi1kUAK60wMDl24A6BCgyYWESbRkLlqjQG59AL7++o5oWNgsggDkAFZsAG5sEMD0AA5QUeJRtGbQUWIwUQwgUX76+qCQsKHOAEz4RKTklIjUdIziACJkqBRUAqw2POoi4m5ScooqYGownVp4OgZGJuaW1pw8DkhhLuMek94zZUHlNVi1kbEJSSlw6ZmFOXkFRSVlFeDQ8DvOAMwNEg9PqtGhQehgZjsTZ8ASjCQTLzTWYAORAAEkwJhkLQSEwFktDMZTBYrEN7Oc9u5PFMfP5TiFflg-lc4olkmkMllnhlXsVSv4gA
『「漢文は教養だ！」って議論が再度賑わうが「その教養、ぜんぶ現代口語訳で学んじゃだめですか？」と問われたら？』という話をプログラミングでも考えてみたら

『「漢文は教養だ！」って議論が再度賑わうが「その教養、ぜんぶ現代口語訳で学んじゃだめですか？」と問われたら？』という話をプログラミングでも考えてみたら

## 元記事

https://m-dojo.hatenadiary.com/entry/2024/03/01/033138

## 漢文についてどう思うか
漢文は難しい、同意できる話だ。
だからこそ、中学生の頃から、先生が懇切丁寧に現代口語訳（超訳）で教えてくれる。

大人になって思うのは、漢文という少ない文字数の中で伝えられている内容は、人生で誰もが悩むことを解決する手がかりになることが多いと思う。

漢文でなく、現代超訳などで学習すると、取っ掛かりとしては良いけど、多分跳躍した著者の体験談とかで解説されることで、意味が絞り込まれすぎる事が問題なのだと思う。

つまり、いろんな解釈ができる故事成語の物語を、自分自身の頭で考えて、自分自身の人生に活かせることが、古文や漢文を現代口語訳で学ばない理由なんだとおもう。

## プログラミングだとどうだろう

プログラミングを日本語で現代口語訳にするとこうなる

https://www.techpit.jp/courses/257/curriculums/260/sections/1627/parts/6508

プログラミングを現代口語訳にして学ぶことは、取っ掛かりとしてはとても良い。
漢文と同じ様に、プログラミングで挫折する理由として、見慣れない文字列が並ぶことにあると思う。

この点だけでいうと、漢文のほうが感じである為、まだ挫折しにくい。
プログラミングだと、いわゆる英語で表記されているので、日本人にとって挫折するポイントしか無い。
だから、現代口語訳して学ぶと、挫折せず学べる。

しかし、ずっと現代口語訳で学び続けるかと言われるとそうではない。
これは、仕事としてプログラミングを行っているとわかるが、結局最終的には英語で表記されているプログラムを実装することになる。

ライブラリも英語だし、最新情報や信頼できる情報筋も結局英語。
クラス名もメソッド名も英語表記にしないと色々困る。
例えば、Google Python Style Guideに次のようなコードが有る。

https://google.github.io/styleguide/pyguide.html#244-decision

``` python
  def connect_to_next_port(self, minimum: int) -> int:
    """Connects to the next available port.

    Args:
      minimum: A port value greater or equal to 1024.

    Returns:
      The new minimum port.

    Raises:
      ConnectionError: If no available port is found.
    """
    if minimum < 1024:
      # Note that this raising of ValueError is not mentioned in the doc
      # string's "Raises:" section because it is not appropriate to
      # guarantee this specific behavioral reaction to API misuse.
      raise ValueError(f'Min. port must be at least 1024, not {minimum}.')
    port = self._find_next_open_port(minimum)
    if port is None:
      raise ConnectionError(
          f'Could not connect to service on port {minimum} or higher.')
    # The code does not depend on the result of this assert.
    assert port >= minimum, (
        f'Unexpected port {port} when minimum was {minimum}.')
    return port
```

`connect_to_next_port` というメソッドを定義しているが、日本語で定義すると、 `tugino_po-to` みたいな感じになる。

 `tugino_po-to` は、色々抜けている命名かもしれないが、現代口語訳で学習を進め、実務でも現代口語訳で進む場合の本質をついた命名だとも感じる。

 ## まとめ

- 漢文もプログラミングでも、初学者のつまづきを無くすために、現代口語訳（超訳）を利用することは素晴らしい。
- ずっと現代口語訳（超訳）で学習すると、漢文であれば本質、プログラミングであれば実務から逸れてしまう。
- 難しいから凄いということではなく、簡単にする（現代口語訳にする）段階で第3者の解釈が入る。
【Tableau】テキスト表 - 複数項目表示

## はじめに
tableauでExcelみたいな表形式にしたい場合、どうやるのだろう？と思いやってみたメモ的内容です。

## やりたいこと
年月日ごとの売上、数量、利益、割引率をExcelの表っぽく表示させたい！

#### 例1）日付ごとのデータをテキスト表にしたい（縦表示）
![35.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3693459/1bb6af8c-7a41-95ff-4eb3-102e6790eb13.png)


■ 作成結果

> STEP
> 1.　左のテーブルから出荷日を「行」にドラッグアンドドロップする。
![28.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3693459/d4660beb-56e1-5a47-2b71-6d421de517ac.png)
> 2.　左のテーブルからメジャーネームを「行」にドラッグアンドドロップする。
> 3.　左のテーブルからメジャーバリューを「テキスト」にドラッグアンドドロップする。（真ん中のメジャーバリュー欄が自動で出る）
![29.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3693459/ea9bc289-0cf3-4bac-8200-5389c15f3370.png)
> 4.　真ん中のメジャーバリュー欄から不要な項目を欄外にドラッグアンドドロップして削除する。
![30.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3693459/f66395d5-d3e2-2a97-ebf2-0aba102fbe29.png)

イメージ通りのが出来た。
が、なんでメジャーネーム、メジャーバリューを使うと出来るのかはよくわからない。。

■ 駄目だったやつ

＞ぽいぽいとほしい項目を放り込んだ
> STEP
> 1.　左のテーブルから出荷日を「行」にドラッグアンドドロップする。
> 2.　左のテーブルから売上を「テキスト」にドラッグアンドドロップする。
> 3.　左のテーブルから数量を「テキスト」にドラッグアンドドロップする。
> 4.　左のテーブルから利益を「テキスト」にドラッグアンドドロップする。
> 5.　左のテーブルから割引率を「テキスト」にドラッグアンドドロップする。
![27-1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3693459/6094ec58-14cd-e7ec-eed1-9ef047d73e1f.png)

う～ん・・何の数値か分からない

Excelでいうとセルの中に複数数値が入っている感じ・・

数値に対応したラベルだけの列が出て欲しいけど・・

> STEP
> 1.　テキストラベルの編集をしてみた
![25-1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3693459/51f799a2-2cde-16a1-952d-9dfe8ec2c478.png)

なんか違う(>_<)


#### 例2）日付ごとのデータをテキスト表にしたい（横表示）

■ 作成したいイメージ
![36.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3693459/e26431f8-cd16-9097-6613-33b81212385d.png)


■ 作成結果
> STEP
> 縦バージョンを作った前提です。
> 1.　行と列の交換のアイコンをクリック
![31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3693459/0c6ecbb5-d003-9c49-3558-f06663cb4881.png)
![32.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3693459/98d0e876-ce3f-c2ba-fdfb-2c6f4ef5fbe0.png)



### あとがき
複数項目を出したいときは、メジャーネーム、メジャーバリューを使えばよいのかな？？
A Tour of Goエラー：zsh: command not found: gotour

# 概要
A Tour of Goをスタンドアロンで動かそうとした時に出たエラーの解消方法について記載しています。
（所要時間1分）
![スクリーンショット 2024-03-02 16.27.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631096/8e357352-ce46-dd56-0c68-a91f018a6907.png)

## 今回起きたエラー
記事に書いてある通りに下のコマンドを実行した時にエラーが出ました
```
go tool tour
```

エラー：
![スクリーンショット 2024-03-02 16.29.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631096/d915dd23-8014-ac05-b1ed-365325ea70ff.png)

## 解決方法
下のコマンドを実行
```
# install
go install golang.org/x/website/tour@latest
# tourがインストールされているかを確認
ls ~/go/bin
# PATHを設定(.zshrc or .bashrcに以下を追加)
export PATH=$PATH:~/go/bin
# 再読み込み
source ~/.zshrc
# tourを起動
tour
```

参照：英語版のA Tour of Go
https://go.dev/tour/welcome/3

## スタンドアロンの起動イメージ
http://127.0.0.1:3999/welcome/1
で起動しています。

![tourofgo_errror.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631096/a127ddc1-7279-dfa8-ce82-560b65d77b80.jpeg)


以上です！！
AzureADについて

### はじめに
業務中にAzureADという単語がよく出てくるが、
ちゃんと理解できていなかったため、まとめてみる。
<br>
### 結論
Microsoft社が提供している「Azure」上のサービスの一つで、複数のクラウドサービスのアカウント管理が一括でできるサービスのこと。

【主な特徴】
**・Microsoftのアカウント情報のみだけではなく、Amazon Web ServiceやGoogle Cloud、Salesforceなど、クラウド上の様々なアプリケーション情報を登録できる。
・グループやユーザー単位で使用できるアプリケーションのアクセス管理が可能。
・シングルサインオンを実装している。**
<br>
### まとめ
AzureADはクラウド上で、ユーザーのアカウントやセキュリティを管理するサービス。オンラインでのログインが簡単で、セキュリティもしっかり守られているから安心して利用できる。


<br>

[参考サイト]
・https://business.ntt-east.co.jp/content/cloudsolution/column-444.html
カレーちゃんから学ぶChatGPTの使い方

### 趣旨
最近Chat-GPTをよく使います。
そんな中カレーちゃんという人が、ChatGPTの解説をしている動画を目にしました。
これをみて、「自分はまだまだChatGPTが使いこなせていないのでは」と思いカレーちゃんから学ぶことにしました。自分が学んだことをまとめます。


### ソース・引用元
1. [【Google &東大松尾研の天才】ガチ議論！AI使いこなす裏技とは？【プロンプト入門】](https://www.youtube.com/watch?v=MblAcX9u9s0)

2. [面倒なことはＣｈａｔＧＰＴにやらせよう](https://amzn.to/4bZFCbC)
<a href="https://amzn.to/4bZFCbC" target="_blank"><img border="0" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138863/f1577e18-f511-9b0d-80a5-77c58f20b12f.png" width="200"></a>

### Tips(基礎編)
- ChatGPTの原理: 何かを入力すると、それに続く単語を、一単語づつ予測する。=> そのためInputが正確であればあるほど、Outputが正確になる。

![logic.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138863/eda66045-6506-616b-26e5-5e55d17ffa70.png)


- なるべく具体的に指示する
どのような出力が欲しいか、具体的かつ簡潔に伝える

![point1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138863/36e829a6-646b-86dc-d5b4-ec750da20621.png)

「高校生に説明するように、」
「2文で説明するように、」
などがポイント。

- ChatGPTは非決定的アルゴリズム。なのでうまくいかない時はもう一回聞きなおすとかも有効なことがある。


### Tips応用編
- Few-Shotプロンプティング: 解答例を示すことで、解答の精度を上げる

![few-shot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138863/5132698c-6387-3c1a-bf24-f060d9247165.png)

- Chain-of-Thoughtプロンプティング: 回答を順序立ててステップ毎に出力してもらう方法
```「ステップバイステップ」で考えてみましょう。```と末尾に入れてみる。

このように、考え方まで教えると論理的な問題も解けるのは知らなかったです。

![chain-of-thought.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138863/19ea628b-fe40-50a5-18d8-04920405f455.png)

- グラフとか、図とかに、日本語入れたい時は日本語フォント入れればいける
いつも文字化けして、仕方ないと思ってた。

(フォントダウンロード先)
https://fonts.google.com/noto/specimen/Noto+Sans+JP

フォント指定しない場合

![no-font.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138863/3fc7aeee-599c-3d64-d6ec-31442ac820d5.png)

フォント指定した場合

![selected-font.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138863/a0b37bf0-aad3-6449-0800-e3cdb475e87f.png)


- 写真とかを入れて「画像を説明して、その説明をもとにアニメ調の画像を生成してください」などでアニメ調の画像を作れる。

![make-image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138863/30a6698c-aed2-f2f0-cfde-8e3be3740c63.png)



### 最後に
カレーちゃんからChat-GPTのより良い使い方を学び、役立ちそうな部分をまとめました。
これをベースに試行錯誤していければと思います。
より詳細知りたい方は、動画または本を見てみてください。
(個人手には本は、少し初心者向けの要素が強い気もしました。)

最後まで見ていただきありがとうございました。

### ソース・引用元
1. [【Google &東大松尾研の天才】ガチ議論！AI使いこなす裏技とは？【プロンプト入門】](https://www.youtube.com/watch?v=MblAcX9u9s0)

2. [面倒なことはＣｈａｔＧＰＴにやらせよう](https://amzn.to/4bZFCbC)
<a href="https://amzn.to/4bZFCbC" target="_blank"><img border="0" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138863/f1577e18-f511-9b0d-80a5-77c58f20b12f.png" width="200"></a>
Android+RetrofitでHTTP通信するアプリの作り方（その３）

# Depnedency Inejectionの活用

前回の記事でHiltを導入しました。

今回の記事ではHiltを使ってInjectするように組んでいきます。

## 目次
- [Depnedency Inejectionの活用](#depnedency-inejectionの活用)
  - [目次](#目次)
  - [通信層をInjectする](#通信層をinjectする)
    - [Modules](#modules)
    - [@Inject](#inject)
  - [できあがり](#できあがり)
  - [リポジトリ](#リポジトリ)

## 通信層をInjectする

実際にInjectしてみましょう。

現在のところ、このアプリの機能はJsonPlaceHolderと通信することだけです。

なので、JsonPlaceHolderと通信する機能をInjectするように修正します。

### Modules

InjectするインスタンスはModuleに定義します。

```kotlin
@Module
@InstallIn(SingletonComponent::class)
object ApplicationModule {

    /**
     * Retrofitのインスタスを供給する
     * urlはhttps://jsonplaceholder.typicode.com/、converterはGson
     */
    @Provides
    fun provideRetrofit(): Retrofit {
        return Retrofit.Builder()
            .baseUrl("https://jsonplaceholder.typicode.com/")
            .addConverterFactory(GsonConverterFactory.create())
            .build()
    }

    /**
     * RetrofitのインスタンスからJsonPlaceHolderAPIインターフェイスのインスタンスを生成し供給する
     */
    @Provides
    fun provideJsonPlaceHolderAPI(
        retrofit: Retrofit
    ): JsonPlaceHolderAPI{
        return retrofit.create<JsonPlaceHolderAPI>()
    }
}
```

### @Inject

`MainActivity`の`jsonPlaceHolder`をInjectするように修正します。

1. 以下は削除する
    ```kotlin
    @AndroidEntryPoint
    class MainActivity : ComponentActivity() {
        ...
        // ここから削除
        private val retrofit = Retrofit.Builder()
            .baseUrl("https://jsonplaceholder.typicode.com/")
            .addConverterFactory(GsonConverterFactory.create())
            .build()
        // ここまで削除
        ...
    }
    ```
2. jsonPlaceHolderAPIをInjectするよう修正
    ```kotlin
    @AndroidEntryPoint
    class MainActivity : ComponentActivity() {
        ...
        @Inject
        lateinit var jsonPlaceHolderAPI: JsonPlaceHolderAPI
        ...
    }
    ```

## できあがり

MainActivityがだいぶすっきりしました。

## リポジトリ

<https://github.com/aburagirio/retrofitExample.git>

ブランチ`part3`をcheck outしてください。
Windows 11が勝手にスリープ解除されていつの間にか起動されるのをなんとかする（できた）話

# 解決できた対処法を先に
コントロールパネルの自動メンテナンスを開き「スケジュールされたメンテナンスによるコンピューターのスリープ解除を許可する」のチェックを外す
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/730454/0ed21087-d30f-1068-23ee-bdb942322e96.png)
コントロールパネルの電源オプションを開き「コンピューターがスリープ状態になる
時間を変更」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/730454/e014027f-41e7-b6d0-c657-4ccec6093ae9.png)
プラン設定の変更画面が開くので「詳細な電源設定の変更」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/730454/cf6f5f74-3d1e-0496-a3f1-30e17c14de66.png)
電源オプションが開くので「スリープ解除タイマーの許可」を**無効**にする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/730454/942421ec-4960-f52c-9d66-0bf2662bf3fe.png)
AWSの公式ハンズオン集

DVAの資格取得に向けてUdemyの試験問題を軽く解いてみたがAWSコードサービス周りの知識が曖昧なのでハンズオンとかでイメージ掴もうと調べてみた。

以下に公式のハンズオンが載ってあり、いくつかの個人情報入れると動画でハンズオンできるので、これでイメージが曖昧なサービスは手を動かして覚えるようにしておきたい
https://aws.amazon.com/jp/events/aws-event-resource/hands-on/
大規模システム開発用ドキュメント標準のサンプル - ComponentAA開発標準


大規模システム開発用のドキュメント標準のサンプルをgithubで公開しました → [[ComponentAA開発標準（ドキュメント標準編）1.0a版]](https://github.com/kagiya00/componentaa_development_standards)

ドキュメント標準とは、コンピューターシステム開発における要求定義/設計/構築/テストを実施するためのドキュメントの標準を規定したものです。ドキュメントの雛形、記述例、作成手順、記述要領、ドキュメント作成に必要となる用語や概念の解説などが含まれています。

![fig1_ドキュメント標準のイメージ.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/471567/24caf948-3b08-0e00-0707-b6f1b3f00a9c.jpeg)
図：ドキュメント標準のイメージ(ComponentAA開発標準より引用）

システム開発プロジェクトで利用されていることはもちろん、しばしば調査・研究の対象にもなっているのですが、一般公開されている事例はあまり多くありません。特に、大規模システム開発に適用可能な本格的なものはほとんどないようです。

ComponentAA開発標準は、かつて富士通株式会社から公開されていたのですが、現在は公開が停止されています。しかし、一定の条件のもとで再配布が認められていますので githubで公開することとしました。内容はかなり古いですが、少しでも参考にしていただける部分があれば幸いです。

## 概要

- ComponentAA開発標準（ドキュメント標準編）1.0a版は、[富士通株式会社](https://global.fujitsu/ja-jp/)が2004年に作成し、2007年に一般公開しました
- 添付の使用許諾条件に従う条件で、使用、複製、改変、再配布が認められています

## 特徴

- 全体
  - 開発手法：ウォーターフォール
  - 適用対象システムの規模： 中規模～大規模向け （数10k steps程度以上向けと思われます）
  - ドキュメントの雛形はExcel形式です。解説資料は word および power point 形式で作成されています。
  - UML記法が部分的に取り入れられています。
- 要件定義工程ドキュメントは汎用性があります。リリースから20年経た現在でも利用可能なドキュメントは多いでしょう。
- 設計および構築工程ドキュメントは、2004年当時に主流だったアーキテクチャと技術に最適化されています。現在利用されているアーキテクチャや技術にはフィットしない部分が多いと思います。ドキュメント体系など抽象レベルの考え方は参考にできる部分があるかもしれません。
  - アプリケーション形態は、オンライン処理（３層構造／２層構造）、および、バッチ処理に対応しています。
  - オンライン処理のプレゼン層は、Java(Servlet/Applet/Javaアプリ)に最適化されています。
  - オンライン処理のアプリ層は、Java(EJB)およびCOBOLに最適化されています。
  - 言語は、Java および COBOL に最適化されています。
- ComponentAA開発標準のエッセンスは、IPAの「機能要件の合意形成ガイド」にも反映されました。

## 参考情報

- [ComponentAA開発標準 ご紹介資料](https://www.fujitsu.com/downloads/JP/archive/jp/jsdas/document/caa-intro20040520.pdf), 富士通株式会社, 2004/5/20
- [開発プロセスの標準化とWebアプリケーション開発への対応](https://www.fujitsu.com/downloads/JP/archive/imgjp/jmag/vol57-1/paper03.pdf), FUJITSU, 2006/1, 斉藤涼子/沖山智/平井宣
- [ComponentAA開発標準の実践適用事例](https://www.fujitsu.com/downloads/JP/archive/imgjp/jmag/vol57-1/paper12.pdf), FUJITSU, 2006/1, 米村有三
- [機能要件の合意形成ガイド](https://www.ipa.go.jp/archive/digital/iot-en-ci/jyouryuu/ent03-a.html), IPA, 2010/3

以上
Qiitaから記事をエクスポートする

## はじめに

個人ブログを作りたく、Qiitaの記事を引っ越したいなぁと思っていたのですが、
どうやら機能としてエクスポートはサポートされていない様子。

手間かけずにMarkdownで出力できないかと調べていたら既に先人がいらっしゃったので参考にしました。

## 記事のエクスポート
ほとんど以下の記事の内容で出力できました。ありがたや。。
https://qiita.com/Trouble_SUM/items/d14ec5abae867b9e5a6b


少し手を加えた部分として、一発のAPIで取得できる項目数がデフォルト 20 なので、`per_page`を指定することで取得数を上書きしています。
```
wget $(curl -H Bearer 5f7c14db673f13a831867b66a4a8f4dc6e32d3bf -s 'https://qiita.com/api/v2/users/<ユーザID>/items?per_page=50' | jq -r '[.[].url+".md"]|join(" ")')       
```
ai_extract関数によるテキストデータの構造化

こちらでウォークスルーしている際に気になった関数の一つが[`ai_extract`](https://qiita.com/taka_yayoi/items/9b4a6a2b458959afec7d#%E5%9B%BA%E6%9C%89%E8%A1%A8%E7%8F%BE%E3%82%92%E6%8A%BD%E5%87%BA%E3%81%99%E3%82%8Bai_extract)関数でした。

https://qiita.com/taka_yayoi/items/9b4a6a2b458959afec7d

テキストデータそのままですと、検索するくらいしか使い道がなかったのですが、この関数を使うことで色々な観点から構造化データを作り出すことができます。

早速トライしてみます。使うデータは自分のQiita記事です。

```sql
select * from `takaakiyayoi_catalog`.`qiita_2023`.`taka_qiita_2023` limit 100;
```
![Screenshot 2024-03-02 at 15.52.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/c8fe96e0-aa69-c43b-c19f-ab2fb93614a9.png)

こちらの`body`列に`ai_extract`を適用します。ai_extractの結果はSTRUCT型なので要素を取り出して列にしています。[CTE(Common Table Expression)](https://docs.databricks.com/en/sql/language-manual/sql-ref-syntax-qry-select-cte.html)を使ってます。

```sql
CREATE OR REPLACE TABLE takaakiyayoi_catalog.qiita_2023.taka_qiita_llm AS 

WITH extracted_data AS (
  SELECT
    title,
    body,
    ai_extract(body, array("製品名", "機能名", "ジャンル")) AS extracted
  FROM
    qiita_2023.taka_qiita_2023
  LIMIT
    10
)

SELECT
  title,
  body,
  extracted.`製品名` AS product,
  extracted.`機能名` AS feature,
  extracted.`ジャンル` AS genre
FROM
  extracted_data;
```

テーブルを確認します。

```sql
SELECT
  title,
  product,
  feature,
  genre
FROM
  takaakiyayoi_catalog.qiita_2023.taka_qiita_llm;
```
![Screenshot 2024-03-02 at 16.00.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/40332fbf-271c-536b-7de3-23268b671335.png)

これまでは、テーブルを設計する際にどのようなメタデータを管理するか(ある意味構造化)を考えるのが普通でしたが、LLMを活用することでとりあえずテキストを登録しておいて、後からメタデータを抽出して構造化することができるようになりました。興味深い。

### はじめてのDatabricks

[はじめてのDatabricks](https://qiita.com/taka_yayoi/items/8dc72d083edb879a5e5d)

### Databricks無料トライアル

[Databricks無料トライアル](https://databricks.com/jp/try-databricks)
BlazorでJavaScript(今回はECharts)を使う

# 動作画面
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136187/6261fbdb-f824-0f31-3f7e-010dd73255f4.png)

# 前提
.Net8 Blaozr WebAssemblyからJavaScriptのEChartsを使います。

# 設定
* EChartsを[ここ](https://github.com/apache/echarts/tree/5.5.0/dist)からダウンロードしwwwrootにechartsフォルダを作成し保存する

# 利用
EChartsを表示するタグを作成する

```html
<div @ref="chartDiv" id="chartDiv" style="width: 600px; height: 400px;"></div>
```
`@ref="chartDiv"`でDivタグを参照できるようにしておきます

EChartsを読み込み初期化する

``` csharp
private ElementReference chartDiv; //divタグ
private IJSObjectReference? _jsECharts; //EChartsのインスタンス

protected override async Task OnAfterRenderAsync(bool firstRender)
{
    if (firstRender)
    {
        //echarts.jsを読み込む
        await JSRuntime.InvokeAsync<IJSObjectReference>("import", "./echarts/echarts.js");

        //echartsの初期化　インスタンスを_jsEChartsで受ける
        _jsECharts = await JSRuntime.InvokeAsync<IJSObjectReference>("echarts.init", chartDiv);

    }
}

```

EChartsを表示する

```csharp
//表示データ
var options = new
{
    animationDuration = 0,
    tooltip = new { },
    xAxis = new
    {
        data = new string[] { "shirt", "cardigan", "chiffon", "pants", "heels", "socks" }
    },
    yAxis = new { },
    series = new[]
    {
        new
        {
            name = "sales",
            type = "line",
            data = new int[] { 5, 20, 36, 10, 10, 20 }
        }
    }
};

//表示データを設定
await _jsECharts.InvokeVoidAsync("setOption", options);
```

EChartsをダウンロードではなくCDNから利用する場合は
```diff
//echarts.jsを読み込む
- await JSRuntime.InvokeAsync<IJSObjectReference>("import", "./echarts/echarts.js");
+ await JSRuntime.InvokeAsync<IJSObjectReference>("import", "https://cdn.jsdelivr.net/npm/echarts@5.5.0/dist/echarts.min.js");
```
とやってください

動作サンプルは[Github](https://github.com/kyamamoto03/EChartsSample.git)に置いておきます。
【GAS】Googleフォームで4択問題を作る

## １ 目的
Googleスプレッドシートに問題を入力しておいて、Googleフォームでテスト・クイズを作ります。問題の形式は4択問題、ラジオボタンとします。フォームに手入力するよりスプレッドシートの方が問題の入力がしやすそうですし、再利用なども簡単そうです。スプレッドシートのコンテナバインドプロジェクトです。

## ２ スプレッドシート
シートは、設定用シートと、問題用シートがあり、それぞれにデータを入力しておきます。

設定用シートは、例では、sheet1という名前にしています。フォームの題名、フォームの説明、問題のシートの名前、問題の数を入力しておきます。スクリプトを実行してフォームが作成されたら、設定シートにフォームのURL（編集用）が入ります。
![Ss_sheet1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/157289/a9103c80-36d2-108d-7eb1-1f1f46c9c102.png)

問題用シートは、1行目が項目名で、2行目以下に問題、正解、解説、配点を入力しておきます。空欄がないようにして下さい。（一応エラーにならないようにはしています）
![Ss_sheet2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/157289/4a4de9ed-6264-7586-75d8-b53fa0706117.png)

## ３ スクリプト
```JavaScript:create4takuForm.gs
function create4takuForm() {
  const myspreadsheet = SpreadsheetApp.getActiveSpreadsheet();
  const mysheet1 = myspreadsheet.getSheetByName('sheet1'); //設定用シート
  const data1 = mysheet1.getRange(2, 2, 4).getValues();
  const formTitle = data1[0]; //フォームの題名
  const formDescription = data1[1]; //フォームの説明
  const mysheet2 = myspreadsheet.getSheetByName(data1[2]); //問題用シート
  const quiz_num = data1[3]; //問題の数
  let myform =FormApp.create(formTitle); //フォームを作成
  myform.setDescription(formDescription);
  myform.setIsQuiz(true);  //テストにする
  myform.setShowLinkToRespondAgain(true); //再回答するリンクを表示
  myform.setCollectEmail(false); //メールアドレスを収集しない
//問題文データを取得
  let questionList = mysheet2.getRange(2, 1, quiz_num, 9).getDisplayValues();
  //空欄を無くす
  for(let i = 0; i < quiz_num; i++) {
    for (let j = 0; j < 9; j++) {
      if (questionList[i][j] == '') {
        questionList[i][j] = j;
      }
    }
  }
  for(i = 0; i < quiz_num; i++) {
    let choices;
    let item = myform.addMultipleChoiceItem(); //ラジオボタン
    //選択肢と正解かどうか
    choices = [
      item.createChoice(questionList[i][2],questionList[i][7]==1),
      item.createChoice(questionList[i][3],questionList[i][7]==2),
      item.createChoice(questionList[i][4],questionList[i][7]==3),
      item.createChoice(questionList[i][5],questionList[i][7]==4)
    ]
    //問題文をセット
    item.setTitle(questionList[i][0]+'\n'+questionList[i][1]); //問題のタイトルと問題
    item.setChoices(choices); //選択肢
    item.setPoints([questionList[i][8]]); //配点
    item.setRequired(true); //回答必須
    //フィードバックをセット
    item.setFeedbackForCorrect(FormApp.createFeedback().setText(questionList[i][6]).build());
    item.setFeedbackForIncorrect(FormApp.createFeedback().setText(questionList[i][6]).build());
  }
//作成したフォームの編集用URLをシートに書き込む
  mysheet1.getRange('B6').setValue(myform.getEditUrl());
//終了メッセージ
  console.log('フォーム「' + formTitle + '」を作成しました');
}
```
## ４ 使い方
設定用シートにボタンを作ってそこからcreate4takuForm関数を実行するようにしました。フォームができると、設定用シートの「フォームのURL（編集用）」にURLが入りますので、ここからフォームを開き、設定をして、「送信」すればリンクができますのでこれを回答者に知らせます。「成績の発表」を「送信直後」にするように設定したかったのですが、GASでは出来そうになかったので手動で設定しています。問題用シートを作りためておけばどんどんフォームを作ることができます。

## ５ 参考
- [【GAS】スプレッドシートからテスト用のGoogleFormを自動生成する](https://qiita.com/aki_number16/items/e2ac30e7c4d2d44a02ad)（@aki_number16）
- [スプレッドシートからテスト用Googleフォームを作成するGAS](https://blog.synnex.co.jp/google/gas-google-form-from-spreadsheet/)（TD SYNNEX）
Ubuntu 22でGoogle ChromeのPWAが「アプリケーションを表示する」で表示されない

## 状況
1. Ubuntu 22 + Google Chrome 122.0で、PWA（Progressive Web Apps）を作成
1. いつもならUbuntu Dockの「アプリケーションを表示する（アプリケーション一覧）」の中にPWAのアイコンが追加されているが、追加されない
1. Terminalの``cd ~/.local/share/applications``で確認すると、``chrome-[...]-Default.desktop``といったファイルが存在する
1. にもかかわらず、「アプリケーションを表示する」の中には表示されない

## 解決
 1. Google Chromeで、アドレスバーに``chrome://apps/``を入力して、管理画面に行く
 1. アイコンの表示されないPWAを右クリックして「アンインストール」を選ぶと、削除確認が出てくるので、ここで「Chrome（[PWAのURL]）からもデータを削除する」にチェックを入れて、削除を行う（ぼくの場合Google Keepで、その内容が消えてしまうのではないかと心配したが大丈夫）
 1. もういちど、PWAを作成し直すと、今度は、「アプリケーションを表示する」の中にアイコンが表示されました

## 解決2 (2024年08月08日 加筆)
 1. Google Chromeで、アドレスバーに``chrome://apps/``を入力して、管理画面に行く
 1. アイコンの表示されないPWAを右クリックして「ショートカットを作成」を選ぶと、「アプリケーションのショートカットを作成」のウィンドウが表示され、「デスクトップ」「アプリケーションメニュー」から選択できるので、選択する

## やったけど解決できなかったこと

- 再起動
- パーミッションの見直し
- デスクトップエントリーのファイルの中身をコピーアンドペーストして複製
ONNXをCLIで編集する


お手軽にONNXを編集する方法が

- [ONNXモデルのチューニングテクニック (基礎編)](https://cyberagent.ai/blog/tech/17300/)
- [ONNXモデルのチューニングテクニック (応用編１)](https://cyberagent.ai/blog/tech/17657/)

に書かれていたので、  
自分が実際に使わせて頂いた例を紹介する

## 方法1. PINTOさん製ツールを使用してJSONを編集

1. [onnx2json](https://github.com/PINTO0309/onnx2json) でONNXをJSONに変換
2. JSONをテキストエディタで開いて編集
3. [json2onnx](https://github.com/PINTO0309/json2onnx) でJSONをONNXに変換

最初はこの方法で編集していたのだが、  

- JSONの行数がかなり多くなるため、編集するのが大変
- モデルを更新する度に手編集するのが面倒

という理由で、後述の方法に切り替えた

## 方法2. PINTOさん製ツールを使用してCLIで編集

JSONを手編集するよりもずっと楽  

| ツール                                            | 役割                 |
| ------------------------------------------------- | -------------------- |
| [soa4onnx](https://github.com/PINTO0309/soa4onnx) | Nodeの追加           |
| [sod4onnx](https://github.com/PINTO0309/sod4onnx) | モデルの出力OPを削除 |
| [sor4onnx](https://github.com/PINTO0309/sor4onnx) | Node名の書き換え     |

※他にもツールはいっぱいあるが、ここでは使用した物のみを記載  

## 実際に使ってみた

赤線より下のNodeを削除して
![origin.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/675511/74af0abc-37c5-e7ed-6eee-6db151c4838a.png)

3つの出力OPに分離させた  
![output123.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/675511/f533e911-fe9a-a91b-f80c-fc27f45814bb.png)

※特定のハードとソフトで使えないNodeが含まれていたため、このような面倒なことをする必要があった

手順を以下に記載する

### 1. [soa4onnx](https://github.com/PINTO0309/soa4onnx) で出力OPを追加

```sh
soa4onnx \
--input_onnx_file_path  "models/yolov7-tiny.onnx" \
--output_op_names       "259" "293" "327" \
--output_onnx_file_path "models/yolov7-tiny_grafted.onnx"
```

出力OPが追加される  
こいつを新しいoutputとし、元からある方(赤線より下のNode)はこの後の手順で削除する  
![grafted.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/675511/326a7baa-b43c-4aa0-dbb7-26157c053d31.png)

### 2. [sod4onnx](https://github.com/PINTO0309/sod4onnx) で不要なoutputとNodeを削除

削除対象の出力OPを指定するだけで、不要になるNodeも自動的に削除してくれるので便利

```sh
sod4onnx \
--input_onnx_file_path  "models/yolov7-tiny_grafted.onnx" \
--output_op_names       "output" \
--output_onnx_file_path "models/yolov7-tiny_grafted_output_removed.onnx"
```

### 3. [sor4onnx](https://github.com/PINTO0309/sor4onnx) で出力OPをリネーム

この手順は必ずしも必要なわけではないが、  
出力OPの名前が謎の数字だったりすると後で混乱するため、  
分かりやすい名前にリネームした方が良い

```sh
# output1
sor4onnx \
--input_onnx_file_path  "models/yolov7-tiny_grafted_output_removed.onnx" \
--output_onnx_file_path "models/yolov7-tiny_grafted_output_removed.onnx" \
--old_new               "259" "output1" \
--mode                  outputs \
--search_mode           exact_match

# output2
sor4onnx \
--input_onnx_file_path  "models/yolov7-tiny_grafted_output_removed.onnx" \
--output_onnx_file_path "models/yolov7-tiny_grafted_output_removed.onnx" \
--old_new               "293" "output2" \
--mode                  outputs \
--search_mode           exact_match

# output3
sor4onnx \
--input_onnx_file_path  "models/yolov7-tiny_grafted_output_removed.onnx" \
--output_onnx_file_path "models/yolov7-tiny_grafted_output_removed.onnx" \
--old_new               "327" "output3" \
--mode                  outputs \
--search_mode           exact_match
```
【Ruby】名鉄津島線の準急・急行・特急停車駅判定

名鉄津島線の急行停車駅判定プログラムを作りました。


```ruby
# 名鉄津島線の急行停車駅(準急・特急も同じ)駅名表示

tsushima_line_data = ["須ヶ口","甚目寺","七宝","木田","青塚","勝幡","藤浪","津島"]
express_stop_data = ["須ヶ口","甚目寺","木田","勝幡","津島"]
station_num = tsushima_line_data.length
express_stop_num = express_stop_data.length

for i in 0...station_num do
  station_info = tsushima_line_data[i]
  express_stop_flag = express_stop_data.index(station_info)
  # print(express_stop_flag)
  if express_stop_flag == nil then
    puts "#{station_info}駅は急行停車駅ではありません"
  else
    puts "#{station_info}駅は急行停車駅です"
  end
end

```

結果は次の通りです。

```
須ヶ口駅は急行停車駅です
甚目寺駅は急行停車駅です
七宝駅は急行停車駅ではありません
木田駅は急行停車駅です
青塚駅は急行停車駅ではありません
勝幡駅は急行停車駅です
藤浪駅は急行停車駅ではありません
津島駅は急行停車駅です
```
【SIer日記】基本設計書、詳細設計書作成を経験した気づき、感想など

# はじめに
最近基本設計書、詳細設計書を作成する機会があり、気づいたこと、感想などを書いてみたいと思います。
今回初めて設計書作成に取り組んでいるので、学びを備忘録的に書いてみたいなといった感じです。
※一般的にどうかは置いておいて、私の主観なのでご注意ください。 
# 前提
- プロジェクトメンバは10名程度、開発メンバとして参画
- 参考資料は要件定義書、Q＆A表(要件定義書の疑問点のすり合わせ用)
- 私の開発経験は、詳細設計をもとにjavaSpring、html、css、SQLでのコーディングを半年ほど行ったのみ→ペーペー
- システムを使う側→顧客、システムを作る側→PJ側と呼ぶことにします
# 気づき、感想など
### PJ参画直後
まず、PJに参画してはじめに感じたことは「参考資料少なっっ」でした。
今まではしっかりした詳細設計書（不足があったり文句を言いたくなった部分もあったが）がありました。私はそれに準じた処理をコードとして落とし込めばよかったのですが、基本設計書作成ではそうもいきませんでした。
### 基本設計書作成において気づいたこと
- **基本設計書は「顧客がシステムの概要を理解できるように、PJ側が説明することを前提にした設計書」**
私がPJメンバーに質問したり、設計書を作成したりしてきたイメージはこれでした。
システムを利用する人が見る画面や画面項目であったり、利用する機能の概要を盛り込むのが基本設計書であると認識しています。

- **基本設計書が作成できるだけの情報が、要件定義書作成時点で存在するわけではない**
どうやら作成した要件定義書から不足があれば、それを顧客にQAとして提示し解消する。または、基本設計書で要件定義書とシステムの差分を埋めるように内容を盛り込む。などをして、顧客とシステム要件をすり合わせていくようです。
イメージしていたウォーターフォール型開発は、下流から上流に戻ることはないと思っていましたが、そうでもなさそうでした。たしかに、戻らなくていいくらいに抜け漏れなく検討するのはなかなか難しいですし、戻ることを前提にした方がスピード感はありそうですね。（アジャイルとも言えなそう）

### 詳細設計書作成において気づいたこと
- **詳細設計書は「開発者が処理を理解するために参照することを前提とした設計書」**
基本設計書と比較したときの詳細設計書のイメージはこれでした。「基本設計書は顧客寄り、詳細設計書は開発者寄り」で私はしっくりきましたね。
基本設計書で説明されている画面の動きで合ったり処理方式の説明や、説明されている機能は何を引数としてどのような処理を行い、何をレスポンスとして返すのかなど、コーディングするときに必要な情報を記載するのが詳細設計書であると認識しました。
- **詳細設計書作成工程で完璧に完成させることは難しい**
基本設計書と同様、詳細設計書を作成するのに必要な情報が詳細設計書工程の走り出しで出揃っていると思わない方がよいです。
とりあえず、ここまでは作成できる、この部分は後続タスクが完了した時点で正確に記載する。など大まかに進めることも時には必要だと感じました。

# 最後に
誰かの作成した設計書に文句言うのやめます。設計書なかなかムズイ。

まだ、作成している途中なので、どんどん書き足していきたいと思います。