OmniAICreator/Qiita-1.07M huggingface dataset:
世界五流エンジニアの思考法【ブチ切れて覚えるフロントエンド おまけ】

# はじめに
[前回](https://qiita.com/shinononononono/items/48bcdc638aa9ab19c557)の続きとなります。
stylelintのエラー解決のステップにあたり、
たったひとつのことで、必要以上の時間をかけてしまいました。

この記事は反省備忘録です。

# 前回
前回の記事はこちらになります。
[ブチ切れて覚えるフロントエンド【stylelint編】](https://qiita.com/shinononononono/items/48bcdc638aa9ab19c557)

エラー発生にあたり、解決ステップを書いた記事となります。
要約します。
1. エラーが出る（**Unknown rule string-quotes.Stylelint(string-quotes)**）
1. ググる
1. ググる（検索文字列を変える）
1. 公式ドキュメントを見る
1. 設定ファイルを変更する（うまくいかない）
1. 設定ファイルを変更する（うまくいった）

# 世界五流エンジニアの思考法（１）
修正には何十分もかかりました。
時間をかけていた要素を抜粋します。

- ググりすぎ
    実際には、検索を行った後、複数のページを閲覧しています。
    あれも違う、これも違う、となり、再度、検索文字列を変えての検索を行っているのです。検索文字列はエラーメッセージだったので、文字列が完全一致の記事があってもよさそうですが、ありませんでした。
    なかったのにもかかわらず、一生ネットサーフィンしてました。

<br>

- 公式ドキュメントを調べた経緯
    「検索にひっかからなかったなー。じゃあ公式ドキュメント見るかー」
    という経緯ではなく、
    調べていたら偶然「**The "string-quotes" rule is deprecated**」という文字列があり、そこではじめて「Unknown rulesって怒られてるんだから、普通に非推奨とか廃止されている可能性あるな」と思いました。そこでようやく公式ドキュメントを見るという発想になりました。

# 世界五流エンジニアの思考法（２）
- **思えば、なぜ最初から公式ドキュメントを参照しなかったのでしょうか？**

    エラーメッセージには「**Unknown rule string-quotes.Stylelint(string-quotes)**」と書いてあったのだから、廃止されていたりするドキュメントを探せば良さそうです。
    
    
    おそらく、無意識に解決ステップを楽にしたかったのでしょう。調べて、完全一致のエラー解決記事が出ればそれを参照すればいいのだから。
    ここまでは、おそらくですがそこまで問題はない気がします。
    一致する記事があれば、それと公式ドキュメントを比較し、問題なければ適用すればいいですしね。

<br>

- **一致する記事がなければどうすればいいのでしょうか？**
    ここからが問題です。
    私はググり続けました。
    この時点で思考は
    「**なぜこのエラーが起きているか**」
    ではなく
    「**エラーを直さなきゃ**」
    にすり替わってしまっていた気がします。

    「**なぜこのエラーが起きているか**」を考えていれば、
    エラーメッセージから、何を参照すべきかが明確になるはずです。
    
    それが「**エラーを直さなきゃ**」思考になってしまったせいで、次に行うべきアクションが曖昧になり、結果本能的に身についている「ググる」を選択してしまった気がします。

# 世界一流エンジニアの思考法
最近流行しているエンジニア読み物で、
「世界一流エンジニアの思考法」という書籍があります。
牛尾剛さんという方が書いている本です。

[世界一流エンジニアの思考法](https://www.amazon.co.jp/%E4%B8%96%E7%95%8C%E4%B8%80%E6%B5%81%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%AE%E6%80%9D%E8%80%83%E6%B3%95-%E7%89%9B%E5%B0%BE-%E5%89%9B/dp/4163917683)

その中には「生産性の高さ」として
- 「試行錯誤は悪である」こと
- 「理解することに時間をかける」こと

が挙げられていました。

- **試行錯誤は悪である**
今回私は試行錯誤してエラーを修正したわけではなかったので、完全に一致するわけではありません。
しかし、「試行錯誤は悪である」ことで紹介されていた、
「**仮説　→　仮説の証明**」をしていればもっと早く修正ができたと感じました。
<br>

- **理解することに時間をかける**
もう一つ思ったことは、
仮に私が同一事象のエラー解決記事を発見したとして、果たして、そこから公式ドキュメントも参照したのでしょうか？ということです。

    私を含め、多くのよわよわエンジニアの皆さんは、エラー解決を、記事のとおりそのままやってしまう、ということがあります。
    でもそれは今回のケースのみ解決できるだけ（もしかしたら本当は解決できていないかもしれない）で、次に似たようなケースでエラーが出たとしたらもうダメです。
    この思考の修正が「公式ドキュメントをよく見る」につながりそうですし、加えて「理解することに時間をかける」にもつながりそうです。
    今回のケースでは、公式ドキュメントを見ることで「**string-quotes**」が廃止されていることを知り、しかも実はその他項目も、何十種類か廃止されていたｋとも知れたのです。
    このような解決策をとることで「理解」の一要素「応用できる」が満たせる感じがしそうです。


# おわりに
エラーを修正していて、何十分もかかってしまう自分が嫌になると同時に、ハッとすることもありました。

エンジニアという職業を楽しめるようになるため、少しでもいいエンジニアになるために、少しずつ自分の思考を改善しようと思ったいいきっかけとなりました。
React iconsを使う @yukilulu0229

https://react-icons.github.io/react-icons/


## インストール

```
npm install react-icons --save
```

## 使い方

``` Chat.tsx
import React from "react";
import { FaPaperPlane } from "react-icons/fa";

const Chat = () => {
  return (
    <div className="bg-gray-500 h-full p-4 flex flex-col">
      <div className="flex-shrink-0 relative">
        <input
          type="text"
          placeholder="send message"
          className="border-2 w-full rounded pr-10 focus: outline-none p-2"
        />

        <button className="absolute inset-y-0 right-4 flex items-center">
          <FaPaperPlane />
        </button>
      </div>
    </div>
  );
};

export default Chat;

```

```
import { FaPaperPlane } from "react-icons/fa";
```

インポート

```
<FaPaperPlane />
```

使う
PowerShell Seleniumで自動Webサイトログイン

### 注意点
プログラムの実行については、すべて自己責任で行ってください。実行により発生した、いかなる直接的または間接的被害について、作者はその責任を負いません。

### Powershellのバージョン
5.1

### 使用するモジュール
PowerShellget 2.2.5
Selenium 4.0.0-preview3

### 参考にした記事
https://qiita.com/_Sasaki_/items/91224e038ae565fb1a83
https://qiita.com/_Sasaki_/items/7643f5e144641265e8d7
(以下はログイン要の記事)
https://news.mynavi.jp/techplus/article/powershell_core_--234/

### モジュールのインストール（準備含む）

#### (準備)CurrentUserの権限をUnrestricted→RemoteSignedに変更
```
Set-ExecutionPolicy RemoteSigned -Scope CurrentUser
```

#### (準備)PowerShellgetのバージョンを更新
```
Install-Module PowerShellGet -Force -AllowClobber -Scope CurrentUser
```

#### Seleniumをインストール
```
Install-Module -Name Selenium -Force -AllowPrerelease -Scope CurrentUser
```

:::note warn
もしSeleniumに同梱されている各ブラウザのWebDriverが、使用するブラウザのバージョンと合っていなければ、該当するバージョンのWebDriverをダウンロードして置き換える。

▼配布元URLは以下
Edge: https://developer.microsoft.com/ja-jp/microsoft-edge/tools/webdriver/?form=MA13LH#downloads
Chrome: https://googlechromelabs.github.io/chrome-for-testing/

▼各ブラウザのバージョン確認
Edge: 設定→Microsoft Edgeについて
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/649233/5b28f2e6-04f6-64f3-b882-e4c323ffc559.png)

Chrome: 設定→Chromeについて
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/649233/2cbd17c9-db05-a40c-b410-7882f93e7279.png)
:::

### Seleniumを使ってみる

今回はWebサイトにログインしてみる。
サンプルとして以下のWebサイトを使用。
https://hotel.testplanisphere.dev/ja/index.html
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/649233/37de321c-7e37-6484-23b5-015a5aad8378.png)

#### ブラウザを指定してURLを開く
```
Start-SeDriver -Browser Edge -StartURL 'https://hotel.testplanisphere.dev/ja/index.html'
```

#### 要素の取得

```
> XPathで要素を取得
$go_login_page_button = Get-SeElement -By XPath -Value '//*[@id="login-holder"]/a'
```
>1. XPathとは？
>XPath （XML Path Language）は、XMLやHTMLドキュメントのツリー構造から特定の要素や属性値を選択するための言語です。これは特にWebページの情報取得において有用で、Webページは通常HTMLで記述されています。
>ブラウザ（Chrome、Firefoxなど）を使用してWebページのHTMLを表示する際には、F12キーを押すことで対応するHTMLドキュメントに簡単にアクセスでき、XPathを利用して特定のデータを抽出することが可能です。
https://www.octoparse.jp/blog/xpath-introduction

##### XPathの取得方法（Edgeの場合）
XPathを取得したい要素の上で右クリック→「開発者用ツールで調査する」→開発者用ペインが開き、該当箇所が自動選択される→選択されたコード上で右クリック→コピー→XPathのコピーで取得できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/649233/8615d114-c3d3-2936-fa34-1f05386bdd56.png)

#### 取得した要素のクリック
```
Invoke-SeClick -Element $go_login_page_button
```

#### 文字を入力
```
> 入力したい要素を取得
$login_id_area = Get-SeElement -By XPath -Value '//*[@id="email"]'

> 指定した文字を取得した要素に入力
Invoke-SeKeys -Element $login_id_area -Keys 'sakura@example.com'
```
```
> 入力したい要素を取得
$login_password_area = Get-SeElement -By XPath -Value '//*[@id="password"]'

> 指定した文字を取得した要素に入力
Invoke-SeKeys -Element $login_password_area -Keys 'pass1234'
```

#### (おまけ)
ログイン情報を入力しただけでは先に進めないため、ログインボタンを押す必要がある。
```
> クリックしたい要素を取得
$login_submit_button = Get-SeElement -By XPath -Value '//*[@id="login-button"]'

> 取得した要素のクリック
Invoke-SeClick -Element $login_submit_button
```

#### プロセスを終了
```
Stop-SeDriver
```
React

# 命名規則
コンポーネントとカスタムフックの命名規則：大文字で始める必要がある

# 名称
- 関数コンポーネント
  - 画面上に表示する部品を作るためのもの。スタンプのように「ポン」と画面に表示させるために使います
- カスタムフック
  - 特定の機能を簡単に再利用するためのもの。ゲームの「スキルセット」のように、必要な時にいつでも簡単に呼び出せるようにするために使います
タプルについて

<font color = `#ffce44`>※このQiitaで記事を書くことに慣れていない為、誤字・脱字や読みづらい部分もあるかと思いますが、ご理解ください。</font>

閲覧いただき、ありがとうございます！
私は、現在医療業界で働く医療従事者になります。
とある経緯からpythonを勉強中です。
ここでは自分が勉強した事を復習したり、忘れないようにするため記載いたしますので、もしもっとこうした方が良いよ、とかこれはちょっと。。。というものがあれば教えていただけますと幸いです。
※記事内容は随時更新します


## タプルとは何か
　**→複数の構成要素からなる組を総称する一般概念**
①初心者である私からするとリストとよく似ているように感じますが、タプルは一度作成したら要素の変更は出来ないそうです。
②タプルは様々な型が入っていても良いとのこと
```py:例
 t = ("ご飯", 6, [1, 2, 3])
 print(t)
```
出力結果：('ご飯', 6, [1, 2, 3])



## タプルをアンパック
アンパック・・・・右辺にあるタプルの各要素を左辺にある変数へ一気に代入すること

```py:記述
a = ("bird", "dog", "cat")
b, c, d = a
print(b, c, d)
```
出力結果：　　bird dog cat
PowerShellでオブジェクトのプロパティを文字列の中で展開したい【変数展開方法まとめ】

# はじめに
普段JavaScriptをよく書いているため、PowerShellにおいても以下のような書き方でオブジェクトのプロパティを文字列の中で展開しようとしたところエラーになった。
```powershell
Write-Output "My name is ${profile.name}"
```
PowerShellにおける文字列内での変数の展開方法について、JavaScriptと対比しながら簡単にまとめる。

# 1. 変数を文字列の中で展開したい
本題に入る前に、まず基本的な展開方法について復習する。
## ①JavaScriptにおける変数の文字列内展開
文字列連結の基本は以下のように加算演算子（+）を用いたものであるが、
```javascript
const target = 'world';
console.log('hello ' + target);
// 「hello world」と出力される
```
以下のように連結処理を行わず、文字列の中で変数を展開することもできる。
```javascript
const target = 'world';
console.log(`hello ${target}`);
// 「hello world」と出力される
```
JavaScriptで文字列内で変数を展開する場合は、バッククォート（`）を使用し、展開したい変数はダラー（$）を先頭につけて変数名を中括弧（{}）で囲む。

## ②PowerShellにおける変数の文字列内展開
PowerShellにおいても、文字列の連結や変数の展開がJavaScriptと同じように行える。

### 加算演算子を使う場合
```powershell
$target = 'world'
Write-Output('hello ' + $target)
# 「hello world」と出力される
```
### 文字列内で変数を展開する場合
PowerShellの場合はバッククォート（`）ではなくダブルクォーテーション（"）なので注意。
```powershell
$target = 'world'
Write-Output("hello ${target}")
# 「hello world」と出力される
```

### 文字列内変数展開のアンチパターン
以下のように中括弧（{}）を使用せずに変数展開を行うこともできるが、
```powershell
$item = 'apple'
Write-Output("i have an  $item")
# 「i have an apple」と出力される
```
スペース等が無い文字列を作成する場合、失敗するためオススメできない。
```powershell
$item = 'apple'
Write-Output("i have $items")
# 変数$itemsと解釈されるため「i have 」と出力されてしまう
Write-Output("i have ${item}s")
# これなら「i have apples」と出力される
```
# 2. オブジェクトのプロパティを文字列の中で展開したい
本題。

## ①JavaScriptにおけるオブジェクトのプロパティの文字列内展開
プロパティ名まで含めて中括弧で囲めば良い。
```javascript
const profile = {
  name: 'ako',
  like: 'basketball'
};

console.log(`my name is ${profile.name}`);
// 「my name is ako」と出力される
```

## ②PowerShellにおける変数の文字列内展開
プロパティ名まで中括弧で囲んでも **できない**。
```powershell
$profile = @{
  name = 'ako';
  like = 'basketball';
}

Write-Output("my name is ${profile.name}")
# 変数$profile.nameと解釈されるため(?)「my name is 」と出力されてしまう
```
オブジェクトのプロパティを文字列内で展開する場合は括弧（()）を使う。
```powershell
$profile = @{
  name = 'ako';
  like = 'basketball';
}

Write-Output("my name is $($profile.name)")
# 「my name is ako」と出力される
```
ちなみに、コマンドの実行結果をそのまま文字列内で展開したい時もこの方法を使う。
```powershell
$message = "Date: $(Get-Date)"
```
つまるところ、`$()`で一旦コマンド実行されていると解釈するのがよさそう。

# おわりに
私は中括弧での展開ができなかった時に「PowerShellはオブジェクトのプロパティを文字列内で展開する方法はないんだ！」と勘違いして加算演算子を使ってました。
言語によって細かい記法が異なるからあまり思い込みで感覚的に使わない方がよさそうだと反省しました。
~~にしても変数とプロパティで展開方法が異なるのは規則的によくわからんし公式ドキュメントも色んな用法が散らばってるしPowerShellホントきらい~~

## 参考
- [文字列での変数の代入について知りたかったことのすべて - PowerShell 公式ドキュメント](https://learn.microsoft.com/en-us/powershell/scripting/learn/deep-dives/everything-about-string-substitutions?view=powershell-7.4)
Python の defaultdict は参照するだけで副作用が発生するので注意

Python の defaultdict では初期化の処理を一部省略できます。例えば int を指定すれば、デフォルト値を 0 として計算を行ってくれます。

```python
from collections import defaultdict

data = [
  ['chino', 4],
  ['maya', 8],
  ['megu', 2],
  ['chino', 1200],
  ['maya', 800],
  ['megu', 1100],
]

d = defaultdict(int)

for k, v in data:
  d[k] += v

print(d['chino']) # => 1204
```

# `__getitem__` の副作用

ただ、defaultdict には `__getitem__` を呼び出すだけでキーが追加されるという副作用があるため注意してください。例えば、以下の例ではキーが 3個から 7個に増加してしまっています。

```python
print(len(d)) # => 3

probe = ['cocoa', 'chino', 'rize', 'chiya', 'syaro']

for k in probe:
  print(f'{k} => {d[k]}') # __getitem__

print(len(d)) # => 7
```

![観測によって状態が変化する](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78152/4a08b8c2-1bac-0815-5029-02c39cefe6f6.png)

副作用を発生させずに値の取得だけしたい場合は `get(key)` や `get(key, default)` を使用してください。

```python
print(len(d)) # => 3

probe = ['cocoa', 'chino', 'rize', 'chiya', 'syaro']

for k in probe:
  print(f'{k} => {d.get(k, "unknown")}')

print(len(d)) # => 3
```

# 敢えて副作用を発生させるメリット

ですが、敢えて副作用を発生させることで、list や dict などを初期値にすることもでき、実用上は非常に便利な仕様かなと思います。

```python
data2 = [
  ['chino', '香風'],
  ['chino', '智乃'],
]

d = defaultdict(list)

for k, v in data2:
  d[k].append(v)
  # d.get(k, []).append(v) # これはダメ

print(d['chino']) # => ['香風', '智乃']
```

このように、返り値のリストや辞書に対してメソッドを呼び出したりできるようになります。

もし `d.get(k, [])` と書いてしまった場合、新しく生成された `[]` が辞書 `d` に結び付けられないため、その返り値 `[]` に対して `.append(v)` を呼び出しても、その値は辞書には残らず消えてしまうことになります。

# defaultdict の defaultdict

同じパターンで、defaultdict の defaultdict も作ることができます。

```python
dd = defaultdict(lambda: defaultdict(int))

def birthday():
  dd['chino']['age'] += 1
```

この `birthday()` メソッドが初めて呼ばれると、`dd['chino']` という呼び出しによって `defaultdict(int)` のインスタンスが作成され、そのインスタンスに対して `['age']` の値を設定しています。
【Java】カプセル化についての理解を深める

オブジェクト指向の基本原則である「カプセル化」についての理解を”なんとなく”ではなく”しっかり”理解するためのシンプルな備忘録。ここではJavaを用いて説明する。


## カプセル化の基本理解
ざっくり言うと **「①関係性のあるデータをまとめて、②外部から隠すこと」** である。
これによって、ソフトウェアの更新の際にどこをいじればいいのかが明確になり、不用意な更新を防ぐことができる。

### ①関係性のあるデータをまとめる
関係するフィールドやメソッドをひとまとめにすることで、関係性のないデータをクラスから取り除くことができる。これにより、このクラスはこの役割を果たすんだな、とクラスの目的が明確になる。

では、”ひとまとめにする”とはどういうことなのか？
例えば、クラスAとクラスBがあったとする。クラスAのメソッドがBのフィールドにアクセスできる場合は、ひとまとめにされていないと言える。AのメソッドからBのフィールドにアクセスできるのであれば、AのメソッドはBにあるべきだからだ。

### ②外部から隠す（データ隠蔽）
値の書き換えを防ぐにはアクセス制限をかける必要がある。
アクセス制限をかけるには、アクセス修飾子を用いる。
アクセス修飾子は以下の３種類があり、各役割は以下の通り。
| アクセス修飾子 | 役割 |
|:-----------|:------------|
| public       | すべてのクラスからアクセス可能 |
| protected     | 同じパッケージに属する or 継承しているサブクラスからのみアクセス可能 |
| private       | 同じクラス内からのみアクセス可能 |



以上の①②を踏まえて、カプセル化はどのように実装するのか？
Javaを用いた例を挙げる。

## カプセル化の実現
Javaでカプセル化を実現するには、
**⑴ フィールドは非公開にする
⑵ フィールドを使ったメソッドは公開する**
これだけで良い。
なぜなら、フィールドの公開はせず、メソッドを通してのみフィールドへアクセスする形にすれば良いからだ。
フィールドへのアクセスが可能となると意図せず値が更新されてしまう可能性があるので、フィールドは非公開にしなければいけない。
しかし、メソッドも非公開にすると他のクラスから何も操作できない状態となってしまうので、メソッドは公開にする必要がある。

そして、⑴ ⑵ は上の表を参考に以下のようなアクセス修飾子をつければ実現する。

⑴ フィールドの非公開　→ **private**
⑵ フィールドを使ったメソッドの公開　→　**public**
ここで１点注意すべきなのが、すべてのメソッドを公開にする必要はなく、必要なものだけで良いと言うことだ。

Javaのコード例を挙げると以下の通り。

```
public class Hoge {
 private int num;　　　　//フィールドは非公開に
 public int getNum() { return num; }　 //フィールドの値を得るだけなので公開で良い
 private void setNum(int num) { this.num = num; }　//フィールドの値を操作するので非公開に
}
```

どのメソッドを公開・非公開にするべきなのかしっかり見極めることがカプセル化の実装において重要なのだと思った。
[入門] chatgpt gpts knowledge を使う

# gptsでオリジナルのデータを使いたい

独自データ(社内データや個人データ等のローカル情報)を利用可能。

# ファイル制限

1GPTあたり20ファイル(2023年12月時点)

最大 512 MB 、2,000,000 トークン以下
ひらがなと感じが入り混じった文章の1.5万字前後

制限を超えるファイルは分割して登録しよう

# 以下のファイル推奨

・英語
・txt形式 (utf-8必須)
・データサイズは軽く
・簡潔に体系立てて整理されている
・分類整理を確実に行うこと

# ステップ (Instructions)

・多すぎるとユーザーが使いづらい
・少ないと出力精度の悪化、出力速度の低下

例えば以下のようにする

```
【Name】Japan Disaster Prep Guide

【Description】日本の各都道府県レベル(市区町村を除く)の防災計画を参照できます。まずは、調べたい地方を選んでください。

【Instruction】
#ステップ1
Conversation startersで選択された地方に基づき、「#地方一覧」を参考にして自動的にステップ2に移行してください。

#ステップ2
ユーザーに対してどの都道府県の防災計画が知りたいか「#質問例1」のように質問してください。他のことは質問しないでください。

#ステップ3
各種計画の内、どの災害に応じた計画が知りたいか「#質問例2」のように質問してください。他のことは質問しないでください。

#ステップ4
・ステップ2とステップ3で選択された項目に基づき、「#キーワード」を含む計画をKnowledgeのUpload filesの中から必ず検索してください。
・もし、該当する計画がない場合、「選択された都道府県には該当する計画がありません」と答えて下さい。

#ステップ5
・該当する計画が見つかったら、自動的に該当計画の中にある目次を列挙して、「#質問例3」のように何が知りたいか質問してください。

#ステップ6
・ユーザーの質問に基づき、計画内の該当する目次の節と節の中に記載のある文章を要約せず正確に出力してください。
・出力内容がまだ残っている場合、「他にも節が残っています。知りたい場合、『つぎ』と入力してください」と言ってください。残っていない場合は「この項目内に記載のある事項は以上です。他に知りたいことはありますか？」と言ってください。

#その他
国内外の利用者に対応するため、質問された言語で回答してください。

#地方一覧
・北海道、東北地方:北海道、山形県、福島県、秋田県、青森県、宮城県、岩手県
・関東地方:東京都、栃木県、埼玉県、神奈川県、茨城県、群馬県、千葉県
・北陸地方:富山県、石川県、新潟県、福井県
・中部地方:長野県、三重県、愛知県、岐阜県
・近畿地方:和歌山県、奈良県、兵庫県、京都府、滋賀県、大阪府
・中国地方:島根県、山口県、広島県、岡山県、鳥取県
・四国地方:愛媛県、徳島県、香川県、高知県
・九州、沖縄地方:福岡県、鹿児島県、熊本県、宮崎県、長崎県、大分県、佐賀県、沖縄県

#質問例1
A:北海道
B:青森県
C:岩手県
D:秋田県
E:山形県
F:福島県
G:宮城県

#質問例2
A:地震
B:津波
C:風水害
D:原子力
E:火山
F:大規模事故
G:本編、基本計画

#キーワード
災害の種類に応じた防災計画ごとに以下のいずれかのキーワードが計画のファイル名に含まれています。
・地震:jisintsunami,sinsai,jishin,jisin,nankaitorafu,jisinshiryou
・津波:tunami,tsunami,jisintsunami,tsunamishiryou
・風水害:huusuigai,huusuigaishiryou
・原子力:genshiryoku,genshiryokushiryou
・火山:kazan,kazanshiryou
・大規模事故:daikibojiko,jiko,daikibijiko_siryou,jikotou,kasaijiko
・本編、基本計画:kihonkeikaku,bousaikihonkeikaku,bousaikeikaku,sousoku,chiikibousaikeikaku,honpen,ippan

#質問例3(章が大見出しの場合)
A:第1章 総則について
B:第2章 原子力災害事前対策について
C:第3章 緊急事態応急対策について
D:第4章 原子力災害中長期対策について
E:何の章があるか教えて

#質問例3(部が大見出しの場合)
A:第1部 総則について
B:第2部 災害予防計画について
C:第3部 災害応急・復旧対策計画について
D:資料編について
E:何の部があるか教えて
```

引用
https://note.com/naoki_35/n/n56de54def5e2


# GPTsのメリット

特化した分野だけで比べると、GPTsで作成したオリジナルGPTの方が高性能





アップロード可能なファイルは以下を参照

https://platform.openai.com/docs/assistants/tools/supported-files


外部APIと連携可能
外部APIを呼び出すことができる「Actions」もある。


# テスト

gpt.txt (utf-8)
```
#朝の挨拶

おはようございます
今日も素敵ですね

#昼の挨拶

こんにちわ。
今日は何を食べますか？
```

アップロード

![名称未設定-7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31338/0a1772d4-8ba4-378d-a4c8-43900994d2fd.png)


# 結果

![名称未設定-8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31338/948b114d-150a-5367-7df8-c63a88f7a0db.png)

夜の挨拶は教えていないので出力されませんね
topコマンドの略語の意味

topコマンドに表示されるタイトルは何の略なのかなとふと思ったので調べた

- us : user process. (ユーザープロセス)
- sy : system (kernel) process. (システムプロセス)
- ni : nice process. (niceプロセス)
- id : idle process. (アイドルプロセス)
- wa : waiting. (I/O待ち)
- hi : hardware interrupts. (ハードウェア割込み)
- si : software interrupts. (ソフトウェア割込み)
- st : steal time. (VMから物理CPUへの待ち時間)
- Mib : Mebibite. (ブロック単位1024、Megabyteは1000と区別している)

[What the first five lines of Linux’s top command tell you | Enable Sysadmin](https://l.pg1x.com/8jzEvrK6c89gE21s8)

[linux - What does %st mean in top? - Server Fault](https://l.pg1x.com/aGWcfP79HLWmmwnx5)
Python: RealMediaをwavに変換するスクリプト

世の中的に需要はないかと思いますが、 すぐ忘れる未来の自分用のメモです...

さるところからRealMedia(え?今どき?)で構築された音声データベース(何じゃそりゃ?)からデータを取り出してほしい、すぐ欲しい、という依頼があり、その時は件数も少なかったので


1. htmlのソースからsmilファイルの場所を探す
1. smilファイルをエディターで開いて
1. .rmファイルの場所、start/end timeを特定して
1. VLCでwavに変換し
    + さすがにここはバッチ処理しました。
    + でもいらなかった。
    + rmはAudacityで直接ひらけました...
1. Audacityでstart/end timeでトリムしてwavでエクスポート(ここは手動...)

というようなことを延々としました。

これって自動化できるよね?ということで、smilファイルと同階層に置いて、同名のwavを作って、outputというフォルダに入れてくれるスクリプトを考えてみました。

```py
import xml.etree.ElementTree as ET
import subprocess
from datetime import timedelta

# smilから rmのパスの文字列、 開始(秒:float)、 終了(秒:float)のタプル に
rm_info = lambda smil_file : (
    (audio_attrib :=
        ET.parse(smil_file)
        .getroot()
        .find("body")
        .find("par")
        .find("audio")
        .get
    )("src")
    .replace("\\","/")      # セパレーターのバックスラッシュをスラッシュに変換

    , (seconds_from_attrib := lambda attrib_str :
            time_in_seconds(
                audio_attrib(attrib_str)[4:]    # 文字列先頭の"nts="を除去
            )
        )("clip-begin")

    , seconds_from_attrib("clip-end")
)

# hh:mm:ss.ss/mm:ss.ss/ss.ss形式から 秒:float に
time_in_seconds = lambda time_str : timedelta(
    0       # days
    , (times_split_reversed := [
            float(x)
            for x
            in time_str
                .split(":")
                [::-1]
            ]
        )[0]  # seconds
    , 0     # milliseconds
    , 0     # microseconds
    , *times_split_reversed[1:]   # minutes, hours (optional)
    ).total_seconds()

def convert_to_wav(rm_file, start_time, end_time, output_file):
    subprocess.run(
        [
            "/opt/homebrew/bin/ffmpeg",
            "-ss",
            str(start_time),
            "-t",
            str(end_time - start_time),
            "-i",
            rm_file,
            "-acodec",
            "pcm_s16le",
            "-ar",
            "44100",
            output_file,
        ]
    )


if __name__ == "__main__":
    import glob
    import os

    out_path = "../output/"
    os.makedirs(out_path, exist_ok=True)

    for smil_file in glob.glob("*.smi") :

        convert_to_wav(
            *rm_info(smil_file)
            , f"{out_path}{os.path.splitext( os.path.basename( smil_file))[0]}.wav"
        )
```
ffmpegの位置は自分の環境での決め打ちになってます。
エラー処理はしてません。

とりあえず目的は果せたのでここに残しておきます。
PowerAutomate：マイフローのソリューションインポート

子フローを呼び出せるのはソリューションのフローのみで、マイフローからは呼び出しできません。
また、作成済みマイフローをマイフローの中で子フロー化することもできません。

でも、安心してください！作成済みマイフローをソリューションに移すことはできます。

# マイフローからソリューションフローへの移行

作成済みのソリューションを選択し、「既存を追加→自動化→クラウドフロー」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3681410/e58ad1a5-8cb8-b405-20e2-7c122cd8b91b.png)

Dataverseを使ってない場合？は「Dataverseの外部」を選択すると作成済みマイフロー一覧が表示されるので、ソリューション化したいフローを選択して追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3681410/5f851daf-bd31-3743-1731-68a3b96a39fc.png)

# 子フロー応答処理の追加

子フローは親フローへの応答が必要なので、ソリューション化したフローを子フローにする場合は、フローの最後に「PowerApp または Flow に応答する」を追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3681410/4d3e73a4-dbc0-076e-f382-14204e25a248.png)



# 子フローの権限設定変更

ソリューションフローから移行した子フローは呼び出せるようになりますが、子フローがTeamsやSharePointなど特定機能を使っている場合、フローチェッカーに引っ掛かり、そのままでは使えません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3681410/f78d5107-fe8b-f729-4df9-1ae0ce643c9c.png)

移行した子フローの詳細画面の右下にある実行のみのユーザーの右の「編集」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3681410/f1a3a23b-a55a-5029-6039-ee70dffcb1d6.png)

対象子フローの各接続を実行する権限を「この接続（自分）を使用する」に変えて保存します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3681410/3e518e4f-c541-cf7f-ed80-933a32a25fdd.png)

再度、子フローを呼び出す処理に戻ると、無事に保存、実行することができるようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3681410/7f3bf2ca-0d2f-4b86-a397-a8368cdeb2d9.png)
GitHub ActionsでのFirebaseデプロイエラー解消法：'dist'ディレクトリが存在しない

# はじめに
今回は**React×Vite**で作成したアプリを、**GitHub Actionsを使用してFirebaseにデプロイする際に、エラーに遭遇した**ので、解決方法をまとめます。

FirebaseとGithub Actionsの各種設定に関しては、本記事では説明を省きます。
なお、下記を参考に行いました。

https://zenn.dev/jinwatanabe/articles/4026d373383739#1.-firebase-%E3%81%AE%E3%82%B5%E3%83%BC%E3%83%93%E3%82%B9%E3%82%A2%E3%82%AB%E3%82%A6%E3%83%B3%E3%83%88%E3%81%AE%E4%BD%9C%E6%88%90
# 問題
**Github Actionsにてdeploy中に"Directory 'dist' for Hosting does not exist."のエラー**が出ました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3675500/54b3d2a5-0ebc-98a6-cb9a-a72145ab0a4a.png)

# 解決方法
firebase.jsonを下記のように修正しました。
`"public": "dist"`と記載のあった部分を`"source":"."`に変更しました。
```json:firebase.json
{
  "hosting": {
    "source":".",
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ]
  }
}
```
# 原因

まず、この修正箇所が何を指しているかというと、**Firebase Hostingがデプロイするファイルを探す場所**になります。

**・`"public": "dist"`の場合（デフォルト設定）**
publicキーがdistに設定されており、**Firebase Hostingはdistディレクトリ内のファイルを探す。**
（プロジェクト構造）
```
project_root/
|__ dist/
|   |__ index.html
|   |__ assets/
|       |__ styles.css
|       |__ script.js
|       |__ ...
|__ src/
|   |__ index.js
|   |__ ...
|__ firebase.json
|__ ...

```

**・`"source":"."`の場合**
sourceキーが"."に設定されており、これはプロジェクトのルートディレクトリを指す。したがって、**Firebase Hostingはプロジェクトのルートディレクトリ内のファイルを探す。**
（プロジェクト構造）
```
project_root/
|__ index.html
|__ assets/
|   |__ styles.css
|   |__ script.js
|   |__ ...
|__ src/
|   |__ index.js
|   |__ ...
|__ firebase.json
|__ ...

```
今回の場合、Github Action時にdistディレクトリを生成しています。
しかし、**.gitignoreファイルにdistディレクトリを含んでいたため、gitによって追跡されず、リポジトリには含まれません。**
一方で、`"public": "dist"`でFirebase Hostingがdistディレクトリを参照する設定だったため、distディレクトリが存在しないというエラーが発生していました。
従って、**Firebase Hostingの設定を修正し、ビルドされたファイルがプロジェクトのルートディレクトリに配置されるように**しました。

# おわりに
今回のようなパターンはそこまでないかもしれませんが、ファイルの構造によって、Firebaseの設定を手動で変更する必要があります。
ColorDialogのCustomColorsへの変換式

# ColorDialogのCustomColorsへの変換式
```c#
        public static int DrawingToInt(System.Drawing.Color color)
        {
            return color.B * 256 * 256 + color.G * 256 + color.R;
        }
```
独自のカラーコード作るなら、変換式もしっかり提示してほしいです...  
Color.ToArgb()でも無理だったので、この変換式を見出すのが本当に大変でした...
[入門] chatgpt gpts で おはようと入力すると返信するだけのbotを作る

# chatgptにログイン
画面左下の私のGPTsをクリック

![名称未設定-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31338/692660c6-1f89-e578-757e-cbfc02f6ec01.png)

Createタブで
どのように対応していて欲しいかを入力

![名称未設定-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31338/ae2fde93-e567-acfa-2490-54b1d0eb4b2b.png)

タブをConfigureに切り替えると、設定した情報が入力されている。
Conversation startersの情報を入力し直すと選択肢を変更できる。

![名称未設定-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31338/6fd41103-d333-f121-c57d-9f81a5287f1c.png)


右上のセーブをクリックして、誰が使えるかを設定。
とりあえず、私だけにする。

![名称未設定-4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31338/73e3502a-955b-4edc-651d-0c199a511db1.png)

すると、左上に「あいさつbot」ができました。


![名称未設定-5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31338/3234a1ee-d49a-dc43-4cfc-c6bf2934cbd8.png)


以下のように「おはよう」と入力してみましょう。

![名称未設定-6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31338/b2413081-454d-20b0-163e-5ad730f71097.png)


結果
おはようございます。今日はごきげんいかがですか？
と命令した通りの出力になりました。
TailWindCSSでScrollbarを消したかったのでメモ

個人アプリ制作で、TailWindCSSを使いました。
`overflow-x-scroll`などスクロール関連のclassを使った時に、スクロールバーを表示したくないところがあったので調べてみました。意外と使う箇所が多かったので、次回のためにメモに残します。
## スクロールバーを消す方法
class名は適当に`hidden-scrollbar`とします。
ブラウザによって、書き方が違うのですべてのブラウザに対応させるには、以下のように書きます。
```stylesheets/application.tailwind.css
@layer utilities {
  .hidden-scrollbar {
    -ms-overflow-style: none; /* IE, Edge 対応 */
    scrollbar-width: none; /* Firefox 対応 */
  }
  .hidden-scrollbar::-webkit-scrollbar {
    /* Chrome, Safari 対応 */
    display: none;
  }
}
```
あとはスクロールバーを消したい箇所に`hidden-scrollbar`を書き足せばOKです。
```
<div class="overflow-x-scroll space-x-2 flex hidden-scrollbar">
...
</div>
```
## 参考記事
https://zenn.dev/nbr41to/articles/11efbc362a89ba
Unity DB代用

## 準備
### 格納したいデータ型
```C#
using System;
using UnityEngine;

[Serializable]
public class Data
{
public int id
public string name
}
```

### 上記データ型を保持するListクラス
```C#
using System.Collections;
using System.Collections.Generic;
using UnityEngine;


[CreateAssetMenu]
public class DataList : ScriptableObject
{
    public List<AllDatayData>list = new List<Data>();
}
```
|項目|||
|----|----|----|
|[CreateAssetMenu]|Projectwindowから右クリックでCreateを選んだ際に作成したクラスが表示されるようになる||
|[ScriptableObject]|クラスをアセットデータとして利用できるもの||

### データをセット
* Projectwindowから右クリックでCreateを選択し、作成したScriptableObjectクラスのアセットを作成する
* データを入力する

## 使い方1
使いたいクラス内のメンバに宣言し、上記で作成したScriptableObjectクラスのアセットをUnity上でアタッチする。

```C#
public DataList datalist;

//例 名前を取得
string name = datalist[0].name;
```

## 使い方2
リソースから直接取得
```C#
DataList datalist = Resources.Load<DataList>("src/DataTable");
string name = datalist[0].name;
```
#### パスの指定の注意点
例) 右クリックで以下ののパスを取得した場合の指定方法
Assets/Resources/src/DataTable.asset

指定
src/DataTable
うん、やらかした(Power Platform環境の契約E1➡E3)

## よし、Power Platformを学習しよう(2023年04月)

現場で、粛々とPower Automateのフローを作成を頼まれて
作っていたものの、Power Platformには、Power Appsやそのほかのツールが用意されている
それにオンラインのコミュニティに何度か参加していて、色々と試したいなぁと思ってみたものの
出向先で触らせえもらっているので、権限などの壁が立ちはだかって来たので

そっかいっそのこと環境作ってしまうか

一手目：自社もMicrosoft 365を使っているので
　　　　E3ライセンスを付与してもらえるか聞いてみた

➡　学習目的では付与できない(そりゃそうですね)

二手目：開発者プランで試してみる
　　　　うん、いい感じ期間もあるしやれそう
　　　　※これがいけない、後でやる感がでてやらない
　　　　　それに試したフローはどうなる？？？など
　　　　　もやもや発生

三手目：いっそのこと、環境を作ってしまおう(2023/07)
　　　※やらかし１：年契約でE1を契約してしまった
　　　　年契約なので2024年07月まで解約不能

四手目：E3を使いたい
　　　　理由は？Copilotアドインを試したい
    　　➡この動機は正しいのか？悩んでる

五手目：E3ライセンスを契約したらこうなった
　　![スクリーンショット 2024-02-12 114724.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3701343/b9bdd748-9b08-2473-d6a5-d04800ec37d7.png)

　これは、E3ライセンスを追加しようと購入したときに
　上のE3ライセンスの状態が無効になっていて、ユーザーにも割り当てで出来ずに
　路頭に迷っていた感じです
　結局、何をやっても無効を解除できずに、
　翌日に購入の手順をやり直したら、やり直したほうはアクティブになったのですが
　このアクティブになっているライセンスが、ユーザーに割り当てができず
　しばらく、頭が真っ白に放心状態になりました

　このあと。フィードバックの送信で、2回ほど状況を訴えた(助けて！！)ところ
　解消されて、無事にユーザにE3ライセンスの割り当てができました
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3701343/2c1439bf-b0a2-054d-bf49-230569bb10df.png)


環境を作るならきちんと何がやりたいのかを考えて契約しないと
やりたい事が出来なったりして、切り替えようとしても
今回みたいなことになって無駄をだしてしまったりと反省することが多いので
よく考えて行動しなきゃという教訓になった
Fly.ioに個人アプリをデプロイしたのでメモ

Fly.ioに個人アプリをデプロイしました。色々記事を見比べながらやったので、次回のために流れをメモしようと思います。
デプロイするアプリは作成済みであることを前提とします。
## デプロイの流れ
### flyctlをインストール
Fly.ioが提供しているCLI（flyctl）で行うためインストールします。
```
% brew install flyctl
```
### サインアップ
初めて使う時は、アカウントの登録が必要です。コマンドを実行するとブラウザが立ち上がり、会員登録画面が表示されます。メールアドレスか外部認証を使って登録します。
```
% flyctl auth signup
```
### ログイン
アカウントの登録ができたら、ログインをします。コマンドを実行するだけで大丈夫です。

```
% flyctl auth login
```
### RailsとPostgreSQLサーバーの起動
`fly launch`コマンドを実行すると、質問文が表示されます。対話形式で答えて、設定していきます。
```
% fly launch
...
# アプリケーションの名前を指定
? Choose an app name (leave blank to generate one): rails-flyio-sample
...
# 東京リージョンを指定
? Choose a region for deployment:  [Use arrows to move, type to filter]
> Tokyo, Japan (nrt)
...
# PostgreSQLを作成する
? Would you like to set up a Postgresql database now? (y/N) y
...
# Postgresqlは最低スペックで立ち上げる
? Select configuration:  [Use arrows to move, type to filter]
> Development - Single node, 1x shared CPU, 256MB RAM, 1GB disk
```
私の場合、初回の`fly launch`では上記のように対話形式で設定をしていきましたが、2回目の`fly launch`では、以下のような形に変わりました。(ログをメモしてなかったので少し違いますが、大体このようなログです)
```
% fly launch

Scanning source code
Detected a Rails app
Using the following build configuration:
    Builder: paketobuildpacks/builder:base
Creating app in /Users/chris/FlyTests/hello-gunicorn-flask
We're about to launch your Rails app on Fly.io. Here's what you're getting:

Organization: MyOrg                  (fly launch defaults to the personal org)
Name:         hello-gunicorn-flask   (derived from your directory name)
Region:       Secaucus, NJ (US)      (this is the fastest region for you)
App Machines: shared-cpu-1x, 1GB RAM (most apps need about 1GB of RAM)
Postgres:     <none>                 (not requested)
Redis:        <none>                 (not requested)

? Do you want to tweak these settings before proceeding? (y/N)
```
この場合は、yを選べばブラウザが立ち上がり、設定画面が表示されるので、そこで設定できます。
```
? Do you want to tweak these settings before proceeding? (y/N)
```
#### 注意点
スペックは、ポートフォリオレベルのアプリだと、最低スペックの256MBではメモリ不足になる可能性が高いです。最低でも、512MBを選択した方が良いと思いました。私は、256MBでメモリ不足になったので結局512MBに上げざるを得なかったです。その際の設定に苦労したので最初から設定しておいた方が良かったなと思いました。
### デプロイする
以下のコマンドでデプロイします。
```
% fly deploy
```
以下のコマンドで、ブラウザが立ち上がるので、デプロイしたアプリケーションにアクセスできたら成功です!
```
% fly open
```
### 参考文献
https://zenn.dev/hokawa/articles/65ddcd9974448c
https://fly.io/docs/rails/getting-started/
https://qiita.com/yuuki-h/items/ec23de152368d36672ea
Fakerとseed.rbでUserに紐づいたBoardダミーデータを作成

掲示板一覧機能の作成のために、Boardモデルを作りました。

今回は、Fakerを使ってseed.rbにuserに紐づいたboardのダミーデータを入れました。ただ、user_idの部分のコードがよく分からなかったのでメモに残します。
初学者なため間違っていところがあれば教えていただけると幸いです。
## seed.rbに記述するまでの流れ
まずは、seed.rbを作るためにgemをインストールします。
```
gem "Faker"
```
`bundle install`してseed.rbを作ります。

10人分のUserモデルのデータも作成してあります。
## seed.rbに記述したコード
20個の掲示板のダミーデータを入れたかったので、繰り返し処理でBoardモデルのカラムに対してこのようにコードを設定しました。
```
20.times do |n|
  Board.create(
      user: User.offset(rand(User.count)).first,
      title: "タイトル#{n}",
      body: "本文#{n}"
  )
end
```
そして、今回はUserモデルに紐づいたBoardモデルのデータを作ります。ですので、誰がどの掲示板を作成したのかわかるように10人のユーザーをBoardモデルのuser_idに振り分けていかないといけません。

user_idには以下のコードで数字を振り分けていきます。
```
User.offset(rand(User.count)).first
```
ただ、このコードの意味を理解するまで時間がかかったので忘れないようにまとめてみました。

まずは今回初めてみた二つのメソッドについてまとめます。
### offsetメソッド
`offset`メソッドは、レコードを返す前にスキップするレコード数を指定します。
```
User.limit(5).offset(10)
```
例えば、このコードはユーザーの最初の10人をスキップして、次の11人目から最大5人のユーザーを返すという意味になります。

ちなみに、SQLはこのようになります。
```
SELECT * FROM users LIMIT 5 OFFSET 10
```
### randメソッド
`rand`メソッドは、渡した引数をランダムで返します。引数には、整数かRangeオブジェクトを渡すことができます。
```
rand(7)  #=> 3
rand(1..5)  #=> 2
```
整数の場合(rand(7)の方)は、**0から指定した整数未満の整数**を返します。(例でいうと、0~6)

Rangeオブジェクトの場合(rand(1..5)の方)は、**指定した範囲の値**を返します。
## user: User.offset(rand(User.count)).first
それでは、この部分について細かく分解して説明していきます。
```
User.offset(rand(User.count)).first
```
### User.count
まず、`User.count`はUserモデルのレコード数を返します。つまり、ユーザーというグループに属している人の数を数えるので、今回だと`10`を返します。

そうすると、`User.count`が`10`に置き換わるので、`()`の中は`rand(10)`になります。
### rand(User.count)
`rand`メソッドは、渡した引数をランダムで返すのでしたね。そして、引数に整数を渡したときは、`0から指定した整数未満の整数`を返します。

上述で、`rand(10)`に置き換わったので、ここで返す整数は`0~9のうちのどれか`になります。

ただ、ここで1つ気になる部分が出てきます。あれ？ユーザーは10人で、idは1から始まるから1人分ズレることになる・・・。

それを解決してくれるのが`offset`なのです。
### offset(rand(User.count)).first
`offset`は渡した引数分のレコードをスキップします。`rand(User.count)`で今回だと`0~9のどれかの整数を返す`ことがわかっています。

この二つを合わせると、
- `rand(User.count)`で0が出た時

=> offsetで0をスキップして1からのレコードを返す。
- `rand(User.count)`で9が出た時

=> offsetで9をスキップして10からのレコードを返す。
これで、先ほどのズレがなくなりました！

そして、`first`で一番目のレコードを返すことで、ユーザーの中からランダムに1人選んで、Boardモデルに振り分けることができました。
## まとめ
今回は、chatGPTを使いながら、コードの意味を解読することができました。

Railsガイドなどのサイトを見ても、わからない部分が結構あるので、chatGPTとうまく組み合わせながら、これからも一つ一つ疑問点を潰していこうと思います！

最後まで見ていただいてありがとうございます！
## 参考文献
https://railsguides.jp/active_record_querying.html#%E9%96%A2%E9%80%A3%E4%BB%98%E3%81%91%E3%82%92%E4%B8%80%E6%8B%AC%E8%AA%AD%E3%81%BF%E8%BE%BC%E3%81%BF%E3%81%99%E3%82%8B
https://github.com/faker-ruby/faker/blob/main/README.md
polymorphic_path:部分テンプレートでリンク先を動的に変更する方法

ポートフォリオ制作中に、初歩的な部分だと思うのですが詰まってしまった部分があったのでメモに残そうと思います。
初学者なため、間違っているところがあれば教えていただけると幸いです。
## 前提
:::note info 
Rails: 7.0.6
Ruby: 3.2.2
:::
- 編集リンクと削除リンクのアイコンをまとめた部分テンプレートを作っている。

- カテゴリー一覧とアイテム一覧で同じ部分テンプレートをrenderしたい。

- ページによってパスを動的に変えたい。
## 結論：polymorphic_pathを使う
削除ボタンに関しては、renderの時にlocalsで指定して変数を渡せばいいかなとイメージがついたのですが、編集ボタンがなかなかわかりませんでした。

色々調べた結果、

動的にリンク先を変えたい場合は、該当のパスの部分に`polymorphic_path`を使用すれば良いことがわかりました。

引数にモデルのインスタンスなどを渡すと、該当するurlを生成してくれるメソッドです。
```ruby:shared/_crud_icon.html.erb
<ul>
  <li class="inline-block">
    <%= link_to edit_polymorphic_path(object) do %> #=> "items/1/edit"
      アイコン
    <% end %>
  </li>
  <li class="inline-block">
    <%= button_to object, method: :delete do %>
      アイコン
    <% end %>
  </li>
</ul>
```
```ruby:items/_item.html.erb
<tr>
...
  <td>
    <%= render 'shared/crud_icon', object: @item %>
  </td>
...
</tr>
```
```ruby:categories/_category.html.erb
<tr>
...
  <td>
    <%= render 'shared/crud_icon', object: @category %>
  </td>
...
</tr>
```
## まとめ
便利なメソッドがあることを知れてよかったです。
## 参考文献
https://apidock.com/rails/ActionController/PolymorphicRoutes/polymorphic_url
https://api.rubyonrails.org/classes/ActionDispatch/Routing/PolymorphicRoutes.html
https://railsdoc.com/page/polymorphic_url
Python初心者のコマンド脳内議事録 #0　これは基礎?

はじめに
私は主にExcelをPythonに読み込ませ、使用しています。
その為、検索してもデータの型?が合わず上手くいかない事が多かったのです。
かといってどう変更すればいいのかも分からない…
だったら、備忘録として試行錯誤を載せればどうかな？と思って書いてます。（※丸写し回避の為リンク多め）
その為、人によっては試行錯誤の段階で解決出来る事もあると思いますが、悪しからず。
最後にまとめは作る所存です。
なお、Error等英語は英和辞典片手に訳してフワッと理解なので、違ったなら教えて頂けると幸いです。

最終更新日：2024.02.12

では、前振りが長くなりましたが本編スタートです。

:::note warn
使用環境
anaconda3(Python3.10.9)
拡張子".ipynb"を使用
:::

()はタプル
{}は辞書型表記
[]はリスト型表記
`#`を使うとコメントが書ける
`""`または`''`文字列として認識してもらえる

列の事をindex
行の事をcolumns
行と列の捉え方について確かに！と思ったリンク↓

https://pcacademy.jp/excel-rows-columns

# Qiita書く際に役に立った事。

:::note warn
日本語入力時には反応しなかった。
半角?じゃないとダメみたい。
:::

:bear:　>
段落を下げる

>ひと段落下がった！！
>>２個にするともうひと段落下がった
>>>ど
>>>>こ
>>>>>ま
>>>>>>で
>>>>>>>つ
>>>>>>>>づ
>>>>>>>>>く
>>>>>>>>>>か
>>>>>>>>>>>な
>>>>>>>>>>>>？
>>>>>>>>>>>>>飽きたので辞めます。
>>>>>>>>>>>>>>最後に、
ここまでで15段落下がりました。

:bear:　/　
様々な手助けをしてくれる。　

エディッタとプレビュー画面片手に試しにやってみてください。

:bear:　'
具体的な使い方↓
'×3　改行 本文 改行　'×3　 コマンド画面
```
改行すると黒
```
```改行しないとグレー```
"```のすぐ後にpyとか打つとカラーに出来る。

:::note info
py = Python
cpp = C言語
rb = Ruby
:::
個人的には失敗はグレーにして成功したの黒として使用しようかな…

<details><summary>コメント</summary>
使い分けにプログラマーの暗黙の了解的な事があったらすいません…
</details>

↑コレの出し方
/を打ったのちにdetailsを選択
```<details><summary>details</summary>改行</details>```
こんなんが出てくる。
改行の所に文字を書くと折りたたみコメント完成です。
<>で挟まれていないdetailsを任意に書き換えで好きな見出しに出来る。


:bear:　*　
打つとこうなる

*
前には改行必要、続けて書くと*に戻る、後には改行不要
・こっちははただの"・←これ。
早速追記
* 半角開ければ*に戻らなかった。

:bear:　#
半角開けると大文字になる。
改行で区切り線？入った。

* ここまで書いてまとめてくださってる記事を見つけたのでリンクを貼っておきます↓

https://qiita.com/wdwd5454/items/7d8db521c5c0d1f570f6

#
半角や改行によって仕様が変わるという事が分かりました。
まだ色々あると思いますが…
以上、5点！遊び疲れたのでいったん終わりにします。
ここまでお付き合いしてくださった方ありがとうございました！
Android Studio をインスト－ルしています。

Android Studio をインスト－ルしています。
インストールし始めて自分で本を読ながら時には自分でアプリを作ったりして約1年経ちます。
おかしくなったので、再インストールしています。

途中でSDKを指定するパスはどこか聞かれます。
それから先は進みませんがそれを無視すると

Unable to continue until an Android SDK is specifiedSelf-causation not permitted
Unable to continue until an Android SDK is specified

と言うメッセ－ジが表示されこれより先に進みません。訳すると

Android SDKが指定されるまで続行できない自己因果関係は許可されていません
Android SDKが指定されるまで続行できません

と言うことですが、どうしたら良いのでしょうか？

もう完全アンインストールしてインストールしています。何回も同じ結果です。
NotionとFruitionを使用してのwebサイト改良雑記

実家の家業で営業広報活動用にwebサイトを[Notion](https://www.notion.so/ja-jp)と[Fruition](https://stephenou.notion.site/Fruition-Free-Open-Source-Toolkit-for-Building-Websites-with-Notion-771ef38657244c27b9389734a9cbff44)で立ち上げて、細かい部分の修正を行ったので備忘録も兼ねて残しておく。

## "PAGE_TITLE"を入力しているとページが表示されない問題

Fruitionのサイトでjsのコードを自動生成してくれるが、その際にPAGE_TITLEを入力していざcloudflareのworkerにコピペしてみて、webサイトをPCのブラウザで見る分には何ともないのだが、手持ちのiPhoneのブラウザから見ると

```
「こんにちは。お客様のiOSアプリに問題が発生したようです。このアプリを削除して、AppStoreから再インストールしてください。」
```
と表示されて何もできなくなってしまう。

対処方法としては、以下の部分をコメントアウトするなり削除することでとりあえずこの問題から回避できる。

```js
if (element.tagName === 'title') {
  element.setInnerContent(PAGE_TITLE);
}
```

## faviconやlogo-iosの設定ができない問題

Fruitionを使って生成されたjsのコードをcloudflareのworkerにコピペしているだけなので、ドメインルート以下にfaviconやlogo-iosの画像が無いのは「それはそう」としか言えないのだが、無理やり何とかする方法はある。


`fetchAndApply`の関数の中で以下のif文を作ってしまい、あたかもドメインルート以下に画像が存在するかのようにしてしまえば良い。
（処理の書き方についてはいろんな所からのコピペの継ぎ接ぎなので許してください…）

```js
if (url.pathname.endsWith('favicon.ico')) {
  const headers = {
    'Content-Type': 'image/x-icon',
    'Access-Control-Allow-Origin': '*',
  };
  
  const binaryImage = atob(favicon_base64Image);
  const bytes = new Uint8Array(binaryImage.length);
  for (let i = 0; i < binaryImage.length; i++) {
    bytes[i] = binaryImage.charCodeAt(i);
  }
  const blob = new Blob([bytes.buffer], { type: 'image/x-icon' });
  
  return new Response(blob, { headers });
}
```

`favicon_base64Image`の変数にはfaviconやらの画像をbase64の文字列に変換させたものをソースコード内に行数は喰うが文字列の定数なりで記載しておけば良い。
（`logo-ios`についても`url.pathname.endsWith('/images/logo-ios.png')`と変えれば同様の処理でなんとかなる）

## metaタグの修正

Fruitionで生成したwebサイトの状態のままだとmetaタグに関してがNotionの情報のままだったりと手が入っていないようなので以下のif文を`MetaRewriter`クラスに追記して修正した。もちろん関係無いif文であれば自己判断で消してください。
（正直なところ「これが正解」だとは思っていないので、本来はこうするべきだーなどがありましたらご指摘いただけると嬉しいです）

```js
if (element.getAttribute('property') === 'og:image'
  || element.getAttribute('name') === 'twitter:image') {
    element.setAttribute('content', 'いいかんじのがぞうURL');
}
if (element.getAttribute('name') === 'twitter:site') {
  element.setAttribute('content', '@から始まるXのアカウント名');
}
// 主が日本語で、英語のページも存在するのでalternateの要素も追加
if (element.getAttribute('property') === 'og:locale') {
  element.setAttribute('content', 'ja_JP');
  element.setAttribute('og:locale:alternate', 'en_US');
}
```

## 最後に

[Fruition本家github](https://github.com/stephenou/fruitionsite)の更新もそんなに活発ではないように見えますし、日本語の情報もサイト立ち上げについての情報くらいしか見当たらなかったので、私の行った修正が誰かの助けになればと思います。

立ち上げたサイト自体もドメインで年額25$くらい、Notionの課金もiOSからパーソナルProの課金で年額5000円、cloudflareは100,000件/日以上のアクセスが無ければ無料枠で運用できているので、まぁ安い方でしょう。と勝手に思っている。


## 追記: 2024/11/04

もうFruition本体の更新も3,4年止まっていてNotionの更新に追いつかない部分もちょいちょい出てきているように見えます。
標準出力されるコードをそのままコピペで動くか、というと上手く動かないみたいなので気を付けてください。
よく使うgitコマンド集

## ステージング(インデックス)の取り消し
ワークツリーは修正されない。
```shell
git reset HEAD
```

## ワークツリー、ステージング共に取り消し
```shell
git reset --hard HEAD
```
特定のコミットまで巻き戻しも可能
```shell
git reset --hard <commit id>
```

## Untracked fileの削除
```shell
# 削除されるUntracked fileを確認
git clean -n

# 削除実行
git clean -f

# ディレクトリごと削除する場合
git clean -df
```

## gitの追跡対象外にする
ワークツリー（ローカル環境）にはファイルが残る
```shell
# ファイル
git rm --cached <ファイル名>
# ディレクトリ
git rm -rf --cached <ディレクトリ名>
```

## ステージングの内容を直前のコミットに戻す
ワークツリーは修正されない
```
git checkout HEAD -- [ファイル名]
```

## `git rm`で削除したファイルを復元する
直前のコミットからファイルを引っ張ってきて、反映する仕組み。
### 2ステップ必要
1. [git reset](#git-addの取り消し)コマンドを使う
**※`git reset`は`git add`の取消以外にも使える**
2. git checkoutでファイルを復元
**※git checkoutは[指定したコミットのファイル内容を展開する機能](https://www-creators.com/archives/5595)も持ってる**
## ステップ1(不要なケースもある)
```shell
git reset HEAD <削除したファイル>
# or
git reset <削除したディレクトリ>
```

## ステップ2
```shell
git checkout HEAD <削除したファイル名>
```

## ワークツリー、インデックス、リポジトリからファイルを完全に削除
**※追跡対象外(.gitignoreで定義したconfigfileとか)のファイル（ディレクトリ）を指定するとローカル環境からも完全に削除されるので注意**
```shell
git rm <ファイル名> [-n(対象ファイルの確認)]
git rm -r <ディレクトリ名> [-n(対象ディレクトリの確認)]
```

## 直近のコミットメッセージの書き換え
```shell
git commit --amend
```

## 過去のコミット履歴を追う
```shell
git log
# グラフで表示する(複数指定可能)
git log --graph --decorate HEAD origin/main
# 特定のファイル修正のコミットを追う
git log -- file名
# diffも同時に表示する(先の--fileと組み合わせるとファイルの修正履歴を追いやすい)
git log -p
```

## 差分表示するときに特定のディレクトリを除外
```shell
# :(exclude)【除外したいpathのパターン】
# testディレクトリが除外される

git diff master -- ':(exclude)*/test/*'
```

[コミットメッセージの変更](https://docs.github.com/ja/pull-requests/committing-changes-to-your-project/creating-and-editing-commits/changing-a-commit-message)

[[git] 戻したい時よく使っているコマンドまとめ](https://qiita.com/rch1223/items/9377446c3d010d91399b)
.NET 8バージョンアップに対する所感

.NET 8は、間もなくリリースされる長期サポートバージョン（LTS）です。.NET 7は2024年5月14日にサポートが終了し、前の長期サポートバージョンである.NET 6も2024年11月12日にサポートが終了するため、.NET 8のリリースと共に多くのアップグレードが行われるでしょう。
では、なぜアップグレードするのでしょうか。実際、プログラマーにとってはアップグレードは煩わしいものです。問題なく使っているのに、なぜする必要があるのでしょうか。実際、セキュリティ部門が要求しない限りアップグレードする必要はありません。セキュリティ部門がない場合も、また、セキュリティ脆弱性に関する心配がない場合も、サービスがなくても問題ない場合も、アップグレードする必要はありません。機能しているプログラムが最良のプログラムですから。
では、アップグレードが必須の場合、何に注意すべきでしょうか。以下は、私が個人的に重要だと思うポイントです。
まず、現在のバージョンと最新バージョンの違いを確認することが重要です。.NET公式は、バージョンの互換性の違いに関するウェブサイトを提供していますので、参考にできます。例えば、現在のバージョンが.NET 6で、.NET 8にアップグレードする場合、まず.NET 6と.NET 7の違いを確認し、次に.NET 7と.NET 8の違いを確認します。そして、どの技術点が変更されたのかを総合的に考慮し、一度に修正を適用します。.NETバージョンの違いに関するウェブサイトのURLは以下の通りです：
https://learn.microsoft.com/zh-cn/dotnet/core/compatibility/library-change-rules。
次に、サードパーティのライブラリを調査します。サードパーティのライブラリは、.NET公式ほど親切に互換性文書を提供していないかもしれません。そのため、テストを通じて影響範囲を確認する必要があります。時には、官公庁が新しいバージョンを要求しているサードパーティのライブラリが遅れることがあります。その場合、同じ機能を持つ別のサードパーティのライブラリに切り替えるか、耐え忍んで待つ必要があります。
アップグレードの際は、将来廃止されたり、発展しないライブラリを事前に変更することが最善です。これにより、複数回のアップグレードを避けることができます。また、アップグレード後の官公庁ライブラリやサードパーティのライブラリは、機能の最適化や拡張をもたらし、これを利用して自身のサービスの性能や可用性を向上させることができます。
アップグレードは苦痛です。コードの修正だけでなく、リスクも伴います。そのため、アップグレード後のサービスを新しいプロジェクトとして扱い、プロジェクトのオンライン化プロセスを再度行うことが最善です。例えば、SLAを再調整します。ない場合は、少なくとも機能テスト、パフォーマンステスト、セキュリティチェックを再度行い、アップグレード後のアプリケーションに問題がないことを確認します。

(Translated by GPT)
会社から「UI/UXを任せる」と言われた。

# 自己紹介
### 未経験入社から現在までの１年間
はじめまして。
私は2022年11月にSES事業をメインとする会社に入社し約１年間プログラマーとして勤務しております。
入社前は５年間自動車整備士として働いておりましたが、在宅でも働けるスキルを身につけたいと思い、Javaの職業訓練で４ヶ月勉強し、転職しました。

## 自社アプリプロジェクト始動
そしてJava要員として案件先で勤務する中、自社でもアプリを作ろうというプロジェクトが始まりました。私はフロントエンドの勉強もしたいと思っていたので、フロントチームで参加することになりました。
アプリ自体はつよつよエンジニア先輩方のおかげで形にはなったものの、リリースするにはまだまだ改善が必要でした。

特に、フロントチームはデザイン経験者などおらず素人がなんとなく作ったものだったのでUI/UXのカケラもありませんでした。

## 会社から「UI/UXを任せる」と言われた
そんな中、私がフロントチームの最年長だったこともあり、改めてリーダーをお願いされました。
正直、余裕がなかったので始めは断りましたが、会社からは
「作業は全部振ってもらえばいい。君にはデザインやUI/UXを任せたい」
ということでした。

もちろん私もデザイン経験はゼロなので一から勉強になるのですが、会社は「君にかけている」とまで言ってくれたので、やれることをやってみようと思いデザイン担当の仕事を受けました。

## Qiitaでアウトプット量UP
ということで、UI/UXの勉強を始めたのですが。インプット量に比べてアウトプット量がほぼゼロに近い状態でした。とりあえず、なにかしらのアウトプットをしてこうと思い、Qiitaを始めました。
今回の記事はお試しということで自己紹介だけにさせていただき、次回から自分が勉強したことのアウトプットとして記載していこうと思っています。
Blazor Serverの.NET 8以降(App.razor)の相対ディレクトリ指定

# はじめに
前記事で.NET 7から.NET 8への移行について書いたのですが、その後に追加したい内容が見つかったので別記事にしました。

https://qiita.com/yaju/items/762d48ecda8b9c59279a

# 現象
.NET 8に変更したアプリケーションを、Visual Studioのデバッグ環境でしか動かしていませんでしたが、Webサーバー上にデプロイメントしてくれとの依頼があったので、.NET 7の時と同じ感覚でデプロイしたところ表示がおかしいことに気が付きました。CSSなどが全然効いていなかったのです。

CSSのURLの参照先を見ると、ホスト名直下の指定になっておりました。
IIS上にはディレクトリとしてエイリアス名(例 TEST)を指定していますので、エイリアス名の直下のCSSが指定されていなければなりません。

# 原因
.NET 7の時には、`_Host.cshtml` では base タグには、チルダ(~)が指定されていました。
チルダ(~)は、ルートディレクトリからの相対ディレクトリを指定できる役割があります。

```xml:_host.cshtml
<base href="~/" />
```

.NET 8で、`_Host.cshtml`ファイルから`App.razor`ファイルに変更した際、base タグのチルダ(~)は無くなりました。Visual Studioのデバッグ環境でしか動かしてなかったので気が付かなかった。

```xml:App.razor
<base href="/" />
```

# 対応
`App.razor`でも同様にbase タグのチルダ(~)を付ければいいのではと思いますよね。
でも、今度はVisual Studioのデバッグ環境でCSSやJavascriptが効かなく正しくレンダリングされないのです。

## 暫定対応
デプロイ時だけ、エイリアス名を追加して発行すればいい。時間が無かったので、この方法で暫定対応しました。

```xml:App.razor
<base href="TEST/" />
```
しかし、この方法はデプロイされる場所を事前に把握しておく必要があります。チルダ(~)指定であれば好きな場所に配置できていたので、これは不便です。

## 最終対応
その後 reddit にいい記事を見つけました。この方法でデプロイして問題なく動作しました。

[How to utilize ~/ in Blazor .NET 8.0 - reddit](https://www.reddit.com/r/Blazor/comments/19dqltq/how_to_utilize_in_blazor_net_80/?rdt=44202)

```xml:App.razor
<base href="@BaseUrl" />

@code
{
    [CascadingParameter] private HttpContext HttpContext { get; set; } = default!;
    private string BaseUrl => $"{HttpContext.Request.PathBase}/";
}
```

# 最後に
プログラムのアルゴリズムで悩むならともかく、こういう設定がらみで悩むのはキツいです。情報発信してくれた方に感謝するしかない。
【Rails】renderメソッドとは

# renderメソッドとは
`render`メソッドは、コントローラーからビューを描画するために使用されるメソッドです。これは、アクションメソッド内でビューを指定し、そのビューをHTMLとしてレスポンスとして返すために使われます。

具体的には、`render`メソッドは以下のように使用されます。
1\. **テンプレートの指定**
```ruby
render :index
```
上記の例では、`index.html.erb`という名前のビューファイルを描画します。

2\. **オプションの指定**
```ruby
render :show, layout: 'application'
```
この例では、`show.html.erb`ビューをレンダリングし、'application'というレイアウトを使用して表示します。

3\. **変数の渡し込み**
```ruby
render :edit, locals: { user: @user }
```
この例では、`edit.html.erb`ビューに`@user`というローカル変数を渡して描画します。

4\. **インラインのレンダリング**
```ruby
render inline: "<%= @user.name %>"
```
この例では、`@user.name`の値を含むHTMLをインラインでレンダリングします。
# まとめ
`render`メソッドは、コントローラーアクションの最後に使用され、そのアクションの実行結果としてビューをクライアントに返します。また、`redirect_to`メソッドと一緒に使われ、リダイレクト先のビューを指定することもあります。

`render`メソッドは、Railsアプリケーションで最も頻繁に使用されるメソッドの一つであり、柔軟性が高く、ビューの描画をカスタマイズするための様々なオプションを提供します。
デブサミ2023夏③

# 前提
プロダクトも経営視点で考えたら、
個々のプロダクト同士が互いに相互作用しつつ、上の経営ビジョンやMissionを支えてる。
このプロダクト同士の相互作用メカニズム(力学)を把握することが重要。

個別最適な設計では、プロダクトA,Bをそれぞれ個別に目標指標高めたからと言って、
それらの間の相関関係を考慮していないと、全体最適に繋がらない。

プロダクトをサービスって見立てて、それらの公開するAPI同士が繋がって、
経営を支えているという構図。

# 課題
## 属人的な仕事
そのプロセスを設計した人しかわからない。
その人しか得た知見を知らないなどの属人化。

## コアプロダクト(MVP)の課題
・モノリシック構造
・個別最適なアーキテクチャ
・使ってる技術が古い

開発生産性が下がってしまい→その結果品質管理にまで時間使えず、品質も低下。
品質下げないためにっていって多くの検証しても、それはそれでテストコストかかる。

## 新旧プロダクトの共存に対する課題
・新プロダクトとコアプロダクトのギャップ
・新プロダクトとコアプロダクトの連携(知見の共有とか)

# スタートアップに共通する壁
## 不揃いなプロダクトが乱立
これはプロダクトの大きさの粒度が揃っていないってこと。
たとえば、コンポーネントとクラスがなぜか同じ粒度構造になってしまってるみたいな。

## 個々のプロダクトが巨大化
神クラスのようなもの。
巨大化していて、結局そのプロダクトの責務が説明できないみたいな状態を指す。
いくつかに分割統治したうえで再検討。

## 開発生産性の低下と品質の低下
１つのプロダクトの品質の低下が、他のプロダクトの品質低下にもつながりかねない。
なぜならプロダクト同士が完全に独立しているとは言えないから。

# 組織再設計
## コンウェイの法則
ソフトウェアアーキテクチャは、開発チームの組織構造とよく似てしまう。
モノリシックなプロダクトをつくる組織は、組織構造もモノリシックであることが多い。
縦割り組織構造だと、各SoSアーキテクチャが独立しがちとか。
(あえてそうしてるならともかく)

## チーム間の連携設計
属人化を無くし、チームという単位で責務を割り当てた。
いわば１つのパッケージに対して責務(貢献すべきこと)を割り当て、その中でクラス(構成員)単位に分割。
ていう設計思想をチーム設計にも用いている。
これはチームトポロジーの基本的な思想。
実際にこの以下のモデルにしてみて、連携がとりにくいといった業務上の問題があれば、
その都度再設計していきつつ、組織的ADRにナレッジとして更新し続ける文化が大切と思う。

<img width="500" alt="スクリーンショット (196).png (480.4 kB)" src="https://img.esa.io/uploads/production/attachments/5827/2023/08/02/135213/5c26d42b-7c6c-4a29-b53e-2e4ee60457d2.png">

そのうえで、各チーム同士を接続し、連携のうえにチャネルを構築することで
チーム間のコミュニケーションを設計した。
これはチームトポロジーにも記載があったが、それを実際に体現されているのには
非常に感心しました。
チャネル設計によって、そのチームの責務や保有しているデータなどもある程度類推がつきやすいし。

## コミュニケーションメッシュ
チーム間の横の知見の共有などの連携のためにメッシュを貼る。
これは別にサービスメッシュを貼るとか、データメッシュを貼るとか
そういった技術的にコストのかかるようなものを指してはいない。
コミュニケーションの数は増えるものの、報告のための報告などの無駄をなくし、
具体的なそれぞれのミッションや得た知見について語り合える重要な連携だ。

マイクロサービスにしたからといって、
認知負荷を下げた各アーキテクチャ量子のみを見てればいいってもんじゃない。
組織に１つ以上の事業、つまり複数のサービスが存在しており、
それらが何かしら疎結合であっても、連携しているのなら、
横断的な活動によって全体を俯瞰して視る人がいなくてはならない。
組織内の横断的スクラムギルドを立ち上げるなどし、
組織全体の改善のための報告を行えるようになっていくことが望ましい。

<img width="500" alt="スクリーンショット (198).png (273.5 kB)" src="https://img.esa.io/uploads/production/attachments/5827/2023/08/02/135213/6dfbd787-d961-4ec1-b01b-55993707e7ae.png">

他のプロダクトの知見をアナロジー展開するってものもこれには含まれる。

## プロダクト同士をインターフェイスで接続
１つのプロダクトをサービスって見立てて、それらをAPIでつなぐと考える。

<img width="500" alt="スクリーンショット (199).png (315.6 kB)" src="https://img.esa.io/uploads/production/attachments/5827/2023/08/02/135213/181e3846-0c01-4356-8f50-b5ec12b90de1.png">

こうやってネットワークで接続できるようにし、情報の共有などを行いやすくする。

マイクロサービス同様に、アナロジー展開しやすいものに関しては、
最初からマイクロサービスの構造に従ってチーム設計をするよりも、
まずは現実的なモジュラーモノリス構造を取ることがトランザクションなどの観点などからも望ましいと考えられる。
マイクロサービス進めるとどうしてもトランザクションも分割されるため、
リアルタイムな結果の整合性が得られないなどの問題があるからである。

また上図では、相互依存の部分があるが、影響範囲の拡大ってリスクを考えたら
新プロダクトYをもう少し小さく分割するなどして相互依存を避ける。
でないと、片方のチームの変更の影響をもう片方が受け、
それの影響をまたこっちが受けてという、変更リスクの循環が起きてしまう。
これはコンポーネントの非循環依存の原則を考えれば、当然避けるべきことだ。
<img width="500" alt="スクリーンショット (200).png (384.1 kB)" src="https://img.esa.io/uploads/production/attachments/5827/2023/08/02/135213/344466da-ce7a-4d3b-a494-436ee6e7395b.png">

さらに言えば、ここからは個人の主観が入るが、
コアプロダクトは一般的に激しい変化に晒されるため、安定したコンポーネントとはいいがたい特性がある。
そのため、依存関係の向きなども気を付けておきたいところ。

# 感じたこと
顧客に求められた機能のうち、うちの企業のKGIを阻害するものも
請け負ってしまっていないか？という視点は常に持った方がいいと感じた。
なんでも請け負っているとビジョンの阻害となるので。
深層学習の説明性について【E資格対策】

# Grad-CAM
Grad-CAMは、CNNベースの画像認識モデルに対して、画像のどの部分に注目してクラス予測をしているのかをヒートマップで可視化するアレですね。

# LIME
LIMEは、説明したいインスタンス（データ）の周辺で、ブラックボックスモデルの挙動を線形モデルで近似し、その線形モデルの係数を特徴量の重要度として表示します。LIMEは、局所的な説明を提供する手法ですね。


# SHAP
SHAPは、協力ゲーム理論のシャプレイ値を機械学習に応用した手法です。各特徴量がモデルの予測値にどの方向にどれだけ影響を与えたかを表すSHAP値を計算します。LIMEと同様に、モデルに依存しない汎用的なアプローチですね。
シフトレジスタ 74LS90 (JK-FF) で遊んでみる

<font COLOR="blue" >

#### よくあるボタンを押すと数字がカウントアップ仕組み

</FONT>


![1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821882/f740161e-6996-aeb0-fedf-36d8eea6b7d8.jpeg)

* スイッチを押す度にLEDがBCDとして点灯して面白い。写真は表示が[点灯 点灯 点灯 消灯]の1110なので10進数で14。

<font COLOR="blue" >

#### 1.基本

</FONT>


![2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821882/2c10e21e-510c-ff28-33cc-a550417bf7fd.jpeg)


<font COLOR="blue" >

#### 2.シュミットトリガ使用 バウンジング対策版

</FONT>

![3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821882/bb1a08bb-fe2a-1004-2396-fff17ecf2c8e.jpeg)

<font COLOR="blue" >

#### 3. 7セグメントLED版

</FONT>


* BCD出力を7SEG LEDドライバに入れるだけで簡単に数字表示に変更できる。
![5.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821882/ae6f86b1-1035-abb3-e22c-663cbd825169.jpeg)

<font COLOR="blue" >

#### 4. 3をブレッドボードで組み立て

</FONT>


![6.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821882/442f9f73-2795-3c26-0ad8-015fa3e3fd93.jpeg)

<font COLOR="blue" >

#### 5. 555タイマを使用して自動カウントアップ

</FONT>


![7.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821882/dae7e37f-106f-c22d-ae05-a0675bdb5a43.jpeg)

* NE555の3番ピンをSN74LS90の14番ピン(CKA)に入れる。
* 発振周波数は約8Hzにしたので毎秒8カウントされる。

<font COLOR="blue" >

#### 6. NE555の波形を観測したオシロスコープの様子 8.047Hz/1.756V DC

</FONT>


![9.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821882/adf45955-4ca5-823e-aca2-137069da325e.jpeg)