OmniAICreator/Qiita-1.07M huggingface dataset:
2023: Week 40 - Prep School Subject Dropouts / Preppin' Data / Tableau Prep

# Challenge Preppin'Data 2023:Week 40
Tableau Prep実行環境：Ver.2023.2.2

## 概要

学校の学生クラス選択の履歴を処理し、時間割作成に適した構造で記録されていたものを整形して、学校が各科目の中退率を計算します。データは手作業で入力されていたため、科目名にタイプミスがあるため修正が必要です。

Requirement
- データをピボットして、それぞれのクラス選択ごとに1行のデータとします。
- 科目名をスペルごとにグループ化して、科目名を標準化し、ヌル値を除外します。
- ドロップアウトまたはアクティブなグループを示すフラグを作成します。
- 科目とアクティブフラグでデータを集計し、各グループの学生数をカウントします（注意: 一意のカウントではなくカウントを使用する必要があります）。
- データをピボットして、科目にアクティブに登録している学生数と科目から脱落した学生数のカウント用の列を作成します。
- 科目ごとの総登録数（アクティブ + 脱落者）を示す行レベルの計算を行い、それぞれの科目で登録者のうち脱落者の割合を示す割合を作成します。

## 問題のページ（英語）※ここからデータをダウンロード
https://preppindata.blogspot.com/2023/10/2023-week-40-prep-school-subject.html

## 出題者の回答のページ（英語）※動画あり
https://preppindata.blogspot.com/2023/10/2023-week-40-solution.html

## 自分の解決法
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531257/5f969f91-7752-ec9f-9276-6add1fee9d1c.png)


1. 最初に、全てのクラスを1つの列にまとめて、科目、クラスまたは脱落、学生名のフィールドを持つようにします。
これを行うために、ピボットを使用して、'Class'という単語を含むすべてのフィールドを取り込む 列から行 ピボットします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531257/f3b196c4-4cf6-ed19-679c-6441c3e3104c.png)

1. ピボットしたフィールドの値から数字をの取り除きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531257/d0639af9-3a6e-efdc-4000-31df8f28823b.png)

1. フィールド名をActive Flagに変更します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531257/37c44051-1762-7fd1-ad7b-6123de20d152.png)

1. Subjectの表記ゆれを修正します。
Group Values＞Spelling での変換の他、Group Values＞Pronunciaionで変換します。
変換のレベルを調整して、表記ゆれをグルーピングします。
うまくいかない場合は、個別に調整します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531257/57f9fe2f-ffa9-9122-3601-a914bd7fceb4.png)

1. NULLを除外します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531257/216f5495-82ca-f23d-72c6-36d3ae3271df.png)

1. 集計で、CalssとActive Flagでグルーピングし、Nameをカウントします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531257/254c09d6-a3be-ff38-c225-9b368f8adb76.png)

1. 行から列 ピボットします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531257/8c311e2f-b9ce-3751-3071-12c2ad0c7d94.png)

1. Active Flagの値を変更します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531257/4736af6a-cd65-474b-8e2d-f798d9978e3f.png)
Class -> Acitive
Dropped Calss -> Drop Outs
1. Total Enrolled数を計算します。
Total Enrolled = [Active] + [Drop Outs]

1. 落第率を計算します。
Drop Out Rate = [Drop Outs] / [Total Enrolled]



## 今回の感想
Subjectの表記ゆれを修正したあとに、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531257/57f9fe2f-ffa9-9122-3601-a914bd7fceb4.png)

Class をグルーピング機能で修正しようとするとエラーになりました。
ここは理由が不明でしたので、備忘で残しておきます。
VSCode おすすめ設定

あくまで一例です！！！
自分のをかなり改変して載せてます。
+ Altスクロール加速
```json
"editor.fastScrollSensitivity": 10
```
+ スムーススクロール
```json
"editor.smoothScrolling": true
```
+ Mateial Icon Theme
```json
"workbench.iconTheme": "material-icon-theme"
```
+ マウスホイールのズーム
```json
"editor.mouseWheelZoom": true
```
+ Tab補完
```json
"editor.tabCompletion": "on"
```

+ フォント
```json
"editor.fontFamily": "Consolas, consolas"
"terminal.integrated.fontFamily": "Consolas"
```
+ Windowの感じを良くする
```json
"window.titleBarStyle": "custom"
```

+ インライン候補
```json
"editor.inlineSuggest.enabled": true
```
+ ブラケットのペアを表示
```json
"editor.guides.bracketPairs": true
```
+ 自動保存
```json
"files.autoSave": "afterDelay"
```

+ Zoomレベル
```json
"window.zoomLevel": 1
```

いい感じの例 : 
```jsonc:settings.json
{
  "editor.fastScrollSensitivity": 10,
  "editor.smoothScrolling": true,
  "editor.cursorSmoothCaretAnimation": "on",
  "workbench.list.smoothScrolling": true,
  "editor.lightbulb.enabled": false,
  "editor.renderLineHighlightOnlyWhenFocus": true,
  "editor.renderLineHighlight": "all",
  "editor.scrollbar.horizontal": "visible",
  "editor.scrollbar.horizontalScrollbarSize": 10,
  "editor.scrollbar.vertical": "visible",
  "editor.scrollbar.verticalScrollbarSize": 10,
  "editor.scrollBeyondLastLine": false,
  "editor.showFoldingControls": "always",
  "editor.tabCompletion": "on",
  "editor.snippetSuggestions": "top",
  "editor.suggest.shareSuggestSelections": true,
  "editor.suggest.preview": true,
  "editor.suggest.localityBonus": true,
  "editor.glyphMargin": false,
  "workbench.iconTheme": "material-icon-theme",
  "editor.mouseWheelZoom": true,
  "editor.fontFamily": "Consolas, consolas",
  "workbench.startupEditor": "newUntitledFile",
  "terminal.integrated.fontFamily": "Consolas",
  "liveServer.settings.donotVerifyTags": true,
  "editor.tabSize": 2,
  "editor.renderWhitespace": "all",
  "window.menuBarVisibility": "toggle",
  "debug.showInlineBreakpointCandidates": false,
  "debug.showBreakpointsInOverviewRuler": true,
  "window.titleBarStyle": "custom",
  "window.title": "${dirty}${activeEditorShort}${separator}${rootName}${separator}",
  "window.zoomLevel": 1,
  "files.autoSave": "afterDelay",
}
```
[PowerShell] パワポのタイトルに特定の文字列を含むスライドを抽出

# 目的

結構前に仕事でパワポのスライドタイトルに特定の文字列を含むスライドを抽出する必要があった。
ページ数が多く、いちいち検索・手動で切り取りするのは骨が折れるのでスクリプトを作成することにした。

# 概要
作ってみた。
Pythonとかでも良かったが、なるべくWindows環境に依存しない形式にしたかったのでPowerShellにした。
※ PowerShellはこれが初かも

https://github.com/Redh00k-k/ExtractSlides

使い方は以下の通り。
なお、環境によっては実行ポリシーを変更する必要があるため、以下のURL等を参考にされたい。
https://qiita.com/earthdiver1/items/b3f529c81f5892972a72
```
PS> ExtractSlides.ps1 <抽出対象となるpptx> <抽出先のpptx名> <検索する文字列>
```

以下の場合は、`src.pptx`のスライドタイトルに`B`と`C`が含まれるスライドを抽出して、`dst.pptx`に書き込む。
```
PS> ExtractSlides.ps1 src.pptx dst.pptx B,C
```

注意点は以下の通り
- `<抽出対象となるpptx>`の1ページ目にはタイトルスライドがある想定なので、指定した文字列を検索するのは実施は2ページ目以降となる。
- 抽出するスライドの種類は「タイトルとコンテンツ」を想定しているので、それ以外だと失敗するかも
[回路] トラックボールセンサ 

keywords
```
トラックボールセンサ
トラックボール arduino
```

# aliexpress

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589906/32e16b60-0f8c-9771-6e3b-bb6c2c609fbc.png)

https://ja.aliexpress.com/item/1005005764832115.html?src=google&src=google&albch=shopping&acnt=494-037-6276&slnk=&plac=&mtctp=&albbt=Google_7_shopping&albagn=888888&isSmbAutoCall=false&needSmbHouyi=false&albcp=19215244010&albag=&trgt=&crea=ja1005005764832115&netw=x&device=c&albpg=&albpd=ja1005005764832115&gad=1&gclid=Cj0KCQjwsp6pBhCfARIsAD3GZuZAmo_9Yl9w2F2KWICKZRWtgbUg-oxCIf7nAyb-OXogEDg4A48U4TgaAiZNEALw_wcB&gclsrc=aw.ds&aff_fcid=d13edeffbe94414ca988bb7b9db914ae-1697119272762-07020-UneMJZVf&aff_fsk=UneMJZVf&aff_platform=aaf&sk=UneMJZVf&aff_trace_key=d13edeffbe94414ca988bb7b9db914ae-1697119272762-07020-UneMJZVf&terminal_id=8a3ae0e4ecc94080a94ec1ba4ee94400&afSmartRedirect=y

# ADNS-5050

https://edoball.hatenablog.com/entry/2021/01/24/154514

# 類似UIデバイス
## マウスホイール

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589906/7f4e78b5-4027-e36b-aec8-be231d53703e.png)

https://ja.aliexpress.com/item/1005003907445085.html?src=google&src=google&albch=shopping&acnt=494-037-6276&slnk=&plac=&mtctp=&albbt=Google_7_shopping&albagn=888888&isSmbAutoCall=false&needSmbHouyi=false&albcp=19215244010&albag=&trgt=&crea=ja1005003907445085&netw=x&device=c&albpg=&albpd=ja1005003907445085&gad=1&gclid=Cj0KCQjwsp6pBhCfARIsAD3GZuYH6L5-kl-2gMdKyeM0wDQbrR-vHJYMcsLlCh_Wr_CgaO98G34_sRAaAjLkEALw_wcB&gclsrc=aw.ds&aff_fcid=72df2a877a1b452daa80e1246bcd2184-1697119803501-04091-UneMJZVf&aff_fsk=UneMJZVf&aff_platform=aaf&sk=UneMJZVf&aff_trace_key=72df2a877a1b452daa80e1246bcd2184-1697119803501-04091-UneMJZVf&terminal_id=8a3ae0e4ecc94080a94ec1ba4ee94400&afSmartRedirect=y

- 百均のものを解剖

https://www.creativity-ape.com/entry/2019/03/14/220821


- 百均のものを解剖２

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589906/92cfce62-b1c8-b15b-c264-9840bf5549b8.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589906/6a9b3acb-b4b5-186e-7ca4-bd443c6c0ae4.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589906/9bb9c415-66aa-bc4f-d329-970ca0c7330b.png)
全銀ネット障害についての考察

全銀ネット障害に対する考察のメモです。
とりあえず見え方は後回しです。


以下10/11　全銀ネットプレスリリース
https://www.zengin-net.jp/announcement/
より抜粋

--
昨日10月10日（火）、全国銀行データ通信システムの不具合により、一部銀行（三菱UFJ銀行1、りそな銀行2、埼玉りそな銀行3、関西みらい銀行4、山口銀行5、北九州銀行6、三菱UFJ信託銀行7、日本カストディ銀行8、JPモルガン・チェース銀行、もみじ銀行9、商工組合中央金庫10）において、他行宛の振込取引ができない事象が発生いたしました。 
--

日経クロステックより抜粋
https://www.businessinsider.jp/post-276648

--
今回、不具合が生じたと考えられるのは、金融機関が全銀システムに接続する際に使う中継コンピューター（RC）のプログラムだ。送金元の金融機関から送金先の金融機関に対して支払う「内国為替制度運営費（旧銀行間手数料）」の設定などをチェックする機能に不具合が生じたと見られる。
--

なお現在はCOBOLのままの模様。
その上で
・基盤の入れ替えである
・１日経っても原因不明
というのが不思議である。

この手のシステム現場ではいるはずの生き字引でもわからない、
内国為替制度運営費計算で問題だとすると考えられそうな原因

・ソース管理の問題。ソースとロードの不一致（ソースがない含む）
・アセンブラが悪さをしている
・Amode、Rmodeが不整合のロードがある
・マスタの不具合？
・半角カナの撥音とかが悪さしている
・漢字が混じった、シフトコードが悪さした


（2023/10/17補足）
メモリ不足との続報あり。

（2023/10/21補足）
どうもメモリ不足は誤報の模様
日経クロステックより

テーブル破損も「生成プログラムは正常終了だった」、18日の全銀ネット会見一問一答
--
辻松雄理事長：内国為替制度運営費（旧銀行間手数料）を計算する際に「金融機関名テーブル」、ならびに金融機関名テーブルを読み出す「インデックステーブル」が必要になる。このうち「インデックステーブル」が破損しており、一部の金融機関コードが読み取れなかった。
--

どうもマスタの不具合ですね。
VSAMがぶっ壊れたってことの模様。

まあプログラムを見てもわからないでしょうね。
でもだとするなら本番検証でわかりそうなものですが。
どうも各社に保管していたマスタを集約したとも言っていることも考えて
原因の想像
・集約した時にキーが重複した
・VSAMのキーの桁数が足りなかった
・ローディングの時にVSAM壊した
・VSAMの容量が足りなかった

（2023/11/9）
時々なぜ東京、大阪両方をアップデータとしたんだ
なぜ銀行側、全銀側両方を直したんだというが、的外れである。
銀行側のテーブルを全銀側に移す対応らしいので、銀行と全銀側で同時に対応しないと無意味である。当然東京だけアップデートしても銀行側で対応してしまった以上、無対応のままのシステムを残しても使い物にならない。

ただ不思議な点がいくつか。
・銀行マスタをコンバートする際にデータを壊したように見えるとのこと。
　とするならIDCAMSでデータコピーした時、エラーを吐かなかったのか、
　なぜそれを見落としたのか。
・コンディンジェンシープランがおかしすぎる。
　大人の事情で戻せなかったというのがおかしい。
　こんなの事前に「どこか1社でもおかしかったら差し戻します」って
　合意とっておくべき話。
Reactで改行を含む文字列をBRタグに置換する方法

# TL; DR

`Array.prototype.map()` のindexを活用すれば、条件分岐できることに気付きました。


# 内容

ReactのJSX内では改行文字をUI上の改行として表示できません。
また、単なる文字列置換だけでは、 `<br />` をDOMとして認識せず、単なる文字列として表示してしまいます。

対処方法として、様々な手法が考えられているようです。

https://kazunaka.com/react-linefeed/

https://qiita.com/suzuki0430/items/76c21e2d68f09d260872

https://chaika.hatenablog.com/entry/2020/07/12/083000

個人的には、for文を使う手法がシンプルで良さそうなのですが、やはり最後に `<br />` が残ってしまうのが気になります。

```react:最後にbrタグが残ってしまう手法
export const MultiLines = props => {
  const { text } = props;
  const lines = text.split(/\r?\n/);

  return (
    <>
      {lines.map((line: string, index: number) => (
        <React.Fragment key={index}>
          {line}<br />
        </React.Fragment>
      ))}
    </>
  );
};
```


# 提案する対処方法

`Array.prototype.map()` におけるindexを活用し、最後以外の要素を描画する際にのみ `<br />` を表示すればいいと考えました。

```react:提案する手法
export const MultiLines = props => {
  const { text } = props;
  const lines = text.split(/\r?\n/);

  return (
    <>
      {lines.map((line: string, index: number) => (
        <React.Fragment key={index}>
          {line}
          {index + 1 !== lines.length && <br />}
        </React.Fragment>
      ))}
    </>
  );
};
```

<p class="codepen" data-height="300" data-default-tab="js,result" data-slug-hash="ZEVZzGM" data-user="Morichan-the-sasster" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/Morichan-the-sasster/pen/ZEVZzGM">
  Split text at newline character and convert to BR tag</a> by Morichan (<a href="https://codepen.io/Morichan-the-sasster">@Morichan-the-sasster</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>
$CODESPACE_NAME-$PORT.app.github.devに認証なし匿名でアクセス【anonymous】

匿名でアクセスするには、ポートを公開用( Public ) にしましょう

![ezgif.com-video-to-gif (3).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435735/45cf3da1-57b3-2990-18eb-e5a396bff320.gif)


![ezgif.com-video-to-gif (4).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435735/199e8e69-2aca-2138-2cd1-6c68b70a41d3.gif)



# 参考

https://qiita.com/n0bisuke/items/0d279fccd6f62db37587
脱word履歴書の一歩目メモ

# Word系ドキュメントのテキスト管理

マークアップ言語や関連ツールが普及してきたこともあって、仕様書などのいろいろなドキュメントをテキストで管理できるようになって久しいですがそれ系の話です。

今回のターゲットは履歴書です。
一般的な履歴書のフォーマットを見ると、表でガチガチに組んでいるものが多そうです。
そういうドキュメントをうまく作れるか？というのを試してみました。


## ツール候補

- markdown　×
    - マークダウンで書いてpandocなどで出力するという方式
    - どうも表の表現があまり細かくは操作できない（セルの結合とか）ので今回は断念
- LaTex　△
    - レイアウトをガチッと定義すれば完璧なものができそう
    - [先人のテンプレート](https://www.tamacom.com/rireki-j.html)あり
    - Texは学習コストが・・・、ということで今回は他を探す
- AsciiDoc　○
    - 書籍書いたりに向いている（というかそれ用？）
    - できることも難易度もmarkdownとLaTexの間ぐらいという印象
    - よさそう！


他にもいろいろな選択肢があります。比較記事色々。
- [軽量マークアップ言語の特徴比較まとめ](https://qiita.com/sake8223/items/d26001dda80d9e2d9307)
- [Markdownだけじゃない。開発者向けドキュメント記法まとめ（Textile、RDoc、Org、Creole、AsciiDocなど）](https://notepm.jp/blog/6936)

## AsciiDoc

- [本家](https://asciidoc.org/)
    - [ドキュメント](https://docs.asciidoctor.org/asciidoc/latest/)
- 参考になるページ
    - [Asciidoctor 文法クイックリファレンス(日本語訳)](https://takumon.github.io/asciidoc-syntax-quick-reference-japanese-translation/)
    - [AsciiDoc文書作成入門:: Asciidocによる文書作成環境の構築](https://itcweb.cc.affrc.go.jp/affrit/documents/guide/asciidoc/start)
    - [AsciiDoc チートシート](http://www.venus.dti.ne.jp/~iisaka/DocSys/cheatsheet-ja/asciidoc-869/asciidoc-869.html)

ささっと使ってみたい場合、最も簡単な方法はVS CodeのExtensionsで導入してしまう方法かなと思います。
（PDF化だったりレイアウトをもっと凝ったりする場合の設定などは今後。）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83530/c3f9deac-1af2-ff78-869a-a7f317ffba22.png)
インストールし、.adocファイルを作成したらすぐ使えます。

## 現在のテンプレート
### 完成図
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83530/c729058e-4085-0c69-5896-8fdbe10cc2d5.png)

- 見た目は結構それっぽくなった
- チュートリアル見ながら作った程度なのでもっといい書き方はあるとおもいます。これも今後の課題。

### コード

- ファイルと同じ階層にimage.pngを置いてください。

```
:doctype: article
:scripts: cjk
:pdf-theme: default-with-font-fallbacks

= 履歴書

image:image.png[Image,200,130,float="right"]

[cols="1a,>",options="autowidth"]
[width="70%"]
[frame=none, grid=rows]
|===
||2023年 XX月 XX日 現在
|===

[cols="1a,1a",options="autowidth"]
[width="70%"]
|===
2+|^ふりがな^   はと かも
2+|^氏名^　　[big]#鳩 鴨#
|^生年月日^  令和4年  10月 8日 (満 1歳)|^性別^  オス
|===

[cols="7,3"]
|===
|^ふりがな^   |^連絡先^
.2+|^現住所^　〒000-0000 + 
　　Stable Diffusion XLにより誕生 +
　　
|000-0000-0000
|hato.kamo@mail
|===

[cols="2,1,10"]
|=================================
|*年*|*月*|*学歴*
|平成 10 |3 |XX大学 XX科 卒業
|平成 10 |4|XXXX大学院 XXXX専攻 入学
|平成 10 |3 | XXXX大学院 XXXX専攻 修了
|||
|*年*|*月*|*職歴*
|平成 10 |4 |XXXX株式会社 入社
|平成 20 |3 |XXXX株式会社 退職
|平成 30 |4 |OOO株式会社 入社
|||
|*年*|*月*|*資格*
|令和 2 |10 |XXX試験 合格
|令和 3 |11 |XXX検定 X級
|令和 4 |12 |OOO士
|=================================

[cols="6,2,3"]
|===
.3+|^志望動機、アピールポイントなど^   +
markdownではこのような表がうまく作れなかったのでAsciiDocで作ってみました。

2+|^通勤時間^ +
空を飛んで 約  0時間 2分

2+|^扶養家族数（配偶者を除く）^ +
X 人

|^配偶者^ +
有・無
|^配偶者の扶養義務^ +
有・無

|===

|===
|^本人希望記入欄^
|勤務地：自然が多い公園希望
|給与　： 希望年収  豆10個（現年収：豆7個）
|自由記述： +
xxxの考慮をお願いします。 +
xxxを希望いたします。
|===

```

今後も更新するだろうし、Gistかどこかに置いておこうかな。


## 追記

厚生労働省の指針によると昔のものとは色々と変更点がありそうなので注意。
- [新たな履歴書の様式例の作成について](https://jsite.mhlw.go.jp/kumamoto-roudoukyoku/content/contents/000884568.pdf)

いずれ直そう。
LINE botの作り方(その0: 全ての始まり)

# Abstract
「LINE botの作り方(その0: 全ての始まり)」では、LINE bot の作る上での最初の一歩、前提知識について、概要を説明する.


※この記事は、シリーズ「LINE botの作り方」の1つである.
シリーズ「LINE botの作り方」では、主にGoogle Apps Scriptなど種々のGoogleサービスと組み合わせたLINE botアプリの作成方法について展開している。読者はこのシリーズによってLINE botに限らず Google Apps Scriptの活用方法についての知見が得られることだろう。

# 想定
対話型のLINE botを作成することを想定する.
何でもよいが、たとえば、「botのトーク画面でユーザーが何かメッセージを打つと、それを受けたbotが、同じメッセージをそっくりそのまま2度繰り返したものをオウム返しする」といった簡単なものが良いだろう。

この一連の流れを詳細に書くと、以下のようになる:
- 受付嬢がユーザーのメッセージを検知して受け取る
- 受付嬢が「受信メッセージ」を処理係に渡す
- 処理係が「受信メッセージ」を元になんらかの処理(受信メッセージを2度繰り返す)をして、「応答メッセージ」を作成
- 処理係が「応答メッセージ」を受付嬢に渡す
- 受付嬢がユーザーに「応答メッセージ」を返す

Webやインフラに詳しい人向けのイメージとしては、Web三層構造でいうところの
受付嬢がWebサーバーに、処理係はアプリケーションサーバー
に大体相当すると言うとわかりやすいかもしれない。

# ソリューション
実際にこの対話型LINE botを実現するための最も典型的なソリューションは、
以下の3つの部品からなる:
- LINE Messaging API
- Webhook
- Webアプリケーション

### 各ソリューションの概要
 - LINE messaging API 
    - 受付嬢に対応
    - ユーザーとLINE bot間の通信部分を担う
    - LINEが提供するLINE bot 作成用のプラットフォーム
    - Web三層構造でいうところのWebサーバー
 - Webhook
    - 受付と処理部屋の連絡通路に対応
    - LINE botとWebアプリケーション間の通信部分を担う 
    - APIと外部のWebアプリケーションを紐づける汎用的な仕組み
    - LINE messaging APIのポータル画面に「Webhook」の項目があり、そこにWebアプリケーションがおいてある場所のURLを入力することで通信が確立される
 - Webアプリケーション
    - 処理係
    - ここに置いてあるスクリプトを元に処理がなされる
    - 例:
        - Google Apps Script
        - ランタイム環境がインストールされたPCやレンタルサーバー
        - クラウドの関数アプリ等のPaaS
    - Web三層構造でいうところのアプリケーションサーバー


# 参考文献
https://qiita.com/probabilityhill/items/a9dc082e40aeed8d2a5f
https://auto-worker.com/blog/?p=5141#
https://developers.line.biz/ja/reference/messaging-api/#webhook-event-objects
https://www2.kobe-u.ac.jp/~tnishida/programming/GAS-03.html
https://blog.smtps.jp/entry/2023/02/24/102649
https://qiita.com/kunichiko/items/7f64c7c80b44b15371a3
https://creators-note.chatwork.com/entry/2017/12/20/163128
https://tonari-it.com/gas-chatwork-webhook-message/
https://www.yukibnb.com/entry/linemessagingapi_gas_detail
他人の記述したソースコードを読むことの難しさと得られるものに気づいた日


## 概要
#### リバースエンジニアリング的な作業ですが、実装内容に合わせて作成するのが要望なので、問題ありません。)

お客さんとの打ち合わせの際、いつものようにプロジェクトの発注を受け納品物の確認をしていると、詳細設計書というものがあることに気づきました。

「これは何ですか？　設計書とは異なるものですか？」

と尋ねると

「詳細設計書はシステムの完成後(ソースコードの納品後)、実装した処理の方法やAPIの呼び出しタイミング、そのソースコードなどを記述してください。」

とのこと。(要約)

まだ関わったプロジェクト数の少ない私は「なるほど、そんなものもあるのか。」 と思い当時は特に深く考えておりませんでした。

さて、私はレビューは何度も受けた経験はありますが、まだコードレビューなるものをしたことがありません。

### 他人のソースコードを読む

という経験を今回初めて行うことになりました。

## 実際にやってみて

開発作業も無事終わり、詳細設計書の作成作業が始まりました。

まずは私が開発を担当した範囲の詳細設計書の作成を行い、どんなものか慣れていきました。

そして作業にも慣れたころ、協力会社の方に作成いただいた範囲の作成を始めようとして、コードを見ました。

### 全然わかりませんでした。

コーディングルールが厳格化されていたので、まだ「コードが汚い」ということはなかったのですが、完全に私のコードを読む能力が足りず、どこでどんな処理が行われているのか、なんとなくしかわかりませんでした。

## 原因

問題が発生した原因は以下の通りです。

- 他人の書いたコードを読むことの難しさを理解していなかった。
今まで他人の書いたコードをまともに読んだことがなく、コードを読むことのむずかしさを知りました。
コメントが書いてある説明用のコードぐらいしか見たことがなかったので、業務レベル且つコメントなしの他人が書いたコードをなめていました。

- コードを読む能力が足りなかった.
上記の理由と重複している箇所もありますが、コードを読む能力が足りませんでした。
単純に言語への理解度が低かったこともありますし(この時点で経験3カ月、業務で資料するのは初の言語)そもそもどんな実装方法があるのかも何パターンも思いつくほどの知識はなかったです。

## 困りました。

めちゃくちゃに困りました。
全てを検索したり質問している時間はありませんし、ChatGPTにメソッド単位で投げつけるわけにもいきません。

とにかく時間がかかりました。

## 他人のソースコードを読むことは勉強になる

終わってみれば、他の会社のエンジニアが書いたコードを読むということは勉強になるな、と思えました。
当時は焦っていましたが…

コードを少し書き換えてビルドしてみて…と試したりしてましたね。

自分もまだ開発経験が少ないので、いい機会でした。

先輩に確認したところこのような仕様書の作成を求められることは珍しいらしく、今後はあるかわからないとのことでしたが、また機会があれば積極的にチャレンジしていきたいですね。

# andmore...

他にもこんな記事書いてます。

https://qiita.com/SZR/items/837574ffe887a7556fa6

https://qiita.com/SZR/items/401a1f839723d89bd7f2

https://qiita.com/SZR/items/f46822b009fa47e1ca53

https://qiita.com/SZR/items/176586cde17ea0e9828a

https://qiita.com/SZR/items/a000cbaa583dcd2a344b

https://qiita.com/SZR/items/1d8edaf95fa2f5bbe821

https://qiita.com/SZR/items/1debe21a6759d0067ad7
【Linux初心者】Linuxコマンドってどこに定義されているの？正体は？

# 初めに
Linux環境に新しいコマンドをインストールした際、コマンドが使える仕組みを知ることができました。
忘れないようにアウトプットします。

:::note warn
この記事の著者はLinuxド初心者です。表現に間違いを含んでいる可能性があるので暖かい目で見ていただけると幸いです。
:::

# 新しいコマンドをインストールしてみる
ことの始まりは、alpというコマンドをインストールしようとしたときでした。
ubuntu上でコマンドをインストールするにはaptコマンドを使ってインストールすると思います。
しかし、alpコマンドはaptでインストールできませんでした。
そのため、githubから直接インストーラを落としてこようと考えていました。

# alpコマンドをダウンロードしてみた
ということで、wgetコマンドでalpのzipファイルをダウンロードしてきます。
```
$  wget https://github.com/tkuchiki/alp/releases/download/v1.0.21/alp_linux_arm64.zip
いろいろログ出たけど割愛
 
$ ls
alp_linux_arm64.zip
```

無事にダウンロードできたので、unzipします。

```
$ unzip alp_linux_arm64.zip
Archive:  alp_linux_arm64.zip
  inflating: alp
$
$ ls -l
total 13132
-rwxr-xr-x 1 root root 9764864 Oct  3 00:14 alp
-rw-r--r-- 1 root root 3679001 Oct  3 00:20 alp_linux_arm64.zip
```
unzipしたところ、alpというファイルができました。
windows脳の私は「これがインストーラか！」と思ったのですが、拡張子もついてないようでどう実行すればよいのかがわかりません。
catで中身を見ようとしたのですが、バイナリファイルのようで読むことさえできませんでした。
これは一体、、、


# なんとかalpコマンドを使える状態に
コマンドを使えるようにする方法を調べていたところ、installというコマンドでインストールできるということがわかり、試してみたところalpコマンドが使えるようになっていました。

```
$  install ./alp /usr/local/bin
$
$ alp -v
1.0.21
```


installコマンド実行後にalpが使えるようになったんだから、installではインストーラの実行をしているに違いない！
と思って調べたのですが、**installコマンドがやっていることはコピーのみ**のようです。

なので、installコマンド実行時の処理は
**alpファイルを/usr/local/binフォルダに移動コピーした**
のみになります。

移動しただけでなんで実行できるようになったんだ、、、

# 謎のファイルの正体はコマンドそのものだった
調べたところ、二つのことがわかりました。

### ① alpというファイルの正体は、コマンドそのものだった
自分がインストーラだと思っていたalpというファイルは、どうやらコマンドそのものだったみたいです。
以下のように、alpファイルを絶対パス指定して実行すると、alpコマンドを実行したときと同じ結果を得ることができました。

```
$ /root/download/tmp/alp -v
1.0.21
```
つまり、コマンドの正体はこのファイルのことだったわけです。
コマンド実行時には、そのコマンドに対応したバイナリファイルを呼ぶ必要があるわけですね。

では、なぜ/usr/local/binフォルダのalpファイルは絶対パス指定をしなくてもよかったのでしょうか？

### ② /usr/local/binは、環境変数のパスが通っていた
そうです。/usr/local/binはパスが通っていました。
そのため、絶対パスを指定をしなくても実行できるようになっていたんですね。
この辺はwindowsと同じなのですぐに理解できました。

```
$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
```

# 普段よく使う標準コマンドはどこにあるの？
alpコマンドをインストールしたことで、コマンドがどうなっているのか知ることができました。
では、普段よく使うcpやlsコマンドはどこにあるのでしょうか？

Linuxには、コマンドを置いておくためのフォルダが複数用意されいてるそうです。

|場所|用途|
|--|--|
|/bin|いつでもだれでも使える基本的なコマンドの実行ファイルがおかれる。全ユーザが使える|
|/usr/bin|基本的なコマンドの実行ファイルがおかれる。全ユーザが使える|
|/usr/local/bin|自作のコマンドなどがおかれる。ユーザごとに管理されている。|

alpコマンドを/usr/local/binに置く理由がわかりました。

# 終わりに
今回はLinuxコマンドの正体をアウトプットしました。わかってみると簡単なことでした。
この調子でLinux初心者脱却を目指します！

# 参考
[PATHを通すってどういうこと？コマンドはどこにある？](https://qiita.com/spre55/items/47da201237450ae2ea4d)
ローカル環境構築

dockerでローカル環境を構築したため備忘録

### 1.docker-compose.ymlでローカル環境を構築する
※すでにdocker-compose.ymlが作成されている場合

docker-compose.ymlファイルがあるディレクトリに移動する
例)desktop/myfail/docker-compose.ymlの場合
```
$ cd desktop/myfail
```
ローカルの開発環境を起動させる
```
$ docker compose up -d
```
これで複数のコンテナが作成され起動する。Docker Desktopでコンテナが存在していればOK

### 2.コンテナ内に入る
```
$ docker exec -it コンテナ名 bash(/bin/bash)
```

### 3.conposerインストール
vendorディレクトリに必要なPHPライブラリや依存関係をインストールする
まずプロジェクト直下に移動する
```
$ cd /ver/www/laravel/ディレクトリ名
```
そしてcomposerをインストールする
```
$ composer install
```
Composerはプロジェクトのvendorディレクトリに必要なPHPライブラリや依存関係をインストールします
プロジェクトの開発環境を設定し、依存関係をインストールできます

venderについて↓
https://biz.addisteria.com/laravel_vendor/

### 補足
DockerFileやdocker-compose.ymlを修正し再度コンテナを立ち上げたい場合は下記コマンドを実行
```
docker compose up --build
```
package.jsonでコマンド引数を渡す方法など

# 基本文法
package.json
```
{
  "scripts": {
    "script_name": "echo Hello ${npm_config_xxx}!"
  }
}
```

terminal
```
npm run script_name --xxx=value
```

output
```
Hello value!
```

# example
package.json
```
{
  "scripts": {
    "example": "echo Hello ${npm_config_name}!"
  }
}
```
terminal
```
npm run example --name=jun01t
```
output
```
Hello jun01t!
```

##when multiple params

--params1=value1 --params2=value2

```
{
  "scripts": {
    "example": "echo Hello ${npm_config_params1}${npm_config_params2}!"
  }
}
```
terminal
```
npm run example --param1=value1 --param2=value2
```
output
```
Hello value1value2!
```

# when set params other script
package.json
```
{
  "scripts": {
    "example": "echo Hello ${npm_config_params1}${npm_config_params2}!",
    "run_example":"npm run example --params1=${npm_config_params1} --params2=${npm_config_params2}"
  }
}
```
command line
```
npm run run_example --params1=value1 --params2=value2
```
output
```
Hello value1value2!
```

# appendix

```
{
  "scripts": {
    "parent": "echo Hello $(npm run -s child)!"
    "child":"echo World"
  }
}
```
terminal
```
npm run parent
```
output
```
Hello World!
```
jlisting パッケージをインストール on Ubuntu

# はじめに
LaTeX で作成した文書内でソースコード（日本語を含まない）を綺麗に表示したい場合、デフォルトでインストール済みの listing パッケージを利用します。一方、日本語を含むソースコードを綺麗に表示するための jlisting パッケージは自ら導入する必要があります。そこで、LaTeX の文書内でソースコード (日本語を含む) を綺麗に表示したい方のために、jlisting パッケージのインストール手順について説明します。

また、jlisting パッケージ未インストールの状態でそれを利用した TeX ソースを無理やりビルドしようとすると、以下のエラーメッセージ [^jlistingエラー]が表示されます。
[^jlistingエラー]: `jlisting.sty` パッケージが自身の環境 (TeX Live) にインストールされていないことを表します。
```
! LaTeX Error: File `jlisting.sty' not found.
```
そこで、このエラーが出た方のためにも jlisting パッケージのインストール手順を説明します。

# 前提とする PC の環境
Ubuntu20.04

# できるようになること
jlisting パッケージの利用

# 今回行うこと
- jlisting パッケージのインストール
- 動作確認

# jlisting パッケージのインストール
まず圧縮ファイル `jlisting.sty.bz2` をダウンロードします。以下をクリックしてください。自動でダウンロードされます。

https://osdn.net/projects/mytexpert/downloads/26068/jlisting.sty.bz2/

ダウンロードした `jlisting.sty.bz2` を任意のディレクトリに配置します。例えば、`~/tmp` に配置してください。

次に、`~/tmp` で `jlisting.sty.bz2` を解凍します。ターミナルを開き以下のコマンドを実行してください。
```
$ bzip2 -d ~/tmp/jlisting.sty.bz2
```

その後、解凍して取得した `jlisting.sty` を listings パッケージのインストールディレクトリに配置します。例えば、listings パッケージのインストールディレクトリが `/usr/local/texlive/2023/texmf-dist/tex/latex/listings/` の場合、以下のコマンドを実行してください。
```
$ cd /usr/local/texlive/2023/texmf-dist/tex/latex/listings/
$ sudo mv ~/tmp/jlisting.sty ./
```
`jlisting.sty` の権限を設定します。以下のコマンドを実行してください。
```
$ chmod 644 jlisting.sty
```
最後に TeX Live のファイルの一覧表を更新します。以下のコマンドを実行してください。
```
$ sudo mktexlsr
```

以上の手順は "[Ubuntu上のtex文書にjlistingパッケージを使ってソースコードを掲載する](https://qiita.com/ocian/items/28bbbec6c44b9b6b44c4)" を参考にしました。

# 動作確認
TeX ソースを用意します。例えば、以下のサンプルファイルをクリックして開き、`sample.tex` として `~/tmp/tex/jlisting_test` ディレクトリに保存してください。

<details><summary>サンプルファイル</summary>

```tex:sample.tex
\documentclass{jarticle}

\usepackage{listings, jlisting}
\renewcommand{\lstlistingname}{リスト}
\lstset{
	language=c,
	basicstyle=\ttfamily\scriptsize,
	commentstyle=\textit,
	classoffset=1,
	keywordstyle=\bfseries,
	frame=tRBl,
	framesep=5pt,
	showstringspaces=false,
	numbers=left,
	stepnumber=1,
	numberstyle=\tiny,
	tabsize=2,
	breaklines = true,
}

\begin{document}
\section{テスト}
\begin{lstlisting} 
#include <stdio.h>

int main(void)
{
	printf("hello, world\n");
	printf("はろーわーるど\n"); //日本語でもOK
	return 0;
}
\end{lstlisting}
\end{document}
```
</details>

サンプルファイルの内容は "[LaTexで綺麗にソースコードを貼る方法【日本語対応可】 - 記述方法](https://prog-masaki.com/latex-sourcecode/)" を参考にしました。

上記の TeX ソースを正常にビルドできたら、jlisting パッケージのインストール完了です。

# おわりに
上記の手順では、`jlisting.sty` ファイルを listings パッケージのインストールディレクトリに配置しました。実は、その配置先をビルドする TeX ソースが置いてあるディレクトリに変えても結果は変わりません。そのため、急いでいる場合や１つの TeX ソースしか編集する予定がない場合には後者をおすすめします。その際は以下の手順を参考にしてください。
```
$ cd <TeX ソースがあるディレクトリ>
$ mv ~/tmp/jlisting.sty ./
$ chmod 644 jlisting.sty
$ sudo mktexlsr
```

# 参考文献
- https://osdn.net/projects/mytexpert/downloads/26068/jlisting.sty.bz2/
- [Ubuntu上のtex文書にjlistingパッケージを使ってソースコードを掲載する](https://qiita.com/ocian/items/28bbbec6c44b9b6b44c4)
- [LaTexで綺麗にソースコードを貼る方法【日本語対応可】 - 記述方法](https://prog-masaki.com/latex-sourcecode/)
社内SE、ラズパイ4を買う。パート6(センサで二酸化炭素濃度を測ろうとしたら火事になりかけたかもしれない話)

・前回

https://qiita.com/ra_risu/items/5f8f8616c7305dd133eb

・やりたいこと

①ラズパイにセンサーをつけて二酸化炭素濃度を測る
②ついでに気温と湿度もはかろうと思う

・解決したい課題

インドア派なので窓を閉め切ってヘッドフォンしてゲームし続けることが多く、たぶん空気が悪くなってるんだろうなとは思うが実態がわからない
温度と湿度はついで

・技術的な課題
これまでソフトウェア上のプログラミングしかしてこなかったので、
ラズパイにセンサーをつけるのは初めて

・まずはセンサー買ったよ
ただうっかり失敗をしてしまった。
AM2302の4ピンには抵抗が必要なのに、抵抗を買っていないのである！

いやね、いくつか初心者向け記事を検索して、「この図の通りにピン繋げば動くよ」っていうのを鵜呑みにしてたんです。まさか同じ型式で３ピンと４ピンがあるとは思わないじゃないですか。
**同じ型式で仕様が全く違う製品が複数あるなんておかしいですよ！**

ものの見事に初心者の罠に引っかかった形となる。
もちろん、このレベルの初心者が今から抵抗だけ買い足してもうまくいくわけがない。
抵抗の使い方もわからない。

これこそ**無駄な抵抗**ってね（ﾄﾞｯ）
結局一度キャンセルして、AM2302だけAmazonで3ピンのものを買いなおした。

まずは先にMH-Z19Cとワイヤが届いたのでそっちをセッティングしようと思うが、
うっかりラズパイを壊したら悲しいのでバックアップを取るところから始める。

ラズパイをシャットダウン
（sudo shutdown -h now）
してmicroSDカード引っこ抜いて

https://tarufu.info/win32diskimager/

を参考にmicroSDカードをバックアップ。

https://procon.fun/2021/10/21/raspberry-pi-%E3%81%A7co2%E6%BF%83%E5%BA%A6%E3%82%92%E6%B8%AC%E5%AE%9A%E3%81%99%E3%82%8B%EF%BC%88mh-z19c%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%EF%BC%89/


キャリブレーションがちょっとめんどくさい。一旦窓際でキャリブレーションして再度シャットダウンして普段の場所に戻すことにした。
上記記事を参考にしてライブラリのインストールをして、キャリブレーションのコマンドまで通った。
しかし、なぜか肝心の二酸化炭素濃度が表示されない。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3565403/4eaf85c7-1e6d-23dc-bc10-4de253609777.png)

「置いてる場所が悪いのかな～」などとのんきに考えつつ、mh_z19を動かそうとしたその瞬間！
**「熱ッッッッッッッッッッッッ！」**</span>


そう、素手で触れないぐらいmh_z19は熱を持っていたのである。
しかも鼻を近づけて嗅いでみると樹脂が焦げたようなにおいがする。
ええ、なんで？
さっき繋いだ時は赤いランプがついたのに、今はついていないし……。

とりあえず安全のためにティッシュを間に挟んで無理やりmh_z19を取り外す。
思い当たる節と言えば、窓際でキャリブレーションするために普段給電しているPCのUSB-TypeC端子ではなくてスマホの充電器（60Wぐらい充電できるはず）にラズパイをつないだことだ。
でも、Type-Cの規格上流れる電流の量はネゴシエーションして決定するはずで、Type-Cをつないだだけで過電流が流れるわけないだろ？
それに過電流が流れたならラズパイ自体が破壊されてないとおかしい（ラズパイは正常に動作している）

え、えー……どうしようこれ……
とにかく、万が一過電流が流れたことが本当なら、これをつなぎっぱなしにしてたら樹脂が焦げて火事になってた可能性もあるわけだよね。
怖い……

・今後
とりあえず一晩様子見して冷やしてから、再度センサをつないで確認する。ダメそうなら返品？　初期不良の可能性もあり。
Figma - レスポンシブデザイン : タブレット、スマホ(2023/10/12)

2023/10/12 レスポンシブデザイン実践 : タブレット、スマホ

1.タブレット版デザイン
 -ガイドを組み直す
	- ガイドラインの設定1024px
	- レイアウトグリッド
		↪︎余白418(左右の余白を30ずつ空ける数値)
		↪︎ガター20
	- ヘッダーやSNSアイコンの調整
		↪︎レスポンシブ調整可能で作成する事で、簡単に縮小できる
	- セクションタイトルはインスタンスを切り離し、タブレット版のコンポーネントを作成する
	- iPad Pro
		↪︎レイアウトグリッド 列数: 12　ガター:20　余白:30

[要復習ポイント]
	- 複数のフレームを用いたオートレイアウトの動き

2.スマホ版デザイン
	- 375pxのフレームを作る
	- ガイド 3列 余白727 ガター15
	- pc用コンポーネント素材を一度インスタンスから解除して再作成する


———よく使うショートカット
・フレームの選択 … 「Command+クリック」 ・要素のコピー … 「option + コピー」 ・キーボード操作だとフレームインしない ・ショートカット ズームイン/アウト … 2本指 コピペ … Command + C,V 複製 … Command + D スタイルを引き継かずペースト … Command + Shift + V スタイルのみコピぺ … Comannd + Option + C / V 画面を動かす … Space + ドラッグ
拡大縮小 … K

———便利プラグイン
Font Viewer … フォント図録
iconify … SNSなど含むアイコンリスト
Hand Wireframe … フリーハンドのワイヤーフレーム
Unsplush … 写真素材
モジュール分割技法とモジュールの評価

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457284/1333c582-49ae-2ab1-3b20-a0d3bbaa6965.png)
１：STS分割
　STS分割とは、データの流れが一直線で分岐がない場合に適用する技法です。S（Source：源泉）、T(Transform：変換)、S（Sink：吸収）の３つのモジュールに分割します。源泉は、入力、変換は処理、吸収は出力に相当します。つまり、STS分割では、ある機能を入力・処理・出力に分けて、それぞれをモジュール単位にするのです。

２：TR分割
　TR（トランザクション）分割は、データの流れが分岐する場合に適用する技法です。データが分岐する地点の機能を振り分けモジュールとして上位モジュールにします。分岐先の機能を振り分けモジュールの下位に配置します。

３：モジュール強度
　モジュール強度は、モジュール単位でのまとまりの良さを表す指標です。モジュール強度が強いほど、使い道が明確で再利用しやすくなります。つまり、モジュール強度が強いほど、「独立性」の高いモジュールであると言えます。
システム環境設定

Pathを初めて通したため備忘録
間違えているところあったら優しくご指摘お願いします、、

環境構築で指定されたコマンドを実行したところ
「'●●●’は、内部コマンドまたは外部コマンド、操作可能なプログラムまたはバッチファイルとして認識されていません。」
とエラーが出て、環境変数のうち1つである「Path」を設定する必要があった

## 環境変数とは
OSに設定を保存するためのシステム変数のこと
Windowsの場合は大きく分けて2種類あり、システム環境変数とユーザー環境変数がある

## 手順
#### 1.システムの詳細設定へ
デスクトップ左下の「スタートメニュー」を右クリックし、表示されたメニューの中から「システム」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3520984/960cf543-ba98-dc15-5d91-9b0dde7a9868.png)
検索窓で「システムの詳細設定の表示」を検索し移動する

#### 2.環境変数でPathを設定
「環境変数」をクリックし、環境変数の画面を表示する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3520984/144f9b6f-9bd1-290d-d759-8f657ff155be.png)
システム環境変数の「変数」欄で「Path」の項目をクリックして選択し、[編集]をクリック
「環境変数名の編集」画面が表示される
[新規]をクリックし、一覧の最後にパスを入力する

例)「C:○○\○○\bin」を追加するとbinコマンドが使えるようになる

これでPathの設定は完了


## ファイルの階層を調べる
#### 1.tab補完
コマンドライン上で「tabキー」を押すと

途中まで打った後にtabキーを押すとコマンド名が補完される

「/Users/」と打った後に「tabキー」を押すと

次の階層のパスが全て出てくる

#### 2.エクスプローラーから調べる
エクスプローラーのアドレスバーのアイコンをクリックするとフォルダーのパスが表示される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3520984/1baa018f-198d-b20b-6421-552dcb580b63.png)

自分のパソコンがmacのため画像お借りしました


参考サイト
https://proengineer.internous.co.jp/content/columnfeature/5205
https://www.scc-kk.co.jp/scc-books/java8_workbook/java_dev-win10.html
https://dekiru.net/article/13408/
マウスジグラーとゆらゆらソーラー

マウスジグラーを検索して、フラワーソーラーの横にマウスを置く画像を見つけました。

![IMG_1755.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2527700/2cc3cc3a-ed7c-315d-9e28-3eec17fc07c2.jpeg)

そうか、百均で買えるゆらゆらソーラーの横にマウスを置けば電源も不要になることに気がつきました。ゆらゆらソーラーを改造すればカッコ良さそうですが、置くだけならすぐ出そう

色々見ているとアナログの腕時計の上に置くというのもありました。これが一番簡単にできそう

アスキーさんのところにいろいろ書いてあった。

https://ascii.jp/elem/000/004/098/4098453/

マウスジグラーの種類についてメモです

# マウスジグラーの種類

大まかに、マウスのエミュレート、実際のマウスと組み合わせて動いたように見せる、実際にマウスを自動的に動かすものに分かれそうです

## マウスのエミュレート

USB マウスまたは Bluetoothマウスをエミュレートするものになります。USBマウスのエミュレートは、Raspberry Pi Pico でマウスジグラーの自作とかでもよく出てきます。Amazonでみると製品も多そう。

Bluetoothマウスのエミュレートは、iPhoneとかでも使えそう。Bluetoothマウスのエミュレートは、micro:bitでも作れるのでそれをベースにマウスジグラーが作れます。micro:bitはボタンもⅡつあるし、傾きセンサーもあるので空中マウスとしても使えて遊ぶには便利です。

## 実際のマウスと組み合わせて動いたように見せる

フラワーソーラーの横にマウスを置くのとか。Amazonでみる製品では、マウスのLEDの下に回転する円盤みたいなのがあって、そこにマウスを乗せるとマウスが動いたように見せかけるものでした。普通にマウスを使って、PCから離れるときに、マウスジグラーを置くという感じ

## 実際にマウスを自動的に動かす

マウスは、ちょっとした振動でも動くので、マウスに振動が与えられればマウスが少し動いてマウスジグラーのようになります。

# キーボードジグラー

マウスジグラー以外にもキーボード版もありました。

https://davesteele.github.io/raspberrypi/2021/04/18/keyboard-jiggler/

# キーボードにマウスジグラーを追加する？

自作キーボードで使われる QMK Firmware にマウスジグラーを入れる方法が紹介されてました。

https://www.reddit.com/r/MechanicalKeyboards/comments/10b3pk7/how_to_add_a_mousejiggler_toggle_macro_to_your/
ARM版CPUのM1 MACにてffmpegのh265ソフトウェアエンコードを高速化する方法

こちらからApple Silicornのffmpegをダウンロードする

https://www.osxexperts.net/

zipを解凍したら、

```
sudo mv ffmpeg /usr/local/bin/ffmpeg
```

フォルダで、/usr/local/bin/に移動して、
ffmpegをダブルクリックして、ハイを押して起動すれば使える。

brewで入れてソフトエンコードをしたときはspeed=0.4だったものが、1.19になった。


参考：https://zenn.dev/esaka/scraps/bb29de3b30fc13
メモリ不足でエラーになったのでDockerのメモリを上げた

## 環境

- M1 Mac
    - OS Ventura v13.6
- Docker Desktop
    - v4.22.1

## 経緯

`$ docker build . -t erd`を実行した。1時間40分ほどbuildを実行した挙句、以下のエラーが出て処理が中断してしまった。

```bash
Error: cabal: Failed to build graphviz-2999.20.1.0 (which is required by
exe:erd from erd-0.2.1.0). The build process was killed (i.e. SIGKILL). The
typical reason for this is that there is not enough memory available (e.g. the
OS killed a process using lots of memory).
```

エラーメッセージを見ると、**メモリ不足**のようだ。  
使用しているM1 Macのメモリは8Gしかなく、アクティビティモニタで確認すると確かに処理がかなり重そうだった。

## 対応

これを機にメモリ16GのMacに買い替えようと思ったが、もっと良い（そして早い）解決策があった。

『Docker for Desktop』で、「Extensions」　-> 「Settings」 -> 「Resources」を開き、「Memory」の欄で4Gから6Gに変更し、右下の「Apply & restart』ボタンを押す。

これでDockerが使用するメモリを6Gまで増やすことができた。

![スクリーンショット 2023-10-12 21.07.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/911578/fa57bca9-badd-e8de-b6db-233775ae30d9.png)


## 参考

- [Docker process killed with cryptic `Killed` message](https://stackoverflow.com/questions/44417159/docker-process-killed-with-cryptic-killed-message)
- [Macのメモリ使用量を簡単に減らす7つの方法 (MacBook Pro、Air、iMacで適用可)](https://macpaw.com/ja/how-to/reduce-memory-usage-on-mac#:~:text=Mac%E3%81%AERAM%E4%BD%BF%E7%94%A8%E9%87%8F,%E3%83%97%E3%83%AD%E3%82%BB%E3%82%B9%E3%81%8C%E8%A1%A8%E7%A4%BA%E3%81%95%E3%82%8C%E3%81%BE%E3%81%99%E3%80%82)
k8sにおけるCSIプラグインを使用したストレージのライフサイクル

# k8sにおけるCSIプラグインを使用したストレージのライフサイクル

**1. はじめに**
Kubernetesは、コンテナオーケストレーションの世界標準として広く認識されています。この節では、Kubernetesでのストレージの基本概念と、Container Storage Interface (CSI) の役割について概説します。

**2. CSIを使用したストレージのライフサイクル**
了解しました。以下のように「CSIを使用したストレージのライフサイクル」の項目をより詳細なステップに分けてみました。

   - **2.1 初期要求**: ユーザーがPersistentVolumeClaim (PVC) を作成し、特定のストレージ容量やアクセスモードを要求します。

   - **2.2 プロビジョニング**:
     - **2.2.1 PVCとPVのマッチング**: PV Controllerが既存のPVをチェックし、PVCの要求に適合するものを探します。
     - **2.2.2 PVの動的プロビジョニング**: 一致するPVが存在しない場合、csi-provisionerが動的に新しいPVをプロビジョニングします。

   - **2.3 アタッチメントプロセス**:
     - **2.3.1 Podのスケジューリング**: スケジューラーがPodをノードに割り当てます。
     - **2.3.2 VolumeAttachmentオブジェクトの生成**: AD ControllerがPVのアタッチメントを検知し、VolumeAttachmentオブジェクトを作成します。
     - **2.3.3 実際のストレージアタッチ**: csi-attacherがcsi-controller-serverを通じて、バックエンドのストレージシステムにpodがスケジュールされるノードにアタッチするように要求を行います。

   - **2.4 マウントプロセス**:
     - **2.4.1 ノード上のマウントポイントの確保**: kubeletは、ノード上でPVをPodにマウントするためのマウントポイントを確保します。
     - **2.4.2 実際のマウント実行**: kubeletはcsi-node-serverを使用して、ストレージをPodのディレクトリにマウントします。

   - **2.5 使用とデタッチメント**:
     - **2.5.1 ストレージの使用**: アプリケーションはマウントされたストレージを通常のファイルシステムとして使用します。
     - **2.5.2 デタッチメント**: Podが削除されたりノードから移動されたりすると、ストレージはデタッチされ、必要に応じて再利用または削除されます。

このように、ライフサイクルの各ステップを詳細に分解することで、CSIを使用したストレージのプロセスをより明確に

**3. ストレージのプロビジョニング**
ストレージの要求は、PersistentVolumeClaim (PVC) を使用して行われます。PVCが提出されると、一致するPersistentVolume (PV) が検索され、存在しない場合は新たにプロビジョニングされます。
   - **PV Controllerとcsi-provisionerの相互作用**: PV ControllerはPVCに一致するPVを探します。一致するものがない場合、csi-provisionerにストレージのプロビジョニングを要求します。
   - **バックエンドストレージのプロビジョニング**: csi-provisionerは、バックエンドのストレージシステムに対してストレージボリュームのプロビジョニングを要求します。

**4. ストレージのアタッチメント**
Podがデプロイされると、AD ControllerはPodが使用するPVを確認します。
   - **VolumeAttachmentの生成**: 必要に応じて、VolumeAttachmentオブジェクトが生成されます。
   - **ノードへのアタッチ操作**: csi-attacherは、csi-controller-serverを通じて、ノードへのアタッチ操作を行います。

**5. ストレージのマウント**
Podが起動する際、kubeletはストレージをPodからアクセス可能なディレクトリにマウントします。
   - **ディレクトリ構造**: マウントポイントは、`/var/lib/kubelet/pods/<pod-uuid>/volumes/<volume-type>/<volume-name>` のような構造を持ちます。
   - **コンテナのストレージアクセス**: 一度ストレージがマウントされると、Pod内の各コンテナは指定されたマウントポイントを通じてストレージにアクセスできます。これにより、アプリケーションが永続的なデータストレージを利用できるようになります。

**6. クラウドストレージベンダーのAPIとの連携**
CSIドライバは、クラウドプロバイダーやストレージベンダーが提供するAPIを使用して、ストレージのプロビジョニング、アタッチメント、およびその他の操作を行います。
   - **OpenAPIとストレージの操作**: クラウドプロバイダのAPIは、通常RESTfulなインターフェースを持ち、CSIドライバはこれを用いてストレージリソースの操作を行います。
   - **一般的なクラウドプロバイダの例**: AWS, GCP, Azureなどのメジャーなクラウドプロバイダは、それぞれのストレージサービスに対してAPIを提供しています。CSIプラグインは、これらのAPIを使ってストレージの操作を行います。

**7. まとめ**
Kubernetesのストレージの管理は、CSIプラグインの登場により、より柔軟で拡張可能になりました。ストレージベンダーやクラウドプロバイダは、独自のCSIドライバを提供することで、Kubernetesとの統合を簡単に行うことができます。これにより、エンドユーザーは様々なストレージソリューションを簡単に利用できるようになりました。今後も、KubernetesとCSIの連携はさらに深まることが予想され、多様なストレージ要件に対応するための新しい機能や拡張が追加されることでしょう。
`Error: spawn node-gyp ENOENT`の解消方法

# エラー内容

`docker build`時に出たエラーです。

```
Error: spawn node-gyp ENOENT
    at ChildProcess._handle.onexit (node:internal/child_process:284:19)
    at onErrorNT (node:internal/child_process:477:16)
    at process.processTicksAndRejections (node:internal/process/task_queues:82:21)
Emitted 'error' event on ChildProcess instance at:
    at ChildProcess._handle.onexit (node:internal/child_process:290:12)
    at onErrorNT (node:internal/child_process:477:16)
    at process.processTicksAndRejections (node:internal/process/task_queues:82:21) {
  errno: -2,
  code: 'ENOENT',
  syscall: 'spawn node-gyp',
  path: 'node-gyp',
  spawnargs: [ 'rebuild' ]
}

Node.js v18.18.1
```

「`node-gyp`をグローバルインストールすれば解消できる」という事例もブログなどで見かけましたが、これでは解消せず・・・

# 原因

Dockerfile内の`node`イメージのバージョンだったようです。

`node:18`から`node:18.17`に変更することで解消できました。マイナーバージョンまで指定するところがキモです。

# まとめ

JavaScript周りのライブラリは結構Node.jsのバージョンに依存していることがあるので、メジャーバージョンのみの指定や`latest`を使用するのはビルドプロセスの安定稼働を考えるとちょっと不安です。

経験上、マイナーバージョンまで固定するのが良いです（パッチバージョンまで固定するのはやり過ぎ感がある、かつ軽微なバグ修正やセキュリティパッチが入る可能性を考えると、ここは緩く受け入れた方が良さそう）。
Arduino 高速 Lチカ 対決

# はじめに

知人より[SDS1104オシロスコープ](http://owon.co.jp/products_info.asp?ProductID=63)を借りたので、ノーウエイトのLチカの周波数を測定してみた。

# Arduino

対決に使用したArduinoボードは、次の3つ。

- Arduino Uno R3 

- Arduino Uno R4 minima

- ESP32-D0WDQ6 (revision v1.0)（Arduino環境）

# Lチカプログラム

対決に使用したSketchは、次のとおり。
Arduino Uno R3とR4はD8ポート、ESP32はGPIO18を使用。

```c
#include <Arduino.h>

#define LED (8)    // for Arduino Uno R3 / R4
//#define LED (18) // for esp32

void setup() {
  pinMode(LED, OUTPUT);

  while (1) {
    digitalWrite(LED, HIGH);
    digitalWrite(LED, LOW);
  }
}

void loop() {
}
```

# 結果

|#|ボード|Lチカ周波数|CPUクロック|
|:-:|:-|-:|-:|
|1|Arduino Uno R3|150.8KHz |16MHz |
|2|Arduino Uno R4 minima|686.8KHz |48MHz |
|3|ESP32-D0WDQ6|1.495MHz |240MHz |

- ↓Arduino Uno R3
![data_22994_R3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283293/6895e85d-588a-ecf3-e74b-e2125922de2b.png)

- ↓Arduino Uno R4 minima
![data_38494_R4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283293/1dbab77c-61ce-28e4-1ba8-f40d19860aad.png)

- ↓ESP32-D0WDQ6（Arduino環境）
![data_50739_esp32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283293/eec313af-11b7-dab0-1dfd-a9f3f32228c6.png)

# まとめ

順位は測定前から想定していた通りであった。

しかし、Arduino **Uno R4** と **ESP32** は、CPUクロック差ほどの差がないのは意外だった。

_ESP32が遅い？ ESP-IDF環境なら、もっと早いのだろうか？_


# 追試

ESP32のESP-IDF環境のノーウエイトLチカを測定した。

```c:blink_example_main.c（ESP-IDF環境）
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "esp_log.h"
#include "sdkconfig.h"

#define BLINK_GPIO GPIO_NUM_18

static void configure_led(void)
{
    gpio_reset_pin(BLINK_GPIO);
    gpio_set_direction(BLINK_GPIO, GPIO_MODE_OUTPUT);
}

void app_main(void)
{
    configure_led();

    while (1) {
        gpio_set_level(BLINK_GPIO, 1);
        // vTaskDelay(CONFIG_BLINK_PERIOD / portTICK_PERIOD_MS);
        gpio_set_level(BLINK_GPIO, 0);
        // vTaskDelay(CONFIG_BLINK_PERIOD / portTICK_PERIOD_MS);
    }
}
```

- ↓ESP32-D0WDQ6（ESP-IDF環境）
![data_8773_idf.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283293/32811584-b1b0-147b-351d-d83a0ab359ae.png)


性能は、Arduino環境より若干低い、1.441MHzと想定外の結果であった。

<hr>

↓レジスタを直接いじれば、3.5MHzほどに高速化できます。

https://qiita.com/caa45040/items/2528b6d8f002c4a6b129#comment-ac7cd9a84362b5516a77


**おしまい**
AWS サービス名の由来を勝手に想像する

# はじめに
AWSって本当にたくさんサービスがありますよね。
SAAの試験勉強をしている時、VPCやEC2、RDS、S3などよく使われるサービスは自然と覚えるのですが、あまり使う機会が少ないサービスだとなかなか頭の中に入ってきません。
そんな時、私は「そもそもこのサービスって何でこんな名前なんだろう？」というところから、少しずつ分かることを積み上げていました。
そこで、今回は私が勝手に想像したAWSサービス名の由来についてまとめたいと思います。
（勝手にとはいいながらいい線をいっているのではないかと思っています）

:::note info
追加があれば随時更新していきます。
:::

# 私が勝手に想像したサービス名の由来
### Elastic Beanstalk
- アプリケーションに必要なインフラ環境を自動でデプロイしてくれるサービス。
> Elastic Beanstalk は、ウェブアプリケーションやサービスのデプロイとスケーリングのためのサービスです。コードをアップロードすることで、Elastic Beanstalk が、容量のプロビジョニング、ロードバランシング、Auto Scaling からアプリケーションの状態モニタリングまで、デプロイを自動的に処理します。
- Beanstalkの意味は「豆の木」
- 名前の由来を「一晩で天まで伸びたジャックと豆の木のように、アプリケーションをアップロードするだけで豆の木が伸びるようにインフラ環境ができあがるから命名」と勝手に想像。

### S3 Glacier
- データアーカイブ専用に設計されているS3のストレージクラス。データの取り出しに時間がかかる。
- Glacierの意味は「氷河」
- 名前の由来を「データを硬い氷河のようにデータをしっかりと守るが、解けにくい氷河のように中のデータを取り出すには時間がかかることから命名」と勝手に想像。

### Amazon Cognito
- ウェブアプリとモバイルアプリ用のアイデンティティプラットフォーム。
- 「Cognito」という英単語はない。
- 否定の「in」を付けたIncognitoの意味は「匿名の」。Incognitoから否定のinを取り「記名」を表しているのではないか。「記名」は自分で書き記すこと。
- 名前の由来は、「Cognitoは利用者自身がID登録できるサービスであり、「利用者自身が登録する」 ＝ 「自分で書き記す」ことから命名」と勝手に想像。

# まとめ
いかがでしたでしょうか。
あくまで私が勝手に想像した名前の由来なのであっているかわかりませんが、「なるほど！」と思ってもらえるものがあれば嬉しいです。
【SwiftUI】ScrollViewの高さを動的に変更する方法

## はじめに
記事をお読み頂きありがとうございます！Reeenと申します。
私は現在、株式会社ゆめみで内定者アルバイトとしてiOSアプリの開発を行っています。
そこでScrollViewの縦方向の無限拡張で少し詰まり、この方法を発見したのでアウトプットをしようと思いました。
少しでも参考になれば幸いです🙇‍♂️

## 動作環境
Swift: 5.7.2
Xcode: 14.2
iOS: 15.0+

## 内容
まず前提としてSwiftUIのScrollViewでは以下のようなコードを書いても内容に合わせて自動で高さが調節されることはなく、無限拡張(.infinityのような挙動)になってしまいます。

```swift
ScrollView {
    Rectangle()
        .fill(.purple)
        .frame(width: 300, height: 300)
}
.border(.black, width: 5)
```

<img width="200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745924/0c5c0096-0bad-7053-e716-e6ed92cf2bd1.png">

そこで、以下のコードを追加します。

```swift
@State private var contentHeight: CGFloat = 0.0
```
```swift
.overlay(
    GeometryReader { proxy in
        Color.clear.onAppear {
            contentHeight = proxy.size.height
        }
    }
)
```
```swift
.frame(maxHeight: contentHeight)
```

その結果、下記写真のようにScrollViewのサイズが自動で調整されました。
<img width="200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745924/0e52a859-7925-bd3e-5ecb-7c5326415745.png">

(紫色の部分がスクロールできます)

## コードの全体
```swift:HogeView.swift
struct HogeView: View {
    @State private var contentHeight: CGFloat = 0.0

    var body: some View {
        ScrollView {
            Rectangle() //ここにScroll可能にしたいViewを設置してください
                .fill(.purple)
                .frame(width: 300, height: 300)
                .overlay(
                    GeometryReader { proxy in
                        Color.clear.onAppear {
                            contentHeight = proxy.size.height
                        }
                    }
                )
        }
        .border(.black, width: 5)
        .frame(maxHeight: contentHeight)
    }
}

struct HogeView_Previews: PreviewProvider {
    static var previews: some View {
        HogeView()
    }
}
```

## 最後に
ここまでお読み頂きありがとうございました！
もっと良い方法があれば教えてください！
SwiftUI頑張ります😁

## 参考文献
https://developer.apple.com/forums/thread/671690
Research Nesterによる医療用カートの市場分析で、2023年から2033年にかけて市場が成長することが明らかに

Research Nester社は、世界の医療用カート市場の成長について、重要な医療用品の容易な入手や、医療ミスを防止するためのERP導入の増加によるものと予測している。
ニューヨーク-2022年10月10日-リサーチ・ネスターの最新市場調査分析は以下の通り「医療用カート市場： 世界の需要分析と機会展望2033年"この調査レポートは、世界の医療用カート市場をタイプ別、製品別、素材別、用途別、エンドユーザー別、地域別に分類し、詳細な競合分析と市場概要を掲載しています。

重要な医療用品を容易に入手できることが、世界の医療用カート市場の成長を促進する
世界の医療用カート市場は、世界的に重要な医療用品が容易に入手できることから、大きく成長すると推定されている。このような現状を踏まえ、医療機器業界団体は必要不可欠な医療機器の小売価格を引き下げるよう求められている。すべての医療機器は現在、2013年医薬品（価格統制）令（DPCO）に基づく価格統制の対象となっており、2020年4月1日に発効する。

市場調査レポートには、世界の医療用カート市場の成長に関連するその他の成長要因や課題も含まれています。主な成長指標は以下の通りです：

成長ドライバー：
世界人口による医療費の増加
ヘルスケア産業における技術分野の進歩

課題だ：
医療用カートのメンテナンスコストが高いこと、初期投資が高額であることは、世界の医療用カート市場の成長を妨げる主要な要因の1つです。市場の成長に関連する数多くの阻害要因にもかかわらず、Research Nesterの分析では、予測期間中の市場の堅調な成長を示しています。
この調査レポートは、世界の医療用カートに関する市場調査報告書であり、現在および将来の市場動向に関する詳細な考察とともに、業界の成長指標、阻害要因、需給リスクに関する詳細な分析を網羅しています。これらの分析は、組織が予測不可能な未来で成功するための継続的な成長機会を特定するのに役立ちます。さらに、市場が露呈している成長機会は、今後数年間で大きな勢いを得る用意があります。
![Medical-Carts-Market-Analysis.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3491677/2a66a1e1-d0c8-5261-b0c1-b5f7baee3ade.png)

詳細レポートへのアクセスはこちら：
https://www.researchnester.jp/reports/medical-carts-market/551

医療用カートの世界市場は、タイプ別に医療用カート、救急用カート、処置用カート、麻酔用カート、遠隔医療用カートに区分される。プロシージャカート分野は、多くの病院でプロシージャカートの利用が増加していることを背景に、2033年末までに最大の収益を獲得すると予測されている。
地域別では、アジア太平洋地域の医療用カート市場が2033年末までに最も高い収益を上げる。この成長は、同地域における医療インフラの改善と筋骨格系損傷の有病率の増加によって予想される。

この調査レポートは世界の医療用カート市場を詳細に分析しています North America (U.S., Canada), Europe (U.K., Germany, France, Italy, Spain, Hungary, Belgium, Netherlands & Luxembourg, NORDIC [Finland, Sweden, Norway, Denmark], Poland, Turkey, Russia, Rest of Europe), Latin America (Brazil, Mexico, Argentina, Rest of Latin America), Asia-Pacific (China, India, Japan, South Korea, Indonesia, Singapore, Malaysia, Australia, New Zealand, Rest of Asia-Pacific), Middle East and Africa (Israel, GCC [Saudi Arabia, UAE, Bahrain, Kuwait, Qatar, Oman], North Africa, South Africa, Rest of Middle East and Africa). また、医療用カートの世界市場規模、前年比成長率および機会分析、市場プレイヤーの競争力調査、投資機会、将来展望に対する需要などの分析も調査レポートに掲載されています。

また、本レポートは世界の医療用カート市場における主要企業の競争シナリオを提供しており、以下の企業のプロフィールを掲載していますInterMetro Industries Corporation, Harloff Company, Armstrong Medical Ltd, Capsa Solutions LLC., ITD GmbH, Midmark Corporation, The Bergmann Group, Lakeside Manufacturing, Inc., Cardinal Scale, Merino International,プロファイリングでは、事業概要、製品およびサービス、主要財務情報、最近のニュースおよび開発など、企業の主要な情報を掲載しています。全体として、当レポートは世界の医療用カート市場の詳細な概観を描いており、業界コンサルタント、機器メーカー、拡大機会を探している既存企業、可能性を探している新規企業、その他の利害関係者が、現在進行中および今後予想される動向に従って市場中心の戦略を調整するのに役立ちます。

レポートサンプル@を請求する
https://www.researchnester.jp/sample-request-551

について Research Nester
Research Nesterは戦略的市場調査とコンサルティングのリーディング・サービス・プロバイダーです。業界、コングロマリット、エグゼクティブが将来のマーケティング戦略、事業拡大、投資などのために賢明な決断を下せるよう、偏りのない比類のない市場洞察と業界分析を提供することを目指しています。私たちは、戦略的思考を通じて適切なタイミングで適切なガイダンスを得ることができれば、あらゆるビジネスが新たな地平へと拡大できると信じています。私たちの既成概念にとらわれない思考は、お客様が将来の不確実性を回避するために賢明な決断を下すのに役立ちます。
【お問い合わせ先】

ナオミ コスギ
Eメール: info@researchnester.jp
米国の電話番号: +81 505 050 8480
【Swift】CIFilterで画像にノイズを合成する

# はじめに
最近、画像加工系のアプリを作っているのでCIFilterを使うことが多いです。
CIFilterを使ったアウトプットをしていこうと思います。
今回は画像にノイズを追加するコードをやってみます。

# 元画像
![icon.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/287cebbc-c32c-defe-fa7a-bc047bd34519.png)

# 生成されるノイズ画像
![outputImage.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/49e1bfcb-b07a-4b4c-fece-86a84da14c18.png)

# 実装
```swift
import SwiftUI

struct ContentView: View {
    @State private var displayImage: UIImage?

    private let image = UIImage(named: "sample")!

    var body: some View {
        VStack {
            if let displayImage {
                Image(uiImage: displayImage)
                    .resizable()
                    .scaledToFit()
                    .frame(width: 300)
            } else {
                Image(uiImage: image)
                    .resizable()
                    .scaledToFit()
                    .frame(width: 300)
            }
            
            Button {
                applyNoise()
            } label: {
                Text("ノイズ追加")
            }
        }
    }

    func applyNoise() {
        let context = CIContext()
        let inputImage = CIImage(image: image)!
        // ノイズを作成
        guard let noiseFilter = CIFilter(name: "CIRandomGenerator") else { return }
        guard let noiseOutputImage = noiseFilter.outputImage else { return }
        // ブレンド
        guard let blendFilter = CIFilter(name: "CIMultiplyBlendMode", parameters: [
            kCIInputImageKey: noiseOutputImage,
            kCIInputBackgroundImageKey: inputImage
        ]) else { return }
        // 出力
        guard let blendOutputImage = blendFilter.outputImage else { return }
        guard let cgImage = context.createCGImage(blendOutputImage, from: inputImage.extent) else { return }
        self.displayImage = UIImage(cgImage: cgImage)
    }
}
```

# 結果
![simulator_screenshot_229663CF-B2CC-45F1-AC19-8484A2CD9E64.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/7f25354b-581d-0ad1-a373-3f63e9c2dd0f.png)

# おわり
CIFilter深いですね