OmniAICreator/Qiita-1.07M huggingface dataset:
【2024年05月版】LinuxでTCP通信を強制的に切断する方法、ただしプロセスは殺さない

# はじめに

LinuxでSocket通信してるプログラムのデバッグをしてるときに、
プロセスを殺さずに指定のポートの通信だけ切断したい。。。さてどうするか。。。

を ChatGPT と解決したときのメモ

:::note info
Amazon Linux 2023 の場合を追加しました。
公式の EPEL がないので、Fedora の EPEL から rpm をとってきてインストールするのが楽。
:::

# ゴール

通信が ESTAB になっている通信を一時的に通信断にさせる

```terminal 
$ ss -ant 
State  Recv-Q  Send-Q Local Address:Port Peer Address:Port 
  :
  :
ESTAB  0       0      [10.0.0.1]:41880   [10.0.0.2]:33333  ← この接続を一時的に通信断にする
```

# インストール

## UBUNTU22.04 の場合

```terminal
sudo apt install dsniff
```

## RHEL9.2 の場合

```terminal
sudo yum install dsniff
```

## amazon linux 2022 の場合

```terminal
sudo amazon-linux-extras install epel -y
sudo yum install dsniff
```

## amazon linux 2023 の場合

- fedora の epel から rpm をダウンロードする
    - https://dl.fedoraproject.org/pub/epel/9/Everything/x86_64/Packages/
- dnf で libXmu, libnet をインストールする
- rpm で libnids をインストールする
- rpm で dsniff をインストールする

### ダウンロード

```terminal
wget https://dl.fedoraproject.org/pub/epel/9/Everything/x86_64/Packages/l/libnids-1.24-23.el9.x86_64.rpm
wget https://dl.fedoraproject.org/pub/epel/9/Everything/x86_64/Packages/d/dsniff-2.4-0.37.b1.el9.x86_64.rpm
```

### インストール

```terminal
sudo dnf install libXmu
sudo dnf install libnet
sudo rpm -ivh libnids-1.24-23.el9.x86_64.rpm
sudo rpm -ivh dsniff-2.4-0.37.b1.el9.x86_64.rpm
```

# 通信断手順

ここでは eth0 の 33333 ポートで接続しているプログラム

## ポートの確認

```terminal
sudo ss -antp | grep :33333
ESTAB  0      0      [10.0.0.1]:57684 [10.0.0.2]:33333 users:(("java",pid=18771,fd=21))  
```

## 通信断

Ctrl+c をするまで切断される

```terminal
sudo tcpkill -i eth0 port 33333
tcpkill: listening on eth0 [port 33333]
10.0.0.2:33333 > 10.0.0.1:57684: R 458329705:458329705(0) win 0
10.0.0.2:33333 > 10.0.0.1:57684: R 458330194:458330194(0) win 0
10.0.0.2:33333 > 10.0.0.1:57684: R 458331172:458331172(0) win 0
  :
  :
```

# さいごに

かんたんでしたね。
もっと快適にvscodeでswaggerを書きたい！（プラグインまとめ）

ファイル分割もいいけど、取り回しわるくなるとねぇ
分割ファイルをひとまとめにするスクリプトをメンテするのさぼっちゃうし
分割そのままで対応してきてるツールももうあるのかな・・？
でもそうするとprismとかのモック動かすときにどうなるんだろう・・

1ファイルにしといて、コードジャンプやらの開発環境を最強にできればそれがベストなのでは！
ということでvscodeに入れるプラグイン考えていきましょう

## 入れるプラグイン
vscodeでswagger書くっていったらやっぱりこれ
swagger ui表示しながら書かないとね

https://marketplace.visualstudio.com/items?itemName=Arjun.swagger-viewer

正直これはちゃんと活用できている気がしないけど、改めて調べてみるとめっちゃ便利な機能なんすね・・
Snippetsとか書いてあると脳死でインストールしてしまうのですよ・・
これからは活用していこう

https://marketplace.visualstudio.com/items?itemName=adisreyaj.swagger-snippets

もっと快適にかきたい！と思って今回調べて追加したやつ
swaggerって1ファイルでやってるとどうしても肥大化する・・
のでどう効率的にジャンプするかってのがポイントになってくる（ファイル分割もいいけど、取り回し悪くなるの嫌だ）
そこで、アウトライン表示しっかり活用する！

https://marketplace.visualstudio.com/items?itemName=42Crunch.vscode-openapi

「linterの導入はもはや義務よねー」という話を同僚エンジニアとして焦って急いでいれたやつ

https://marketplace.visualstudio.com/items?itemName=mermade.openapi-lint


## 成長を期待したいプラグイン

https://redocly.com/

ちょっとこれワクワクしかない
カーソル置くだけでGUI操作できるだって・・

![スクリーンショット 2023-10-03 9.47.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/323088/2a95a999-a19c-972d-ab7c-8e0de68b5a54.png)

まだ、infoとかtagsにしか使え無さそう・・
肝心なところはまだですが、pathsとschemasに対応されるといよいよって感じがする
なので成長を期待したい！！！
elasticsearchのrefreshに関して

## はじめに
elasticsearchには[Refresh API](https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-refresh.html)なるものが存在する。
ドキュメントをインデックスしたら即検索できるようになると考えていた自分は、このrefreshを意識せずelasticsearchを使用していたため、elasticsearchの絡むテストを書くときにハマりかけた。今回はrefreshに関する備忘録を残しておく。

## なぜrefreshが必要なのか？
前提として、elasticsearchではドキュメントをインデックスしただけで検索可能な状態になるわけではない。追加されるドキュメントは一旦In-memory bufferという領域に溜め込まれた上で、まとめて検索対象にとして反映されるようになっている。
このIn-memory bufferに溜め込まれたドキュメントを検索対象として反映する処理がrefreshと呼ばれている。

https://www.elastic.co/guide/en/elasticsearch/reference/current/near-real-time.html#img-post-refresh

## 普段はなぜrefreshを意識せずに使えるのか？
elasticsearchでは上記で述べたrefreshを**1秒間隔で自動的に実行**している。1秒という短い間隔で追加したインデックスが検索可能の状態になるため、通常の利用時はrefereshを意識する必要がない。
（elasticsearchが「"ほぼリアルタイム"の検索プラットフォーム」とされている理由は、厳密に言うと検索できるようになるのが1秒後だからだと思われる。）

## テスト時に困ったこと
「通常の利用時はrefereshを意識する必要がない」と前述したが、テスト時はその限りではない。
例えば、FactoryBotでレコードを作成して、検索によって目的のレコードが表示できるかを検証するspecを書くとする。
FactoryBotでレコードが作成されてからアサーションが実行されるまでの間でrefreshが実行される保証はないため、**目的のレコードのドキュメントが検索可能ではない状態でアサーションが実行されてしまいテストが落ちる**ということが発生し得る。自分の参加している案件では、これが原因でテストがflakyとなってしまっていた。
FactoryBotでレコードを作成し、アサーションが実行される前に明示的にrefreshを行う必要があった。

## 解決策：明示的なrefreshを行う
ドキュメント単位でのrefreshの場合は[このRefresh API](https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-refresh.html)を使用する。
今回の案件ではelasticsearch-railsを使用していたため、以下のようにしてindex_documentにrefreshオプションを渡すことで明示的なrefreshを行った。これにより、アサーションが実行される際にドキュメントが検索可能な状態になっていることが担保できるようになり、flakyテストを解消することができた。


```.rb
factorybot_created_record.__elasticsearch__.index_document(refresh: :wait_for)
```

refreshに渡すことができる引数は以下。

引数 | 説明
--- | ---
**true** | デフォルトでは1秒間隔で実行されるrefreshを即時で実行させる。 
**:wait_for** | 次のrefreshが実行され、documentが検索可能になるまで待つ。trueとは違い、強制的にrefreshを実行させるわけではない。
**false (default)** | refreshに関連するアクションは行わない。デフォルトの1秒間隔でrefreshが行われる。

https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-refresh.html

## 疑問点
最初は`refresh: true`に設定していたがflakyテストは解消せず、`refresh: :wait_for`に変更したところテストが落ちなくなった。`refresh: true`は即時refresh、`refresh: :wait_for`はタイミングは変えずに定期refreshを待つという認識だったので、`refresh: true`でflakyテストが解消しなかった理由がわからん。
（`refresh: :wait_for`では「可視化」を待つという点が重要だったりするのか・・・？）
> Wait for the changes made by the request to be made visible by a refresh before replying.

※この記事は以下のZennの記事から移行したものです
https://zenn.dev/kyo18/articles/b8409bff18d277
【RPA展開#05】そして伝説へ…行く前に「勇者」がいない？

# はじめに
どうも、husuiです。
憧れの芸能人は高田純次とユースケ・サンタマリアです。

UiPath（ユーアイパス）[^0]というRPA[^1]の会社で、若干業務よりの人として[働いています。](https://qiita.com/husui/items/b047615d56f0a0cfe014)
[^0]: https://www.uipath.com/ja
[^1]: Robotic Process Automationの略です。

今回も`私見的RPA展開メソドロジー`というか`ポエム`の続きです。
実は同僚からは「本当にコレ着地するのかねぇ～（ニヤニヤ）」なーんて冷ややかな目で見られ始めていますが、そんなの気にしません（汗）。
実は着地なんて考えてなくて、というか着地できるとあまり思っていないくて、書き散らかして終わるつもりだったんですからぁ！残念！（波田陽区）

というわけで、
全然体系立てておらず、自分の思考整理も兼ねて書いています。
一通り書き終わった後で全体を俯瞰して体系立ててみたいと思います。

ちなみに前回の記事はこちらです。

https://qiita.com/husui/items/03951fee2ee2eea96e1d

:::note warn
注意
本記事はあくまで個人的見解を元とした内容となっております。所属団体の公式見解ではございませんのでご了承くださいね！
:::

# 「身銭」を切るってなんかあるあるでは？
前回は
「身銭」を切るか？切らないか？とか、
仲間を見つけて小さい成果出して国王に認められて魔王と倒しに行くとか、
最後はファンタジーに走ってしまってまたいつも通り`自己嫌悪`ですよまったく。

でもこれってもうちょっと言い方を変えてみると、
「新しいことを始めるにあたって、
初期段階は有志活動に留め、
徐々に広がってきたら公式活動化として動く」
ってことですよね。

**「あれ？こういう話って、普通にあるあるじゃない？？**
**こういうアプローチって、よくビジネス書に載ってない？？」**

そう。
これは別に何も新しい概念でも発想でも発明でもなく、
ずっと以前からある考え方・アプローチを単に言い換えただけですよね。
![PXL_20231003_000901053.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3329659/b8ad9f62-bf4e-0ae3-d886-e9af49440152.jpeg)
「なんだよ、フツーのこと言ってるじゃんhusui。つまんないのー。（ページ離脱）」
って思われた方、ごめんなさい。

でも逆に言うと。
これまでずっとこういうアプローチが言われ続けている、
どの書籍にも似たようなことが書いてある、
ということは、
「いつの時期時代にも、そのアプローチを模索しようとしているニーズがある」
ということですよね？　
つまり、 **みんなわかってるのにできてないからニーズがある** んですよね。

# 「勇者」がいないと物語は始まらない
RPAツールを広める、みたいな新しい活動をやり始めるには、
まずはこのような「草の根」的に、「身銭」を切る気持ちでスタートすることは何となくわかりました。

でも各会社さんによって状況が異なるので、
そう言った想いを持った人（＝勇者）が初めからいるか？いないか？で変わりそうですよね。

ここで「01」の最後に出した「RPA展開の様々なかたち」を思い出してみます。
あの`トップダウン`とか`ボトムアップ`とか言ってたやつです。

1. 現場業務担当者が自発的に使い始めるパターン
1. 情シスとかの管理部門がコスト削減等の施策案として採用するパターン
1. 会社のリーダーシップが経営目標・施策案の一つとして採用するパターン

![rpameth0103.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3329659/c8b00fcd-c969-3962-c448-bd34b8c5c390.jpeg)
こうして見ると、1.の場合は現場担当者が、日々の煩雑業務への **「怒り」** が原動力となるパターンです。これはまさにきちんと動機づけられた自発的な「勇者」になりうると思います。

一方2.と3.はどうでしょうか？
王様レベル、もしくは間接部隊の人間が **「命令」** ベースで物事を進めようとしているのですが、ここに「勇者」はいる可能性はかなり低いですよね。むしろこれから「勇者」が現れるのを待つか、探し出さないと進みません。

つまり、
a. 初めから自発的な「勇者」がいる場合
b. 初めから自発的な「勇者」がいない場合

の2パターンでどう進めればいいか全然変わりそうです。

# あらためてここでいう「勇者」とは？
話を進める前に、今一度この勇者のペルソナを考えてみます。
ここでいう「勇者」とは、
- 業務現場でのいち担当者であること
- 日々の煩雑な業務に不満を抱き効率化したいと考えていること
- 通常の業務時間外に学習とかするのはあまり抵抗がないこと
- 組織のメンバーであり、意思決定権を持つようなレイヤーではないこと
- バリバリのエンジニアではないこと
- でも新しいツールとかガジェットは割と好きな方であること

といったところでしょうか？
![PXL_20231003_001440640.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3329659/1e0ff807-0b93-602c-08de-f1034780ef12.jpeg)
エンジニアスキルをデフォで持ってたり（いきなりレベル50とか）、
組織特殊権限を持ってたり（いきなりイオナズン[^2]使えるとか）、
みたいな状態だと物事は進め易いですが、ここでは一旦なしとします。
[^2]:「イオナズンとは」 https://game8.jp/dragon_quest/dictionaries/752093

あくまでも **「想いは持っているが、レベル1の、ぬののふく[^3]を来た勇者の卵」** って感じですね。
[^3]:「ぬののふくとは」 https://dic.pixiv.net/a/%E3%81%AC%E3%81%AE%E3%81%AE%E3%81%B5%E3%81%8F

# 次回へ続きます
と言うところで、お時間になってしまいました。
ゲームだったら最初から「勇者」がいてスムーズに伝説が始まるのですが、
現実世界ではまずは「勇者」を探すところからスタートしないと伝説が始まらないことがほとんどです。
なので次回はその「勇者探し」についてダラダラ書いてみたいと思います。

https://qiita.com/husui/items/3b011c4167045472cecc

:::note info
まだ視野が狭くレベルが低い私見なので、ぜひ皆様からのアドバイスコメントよろしくお願いいたします。
ディスられると凹むのでお手柔らかにお願いします…
:::
jestでasync関数がExceptionをthrowするかテストする

以下のようなExceptionをthrowするasync関数があるとします。

```
// 1秒スリープ
const sleep1sec = async () => {
    await new Promise<void>((resolve) => {
        setTimeout(()=>{
            resolve();
        },1000);
    });
}
const someAsyncFunction1 = async () => {
    await sleep1sec();
    throw new Error();
}
const someAsyncFunction2= async () => {
    await sleep1sec();
    throw new Error('hoge');
}
const someAsyncFunction3= async () => {
    await sleep1sec();
    throw new Error('fuga');
}
```

それぞれテストコードは以下のようになります。ポイントは
* `expect()`内でテスト対象の関数を実行すること
* Promiseを解決するための`rejects`を追加すること
* toThrowでthrowされるExceptionのassertionを行うことです。

```
    describe('TestExeption',()=>{
        it('case1', async () => {
            await expect(someAsyncFunction1()).rejects.toThrow(Error);
        });
        it('case2', async () => {
            await expect(someAsyncFunction2()).rejects.toThrow('hoge');
        });
        it('case3', async () => {
            await expect(someAsyncFunction3()).rejects.toThrow(new Error('fuga'));
        });
    })
```


参考
https://dev.classmethod.jp/articles/testing-exception-handling-with-jest/
Oracle Analytics Cloud：データに含まれるURLを開く

# はじめに
データに含まれるURLをワークブックから開いてみたいと思います。
別の記事のために作成したデータセットを使います。
- [Oracle Analytics Cloud：自分の書いたQiita記事の一覧をREST APIで取得する](https://qiita.com/tyo38/items/f9e1356044b633db4755)

データとしてのURLを含む表を作成し、「データ・アクション」機能を使ってURLを別タブで開くよう設定します。

# Oracle Analytics Cloud（OAC）でワークブックに表を作成
REST APIでQiitaの自分の記事を検索するように設定したデータセットを使います。
「TITLE」「CREATED_AT」「URL」列を使ってワークブックに表を作成しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342206/88e8e593-0ed0-cc23-1394-1ec3f17e121e.png)
「URL」を別タブで開くように設定していきます。

# データ・アクションを設定
ワークブックのメニューを開き、「データ・アクション」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342206/26f4a5e7-fab9-800c-7538-f40044c3e3bf.png)
「＋」をクリックして、新規のデータ・アクションを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342206/ce88eb5b-f4c9-3c4f-f880-28ca196793b7.png)
「名前」を「新しいタブで開く」とし、「タイプ」を「URLのナビゲーション」にします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342206/c26d7e30-e428-6df7-6793-4b5102217928.png)
URLデータ要素として
```
${valuesForColumn:URL}
```
と入力します。
「${」と入力すると、リストが表示されるので「valuesForColumn:"column"」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342206/6e44d937-68fc-0854-bfc3-cf1772af75be.png)
次に「${valuesForColumn:_列_}」の「_列_」をクリックして「URL」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342206/1679b546-25ef-c2ba-bff8-998977970246.png)
「複数の選択をサポート」は「オフ」にして、「OK」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342206/6c1668b7-7d8b-da8f-e126-112f38c9ddfc.png)

# 右クリックして開いてみる
任意の列を右クリックすると、作成した「新しいタブで開く」データ・アクションが表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342206/0076fc4b-220c-69d3-8631-682e02bb1835.png)
クリックすると、実際に新しいタブでQiita記事が表示されました。

:::note
今回作成したデータ・アクションでは「アンカー先」を指定していないため、どのデータ要素（TITLE、CREATED_AT、URL）を右クリックしても、メニューに作成したデータ・アクションが表示されます。
「URL」を右クリックしたときだけ表示するようにするためには、アンカー先として「URL」を指定します。
:::
litellmを利用してAzure OpenAIとAmazon BedrockのチャットAPIを共通的に呼び出す

# 背景
- 社内で AI チャットサービスを展開する際、GPT-4 と GPT-3.5 などでモデル切り替えを可能にすることが多い
- モデルの切り替えを、Azure OpenAI と Amazon Bedrock などベンダーをまたぐ場合に API 呼び出し分ける必要があり手間になる
- litellm というライブラリがその問題を解消できそうなので試してみる
    - https://github.com/BerriAI/litellm
    - Open Interpreter でも採用されている
        - https://github.com/KillianLucas/open-interpreter/#change-your-language-model

# ライブラリインストール
以下ライブラリをインストール。pip や pipenv などで
```
litellm
jinja2
boto3
```
※ litellm のバージョンは 0.1.813 より新しいものを使う。Bedrock が使えないバグが修正されている

# 認証
今回は pipenv を利用するので `.env` ファイルを準備。
必要な認証情報を選択
```
AZURE_API_KEY=<Azure API キー>
AZURE_API_BASE=<APIエンドポイント>
AZURE_API_VERSION=2023-05-15

AWS_REGION_NAME=<リージョン>
AWS_ACCESS_KEY_ID=<アクセスキーID>
AWS_SECRET_ACCESS_KEY=<シークレットアクセスキー>
AWS_SESSION_TOKEN=<セッショントークン>
```

# スクリプト
以下サンプル。呼び出し処理やレスポンスが共通化されている
```
from litellm import completion

# azure call
response = completion(
    "azure/デプロイしたgpt4系のモデル", messages=[{"content": "日本の初代総理大臣は誰ですか。", "role": "user"}]
)
print(response["choices"][0]["message"]["content"])

# bedrock call
response2 = completion(
    model="bedrock/anthropic.claude-v2",
    messages=[{"content": "日本の初代総理大臣は誰ですか。", "role": "user"}],
)
print(response2["choices"][0]["message"]["content"])
```

# 実行結果
```
日本の初代総理大臣は伊藤博文（いとう ひろぶみ）です。彼は1885年に日本の初代内閣制度が開始されると、そのトップとして初代内閣総理大臣に就任しました。
```
```
日本の初代総理大臣は伊藤博文です。

1885年に内閣制度が導入され、翌1886年に第一回内閣が成立した際に、伊藤博文が初代の内閣総理大臣に就任しました。以後、内閣総理大臣は日本の政府の長としての役割を果たすことになります。
```
Pathfinderを卒業して得た物は？

サワディーカップ、ケニーです。
この度、Pathfinder3期を無事に卒業したので、本プログラムについて学んだ事を紹介できればと思います。

【簡単な自己紹介】
・海外生まれ育ちの帰国子女。タイが1番長く16年住んでました🇹🇭
※文書に怪しい所はありますがご了承下さい
・経歴:
IT営業、マーケティング、Salesforceマーケットに特化した採用リクルーターなど
・Salesforceはユーザー歴4年半
・Salesforce認定アドミニストレーター　
・Trailhead Double Ranger 取得
(年内にTriple Rangerを目指してます！)
・その他:Japan Dreamin'2022に登壇やSalesforce Saturday@銀座を主催などの活動

【ここで1番伝えたい事】
Pathfinderは本当にpath finderだった！
本当にやりたい事、挑戦してみたい事に気付くことが出来ました
今後のキャリアに悩んでる方や、少しでもSalesforceに興味がある方には特にお勧めします

【そもそもPathfinderとは？】
Salesforce社とDeloitte社が共同でスタートしたSalesforce人材育成プログラムです。
期間は約6ヶ月、毎週の課題や認定アドミンの合格がマストですが、1からSalesforceのソリューションやITのシステム導入の流れについて学び、転職活動まで全て無料で分厚くサポート頂けます。

※Pathfinferの詳細は下記リンクにて:
https://www.salesforce.com/jp/company/careers/pathfinders/

※https://www.salesforce.com/jp/blog/jp-pathfinder-program-interview/

【内容】
大きく3つのフェーズに別れてます。
参加者が多い為グループ分されますが、全てのグループに講師が丁寧にサポートして頂きます。

◆フェーズ①: 
・Salesforce社からSalesforceとは？や他のプロダクトについて説明
・講師は週毎に変わりますが、受講後に資料やアーカイブ動画を見直す事ができます
・Trailheadの課題が多く、1週間毎にトレイルをクリアする必要があります
・月曜、火曜はSalesforce社の講師、水曜はボランティアで本プログラムに参加頂いたパートナー会社の方がファシリテートして頂き、グループ内で課題共有や、分からない所を講師が教えて頂いたりしました
・フェーズ②に進むにあたり、Salesforce認定アドミニストレーターの合格がマストです。
僕は下記のように勉強しました！

○本資格を受けられてた方のブログから勉強
https://qiita.com/Takaa/items/485dc2dd1e61f31f2ff9

○Salesforce Certification Day
https://www.salesforce.com/jp/campaign/trailhead-academy/certification-days/

○過去問

◆フェーズ②:
・Deloitte社から一般的なITやシステム導入の流れなど説明
・フェーズ①同様、週毎に講師が変わりますが、上流から下流までの開発フェーズを一つ一つ教えて頂きます
・最後にDeloitte社の講師向けに要件定義から開発など自分で作成したものをプレゼンをして頂きます
※Pathfinder2期生は卒業するにあたり、プレゼンがマストだったそうですが、3期生は全てのクラスを受講し、プレゼンは必須ではありませんでした

◆フェーズ③:
・転職エージェント社から転職活動支援をして頂きます
・職務経歴書や履歴書を一緒にブラッシュアップ、面接の対策など幅広くサポートして頂きます
・フェーズ③の最後に転職フェア(ミートアップ)があり、約40社程の会社とカジュアルに情報交換が出来る貴重な場でした
(主にSalesforce導入パートナーとApp Exchangeパートナーでした)
※転職フェアの1週間前にPathfinderの賛同パートナーからスカウトメールを頂きます

【結果】
無事にSalesforceの導入パートナーの数社から内定を頂き、10月からSalesforceコンサルタントとして稼働してます！
※Pathfinderのクラスメイトやコミュニティーの皆さん、ありがとうございました！

【感想】
結論、Pathfinderに参加出来て本当に良かったです。今後採用コンサルでキャリアを積んで行くのかモヤモヤしてた所、背中を押してくれました。
また、3期生の同期との繋がりがとても刺激になりました。
将来は何かしらの形でPathfinderやSalesforceコミュニティーに恩返し出来ればと思います！

【ご案内】
Pathfinderの4期生の募集が始まりました！
リンク:
https://www.salesforce.com/jp/blog/jp-pathfinder_season4/

※抽選なので応募しても参加出来る確約は出来ないそうです
VPC内のルーティングに関するシンプルな勘違い

## 勘違いしていたこと

AWSをふわりとした理解だけで触っていた頃、VPC内のサブネットごとに独立したルーターが存在し、それぞれのルーターにルーティングテーブルが紐づいていると思っていたことがありました。

サブネットAとサブネットBがある場合、それぞれにルーターA、ルーターBが存在し、各ルーターに対してルーティングテーブルが関連付けられている、という認識です。

あるプライベートサブネットに対してNATゲートウェイを設定したくなったとき、ネクストホップにいないノードをターゲットに指定できるのは何故かと疑問に思ったことが始まりで勘違いが解けたため、ここにまとめようと思います。

## 実際の仕組み

実際は、サブネットごとに独立した物理的なゲートウェイが存在して通信を制御しているわけではありませんでした。

VPCにはユーザーが直接触れないような仮想的なルーターが一つ存在し、この仮想ルーターがサブネットやゲートウェイに対して紐づけられたルーティングテーブルをもとに、VPC内の通信を制御しています。

この仮想ルーターは、VPC内のすべてのサブネットやゲートウェイなどと「直接」接続されていると考えることができ、VPC内の通信はこの仮想的なルーターを中心に行われ、物理的な接続やゲートウェイの存在を気にする必要はありません。

仮想ルータはターゲットとなり得る各AWSサービスとの接続や通信方法を知っており、IPがわからずとも次のようなものをターゲットとして指定できるのでした。

- インターネットゲートウェイ
- NATゲートウェイ
- トランジットゲートウェイ
- VPCピアリング接続
- VPCエンドポイント
- VPN接続
- ネットワークインターフェース

インターネットやVPC外の特定のネットワークにアクセスする際に経由させるゲートウェイや接続だけでなく、VPC内のサブネット間通信で経由させたいノードに関しても指定できるようになっているんですね。

そしてVPC内の仮想ルーターは、トラフィックが発生した際はそれがどのサブネットやゲートウェイから来ているのかを判断し、そのサブネットやゲートウェイに関連づけられているルーティングテーブルに基づいてトラフィックをルーティングすることになります。

## まとめ

一般的なネットワークの知識とAWSの仮想的なネットワーク環境を混同していたために、VPC内の通信制御の仕組みや「サブネットにルーティングテーブルを紐付ける」ことが実際にどのような形で行われるかが良く分かっていませんでした。

物理的なネットワーク環境では、サブネットやVLANごとに独立したルーターやスイッチが存在することが多いですが、AWS VPCは完全に仮想的な環境なので、そのような制約や構造は存在しません。

ルーティングの仕組みを理解するにあたっては、この辺りのAWSのドキュメントやスライドを参考にさせていただきました。

[ルートテーブルを設定する](https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/VPC_Route_Tables.html)

[パケットの気持ちになって辿る Amazon VPC のルーティング](https://pages.awscloud.com/rs/112-TZM-766/images/AWS-08_AWS_Summit_Online_2020_NET01.pdf)
AZ-104試験対策のまとめ「Storage Account編②」

## はじめに
Microsoft Azure Administrator(AZ-104)合格に向けた勉強でまとめた内容を本記事では投稿しています。
試験範囲の内容を私が勉強していく中で、
・忘れてしまっていた内容
・他の知識と絡めて理解した方が良い内容
・Microsoft Learnの読解に苦戦した内容
などをできるだけ分かりやすく簡潔にまとめることを意識しています。
Azureの勉強を一から始め、AZ-104取得を目指している方の参考になれば幸いです。
※本記事の内容が必ず試験に出るわけではないこと、ご注意ください

## 試験対策のまとめ
### **ブロックBLOBのオブジェクトレプリケーション**
送信元と宛先のStorage Accout間でコンテナ内のブロックBLOBを非同期にコピー可能  

* サポートされるシナリオ
    - 読み取り要求待機時間の最小化：クライアントが物理的に近いリージョンのデータを使用可能
    - コンピューティングワークロードの効率向上：コンピューティングワークロードが同じブロックBLOBセットを複数のリージョンで処理可能
    - データ分散の最適化：データを1つの場所で処理/分析してその結果のみを別のリージョンに複製可能
    - コストの最適化：データの複製後、ライフサイクル管理ポリシーでデータをアーカイブ層に移動しコストを削減可能  

#### オブジェクトレプリケーションの前提条件と注意事項
使用には下記のAzure Storage機能が有効になっている必要あり
| Storage Account | 送信元Account | 宛先Account |
| --- | :---: | :---: |
| 変更フィード | 有効 | - |
| BLOBバージョン管理 | 有効 | 有効 |
* 変更フィードとBLOBバージョン管理を有効にすると、追加のコストが発生する場合がある
* 下記のStorage Accountでサポート
    - Standard 汎用 v2
    - Premium ブロック BLOB
* 下記のいずれかを使って暗号化されているアカウントでサポート
    - Microsoftマネージドキー
    - カスタマーマネージドキー

<br>

* 参考
    - https://learn.microsoft.com/ja-jp/azure/storage/blobs/object-replication-overview


## 次の試験対策のまとめ
* **AZ-104試験対策のまとめ「Storage Account編③」**

https://qiita.com/fsd-jume/items/740a79bbf0df404c7de0

## 学習内容をまとめたページの一覧

https://qiita.com/fsd-jume/items/6eda24728c9c03c36bc3
サーミスタで気温を計ってみた

どこかで買ったジャンク袋に一個だけ入っていたサーミスタで気温を計ってみました。

![写真（2023-10-03 7.29）.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/4f9b5b31-2b88-3ba7-3a56-90e22eaaf6c0.jpeg)

![サーミスタ2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/82d3bd5b-5bf3-daca-e6ac-100d7a340c14.png)

PIC12F1822でI2CのSlaveを作りADCした値をI2Cで拾えるようにしました。値は10から3300の範囲でミリボルトになりボリュームを付けてテスターで調べてほぼほぼ正確です。

mruby on YABMな蟹さんで拾った値をそのままTheingSpeakに投げます。

```ruby
#
# mruby script
#
# thingspeak channel update by HomeSpotCube
#

APIKEY = "naisyo"

# GPIO I2C Pin (SW12)

SCL = 2
SDA = 11

STATUS_LED1 = (1 << 0)
STATUS_LED2 = (1 << 6)
STATUS_LED3 = (1 << 17)
TOP_LED1 = (1 << 16)
TOP_LED2 = (1 << 4)
TOP_LED3 = (1 << 1)
TOP_BUTTON = (1 << 3)
ALLLEDS = (STATUS_LED1 | STATUS_LED2 | STATUS_LED3 |
  TOP_LED1 | TOP_LED2 | TOP_LED3)

def gpioinit(yabm) 
  yabm.gpiosetsel(0x003c300c, 0x003c300c, 0x00001800, 0x00001800)

  reg = yabm.gpiogetctl()
  reg &= ~ALLLEDS
  reg &= ~TOP_BUTTON
  yabm.gpiosetctl(reg)

  reg = yabm.gpiogetdir()
  reg |= ALLLEDS
  reg &= ~TOP_BUTTON
  yabm.gpiosetdir(reg)

  reg = yabm.gpiogetdat()
  reg |= ALLLEDS
  yabm.gpiosetdat(reg)
end

def ledon yabm
  reg = yabm.gpiogetdat()
  yabm.gpiosetdat(reg & ~TOP_LED1)
end

def ledoff yabm
  reg = yabm.gpiogetdat()
  yabm.gpiosetdat(reg | TOP_LED1)
end

def chkcrc dat, n
  crc8 = 0xff
  for i in 0..(n - 1) do
    crc8 = crc8 ^ dat[i]
    8.times {
      if crc8 & 0x80 == 0x80 then
        crc8 = crc8 << 1
        crc8 = crc8 ^ 0x31
      else
        crc8 = crc8 << 1
      end
    }
  end
  crc8 & 0xff
end


begin

yabm = YABM.new

yabm.netstartdhcp

gpioinit(yabm)

# sync date by ntp use https X.509
ntpaddr = yabm.lookup("ntp.nict.jp")
yabm.sntp(ntpaddr)

yabm.i2cinit(SCL, SDA, 1)

count = 0
interval = 30

yabm.watchdogstart(256)

arr = Array.new(3)

loop do
  ledon yabm

  yabm.i2cwrite(4, 0, 0)
  for addr in 0..2 do
    arr[addr] = yabm.i2cread(4, addr)
  end
  yabm.print arr[0].to_s(16).rjust(2, '0') + ","
  yabm.print arr[1].to_s(16).rjust(2, '0') + ","
  yabm.print arr[2].to_s(16).rjust(2, '0') + " "
  val = arr[0] * 0x100 + arr[1]
  crc = chkcrc(arr, 2)
  yabm.print val.to_s + " " + crc.to_s(16).rjust(2, '0') + "\r\n"

  res = SimpleHttp.new("https", "api.thingspeak.com", 443).request("GET", "/update?api_key=" + APIKEY + "&field1=" + val.to_s, {'User-Agent' => "test-agent"})
  ledoff yabm
  yabm.print "." + "\r\n"
  yabm.msleep interval * 1000
  yabm.watchdogreset
end

rescue => e
  yabm.print e.to_s
end
```

結果はこんな感じです。

![サーミスタグラフ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/11669348-5d09-c064-6d77-c6ea0dda46c6.png)

サーミスタは温度が下がると抵抗値が大きくなり、その結果ADCに入る電流が増えます。この時間帯の気温は25度から20度くらいになっていました。

25度で3.3Vのだいたい半分くらいになっているので、25度時に10KΩのサーミスタと思われます。

温度センサーよりコストが抑えられるので、卓上時計などに付いている温度計はサーミスタが使われていることが多いです。

生のデータを見ると結構ばらつきがあるので、いろいろ工夫が必要なようです。

温度に変換する場合logの計算が必要になるのですが、mruby on YABMはfloatをサポートしていないので、計算するのが難しいです。

またジャンクの部品では定数が分からないので、計算が困難です。

PIC12の開発がWindowsの重いIDEでしかできないのも問題です。

素直にI2Cの温度センサーを使うのが良さそうです。

と思ったのですが、PICで計算して温度を返すようにするのが良さそうです。
多くの企業が採用しているパスキーとは

# パスキー対応させてきてるサービスが増えてきている

2023年9月以降、パスキーに対応したというニュースが多く見受けられます。

https://id.smt.docomo.ne.jp/src/utility/notice_20230313.html

https://www.nintendo.co.jp/support/nintendo_account/passkey/index.html

https://blog.1password.com/save-use-passkeys-web-ios/

https://github.blog/2023-09-21-passkeys-are-generally-available/

などなど…

## パスキーとは

現在あるサービス・アプリなどはID(Email)とパスワードを使用してアカウント認証を行うことがデフォルトとなっています。
ですが、パスワード管理はユーザーの責任に任されていているためパスワードを忘れないように1PasswordやLastpass、将又Excelなどでパスワードを管理して忘れないようにしているかと思います。
また、パスワードが漏れてしまっては直ぐに不正利用されてしまう危険も潜んでいます。

不正利用を防ぐために2段階認証を採用するサービスが増えてきました
ですが、セキュリティ強化の1つにはなっているが認証のステップが増えているためユーザーとしては面倒極まりないです。

その中2023年9月以降に大手のAmazonにて2段階認証を突破されたというニュースは多くのエンジニアの記憶残ったはずです。

https://www.itmedia.co.jp/news/articles/2309/14/news152.html

そこで最近導入が進められているのがパスキーになります。「簡単・便利・安全」な認証の仕組みとし注目を集めています。(牛丼屋さんみたい)

パスキーは`FIDOアライアンス`というパスワードレス認証基準を普及させる団体が策定しているものになります。
パスワードを使用せず、`指紋認証`や`顔認証`という生体認証を利用してアカウント認証を行うことが出来ます。
正式名称は`マルチデバイス対応FIDO認証資格情報`で名称通り複数端末での利用も可能になっています。
Apple・Google・Microsoftなどが導入を進めています。

https://fidoalliance.org/white-paper-multi-device-fido-credentials-jp/?lang=ja

## パスキーの仕組み

秘密鍵と公開鍵を使用してアカウント認証を行う仕組みになっています。

この説明では従来のFIDO認証と変わらないのでは、と思うかもしれません。秘密鍵と公開鍵を使用してアカウント認証を行いますが、FIDO認証の欠点がありまして、「ユーザーの持っている端末を変更・紛失」した場合です。
FIDO認証は端末自体に秘密鍵を持たせているため、「ユーザーの持っている端末を変更・紛失」した場合には登録・設定を再度行う手間がかかってしまいます。

そこでパスキーは秘密鍵と公開鍵の他に同期鍵を用意してクラウド上で管理する仕組みを取り入れました。これによりユーザーが持っている端末が変わった際にクラウド上から同期鍵を呼び出すことで登録・設定を再度行う必要がなくなります。

![機能の流れ](https://zerokara.dds.co.jp/wp-content/uploads/fidoaliance-passkeys2.png)
> 参考 https://zerokara.dds.co.jp/fido/passkeys

## パスキーの今後の課題

課題として3つが挙げられます

1. サイト・アプリなどでパスキーに対応しているサイトが少ない・対応していても完全ではない
2. 端末のバージョンをアップデートしていたい・アップデート自体ができない環境ではパスキーを利用できない
3. 機種変更、それもiPhoneからAndroid・AndroidからiPhoneのようにマルチデバイス対応でもプラットフォーマーを超えるパスキー共有は不可能なため、再度パスキーの登録が必要

1つ目は対応してくれるサービス・アプリが増えていくことで解消されていきます。ですが、冒頭でもお話した様に最近は多くのサービスでパスキーに対応する流れが来ています。

2・3つ目は第三者によるパスキーを管理できるプラットフォームが登場を待つしかないです。
現状使えそうなのは`Corbado`かと自分では思っています。(現在どこまで使用できるか研究中です)

https://www.corbado.com/

自分が得意とする`Next.js`と`Corbado`を使用した簡単なパスキー実装をまとめているので是非、参考にしてもらいパスキーについて知っていただければ幸いです。

https://qiita.com/roll1226/items/fa5b06495a0c0770949f

## 参考

https://www.itmedia.co.jp/news/articles/2301/23/news086.html

https://zerokara.dds.co.jp/fido/passkeys/

https://it-trend.jp/encryption/article/64-0089

https://xtech.nikkei.com/atcl/nxt/mag/nnw/18/041800012/011800197/
AIHWKITをMacで試してみる

IBMのAIHWKIT (https://github.com/IBM/aihwkit) を試してみる。これはアナログAIハードウェアのシュミレーターです。

## 環境

- Mac Studio (M1 MAX, Apple Silicon)
- OSX Ventura 13.6
- Python 3.9.6
- PyTorch

## インストール

Python環境がすでにセットアップ済みとして

### PyTorchのインストール

PyTorchをインストール。最新版はApple SiliconｍのGPUに対応している。

```
time pip3 install torch torchvision torchaudio
```

### AIHWKITのインストール

cmake, ninjya, OpenBLASが必要なようなのでインストールしておく。
OpenBLASのインストールパスを環境変数にセットしておく。

```
brew install cmake ninja openblas
export OpenBLAS_HOME=/opt/homebrew/opt/openblas/
```

Python関係では pybind11、matplotlib をインストールしておく。

```
pip install pybind11 matplotlib
```

ひとまずこれで、aihwkit がインストール可能なはず。

```
pip install aihwkit
```

## 実行

ひとまずサンプルがあるのでそれを実行してみる。

```
git clone https://github.com/IBM/aihwkit.git
cd aihwkit/example
```

たくさんあるが、04がLeNet5でグラフまで生成してくれるので実行、CPUだと約3時間ほどかかる。

```
time python 04_lenet5_training.py
```
![test_losses.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/157475/53e88424-4321-4c37-0423-15e4d6aa5229.png)

![test_error.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/157475/5f18f3ec-444e-b3a9-1b9f-bc8be5c4e60d.png)

## AppleSillicon

AIHWKITはcudaをサポートするが、Apple Silisonの mps(Metal Performance Shaders)はサポートしません。

## リファレンス


- https://github.com/IBM/aihwkit
- https://aihwkit.readthedocs.io/en/latest/
【JAVA入門】サーブレット、JSPについて簡潔説明

## サーブレット
　Javaプログラムを使用してWebアプリケーションを開発するための技術です。サーブレットは、クライアントからのHTTPリクエストを受け取り、処理し、HTTPレスポンスをブラウザに返します。

##### サーブレットコンテナ
　サーブレットは、サーバー上で実行される特別な環境で動作します。この環境は「サーブレットコンテナ」と呼ばれ、HTTPリクエストの受信からサーブレットの呼び出し、HTTPレスポンスの送信までを管理します。代表的なサーブレットコンテナには、Apache Tomcat、Jetty、IBM WebSphereなどがあります。

## JSP
　サーブレットと同じ、サーバサイドプログラムの技術です。サーブレットクラスの代わりにJSPファイルを使用します。
　JSPはHTML内にJavaコードを埋め込むことができ、サーバーサイドで実行されます。

##### JSP実行の仕組み
　JSが初めてアクセスされた時、JSPサーブレットが自動で生成され、自動でコンパイルされる。クラスファイルを実行するとオブジェクトが生成されてブラウザに出力される。２回目以降のアクセス時は、メモリ上に残っているオブジェクトが直接呼び出される。
Windows 11 のデバイスマネージャーを開く3つの方法

デバイスマネージャーは、パソコンに接続されている機器の表示、ドライバーの追加や削除、機器の設定確認などに使用されます。この記事では Windows 11 22H2 を例に、デバイスマネージャーを開く方法を3つ紹介します。

## 方法一覧

||方法|クリック操作|右クリック操作|キーボード操作|操作手数|備考|
|---|---|---|---|---|---|---|
|**1**|[**設定画面から起動**](https://qiita.com/mmake/items/9c92412907f1324d3825#%E6%96%B9%E6%B3%951%E8%A8%AD%E5%AE%9A%E7%94%BB%E9%9D%A2%E3%81%8B%E3%82%89%E8%B5%B7%E5%8B%95)|必要|-|-|7|**容易**|
|**2**|[**スタートボタンの右クリックから起動**](https://qiita.com/mmake/items/9c92412907f1324d3825#%E6%96%B9%E6%B3%952%E3%82%B9%E3%82%BF%E3%83%BC%E3%83%88%E3%83%9C%E3%82%BF%E3%83%B3%E3%81%AE%E5%8F%B3%E3%82%AF%E3%83%AA%E3%83%83%E3%82%AF%E3%81%8B%E3%82%89%E8%B5%B7%E5%8B%95)|必要|必要|-|2|**簡単**|
|3|[検索して実行](https://qiita.com/mmake/items/9c92412907f1324d3825#%E6%96%B9%E6%B3%953%E6%A4%9C%E7%B4%A2%E3%81%97%E3%81%A6%E5%AE%9F%E8%A1%8C)|必要|-|必要|9|-|

## 方法1：設定画面から起動
### スタートメニューの表示
スタートボタンをクリックし、スタートメニューが表示されたら「**設定**」をクリックします。

![103.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3160433/11afbf74-98ec-7493-6411-e84e8125d719.png)

### 設定の表示
設定画面が表示されたら、左側の「**システム**」をクリックします。

![443.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3160433/9a5aa9ec-6b96-ed14-52b8-69e580927e06.png)

### 設定の表示
右側を下にスクロールし、「**バージョン情報**」をクリックします。

![241.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3160433/1bdcecb8-c716-412e-4eda-77f8388d0035.png)

### バージョン情報の表示
バージョン情報画面が表示されたら、右側を下にスクロールし、「**デバイスマネージャー**」をクリックします。

![243.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3160433/08a7ff8a-1eca-2dda-c1ea-d03b2ac45e2a.png)

### デバイスマネージャーの表示
デバイスマネージャーが表示されます。

![457.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3160433/009c1686-cc50-5453-f80e-7ce94c6fc137.png)

## 方法2：スタートボタンの右クリックから起動
### スタートボタンを右クリック
スタートボタンを右クリックし、コンテキストメニューが表示されたら、「**デバイスマネージャー**」をクリックします。

![133.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3160433/0116a1dc-8d06-fb24-2638-37fde59e8f55.png)

### デバイスマネージャーの表示
デバイスマネージャーが表示されます。

![457.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3160433/009c1686-cc50-5453-f80e-7ce94c6fc137.png)

## 方法3：検索して実行
### 検索ボックスをクリック
タスクバーの**検索ボックス**をクリックします。

![31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3160433/00b2c7f8-2a24-41bb-ce9b-0da95ea2113d.png)

### 検索文字を入力
キーボードから「**devmgmt**」または「**デバイスマネージャー**」などのキーワードを入力します。

### 検索結果の表示
検索結果に「**デバイスマネージャー**」が表示されたら、クリックします。

![337.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3160433/da4cbb86-a31d-015b-f71a-bd2b83145b7d.png)

### デバイスマネージャーの表示
デバイスマネージャーが表示されます。

![457.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3160433/009c1686-cc50-5453-f80e-7ce94c6fc137.png)
2023/10/3主にITとかセキュリティの記事

どれだけ面倒でも「ソフトウェアのアップデート」を無視し続けてはいけない――その理由とは？(9/30)
https://news.yahoo.co.jp/articles/0232c35d842e1b697c5a24220858827cf4b912c1

トロイの木馬を配布する偽のパスワードマネージャに注意(10/1)
https://news.mynavi.jp/techplus/article/20231001-2781149/

iOS17ではなくiOS16ユーザーは要注意！ すぐにアップデートすべき理由(10/1)
https://news.yahoo.co.jp/articles/ef6d66d7ae8eea58d438b926c7fc95dc2249019b?source=rss

攻撃者がGitHubリポジトリをこっそりと改ざん、マルウェアに変更される(10/1)
https://news.mynavi.jp/techplus/article/20231001-2781612/

日本企業の72％が「生成AIの利用禁止」という衝撃　ChatGPTに「積極的な企業・否定的な企業」の決定差(10/1)
https://news.yahoo.co.jp/articles/865168ddd657a1db77dd959c17e368ea18cfe9ed

ChatGPTに｢積極的な企業･否定的な企業｣の決定差 日本企業の72％が生成AIの利用禁止という衝撃(10/1)
https://news.goo.ne.jp/article/toyokeizai/bizskills/toyokeizai-704507.html

世の中のエンジニアたちによる「おすすめのレジストラ」はどこなのか？(9/30)
https://gigazine.net/news/20230930-domain-registrar-recommend/

Google Bardの回答結果がGoogle検索に表示(10/1)
https://www.zaikei.co.jp/article/20231001/739935.html

1億総デジタル時代の
デジタルアイデンティティ活用とリスク管理　ラック(9/6)
https://cp.lac.co.jp/dl/document_digitalidentity

iPhone位置情報の設定方法！オススメの使い方・共有する方法は？(10/1)
https://www.ocn.ne.jp/quiz/list/it_0d8f80a9-b072-4766-8257-19b61f3c8eeb?utm_source=goo_top&utm_medium=Referral&utm_campaign=goo_top_quiz&answer=1

「災害復旧（DR）対策はお金が掛かり過ぎるから後回し」が結局“高くつく”理由(9/30)
https://news.yahoo.co.jp/articles/69e8164be269805c09e2882b7c3c860ee2689dca

人気ドラマも監修、企業システムの脆弱性見抜く　ITベンチャーのフラットセキュリティ（文京区）＜挑む＞(10/1)
https://www.tokyo-np.co.jp/article/280545

アイマイなもの、だからこその活用－AI 時代の学びについて考える
https://berd.benesse.jp/special/researchcolumn/01.php?=5887

「テレグラム」がテンセントと提携　業界関係者がセキュリティリスクを警告(10/1)
https://www.epochtimes.jp/2023/10/177139.html

米国務省、流出メールは非機密 - 約６万通、機密システム被害なし(9/29)
https://www.nara-np.co.jp/global/2023092901000179.html

人手排除でバグも根絶、Oracleエリソン会長が語る生成AIの使いどころ(10/2)
https://xtech.nikkei.com/atcl/nxt/column/18/00001/08457/

国内で急増するランサムウエア被害の実態、半数が復旧に1000万円超を投じる(10/2)
https://xtech.nikkei.com/atcl/nxt/column/18/02597/092700001/

かつてLANは1本の「線」だった(10/2)
https://xtech.nikkei.com/atcl/nxt/mag/nnw/18/091900173/091900001/

いつでもループを検知できる？(10/2)
https://xtech.nikkei.com/atcl/nxt/mag/nnw/18/031600159/091900007/
フォロー機能と同じテーブル構造で複数チェックボックスの管理方法を考えてみた

# 実現したいこと
同じテーブル同士で1つのに対して、複数の同じテーブルのレコードを紐づけてチェックボックスで登録できるようにする。
例えば、
- ユーザーの一括お気に入り機能
- 一括ブロック機能
- アイテムをひとまとめにするアイテム

などが挙げられます。

記事にした経緯として、
- 探しても実装事例が全く見つからなかった
- この発想に至るまでハマって時間を無駄にした

というものからです。

### 開発環境
- Ruby 3.0.2
- Rails 7.0.3.1


### オーソドックスな管理方法
よくある例として車とパーツの関係でテーブル設計をしてみました。
利用例としては、車に対して装着したいカスタムパーツにチェックを入れる想定です。

※ストロングパラメーターの設定は、実装例が多くあるため割愛しております。

### テーブル設計
cars
| カラム名 | 型 |
| ------ | ------ |
| id   | integer   |
| name   | string   |

car_parts
| カラム名 | 型 |
| ------ | ------ |
| car   | reference |
| part   | reference |

parts
| カラム名 | 型 |
| ------ | ------ |
| id   | integer   |
| name  | string  |

- carモデル
```ruby
class Car < ApplicationRecord
  has_many :car_parts, dependent: :destroy
  has_many :parts, through: :car_parts

  accepts_nested_attributes_for :car_parts, allow_destroy: true
end

```

- 中間テーブルとなるcar_partモデル
```ruby
class CarPart < ApplicationRecord
  belongs_to :car
  belongs_to :part
end
```

- partモデル
```ruby
class Part < ApplicationRecord
  has_many :car_parts, dependent: :destroy
  has_many :cars, through: :car_parts

  accepts_nested_attributes_for :car_parts, allow_destroy: true
end
```

チェックボックスとして表示させるフォーム
```slim
= form_with model: @car, local: true do |f|
  = f.fields_for :car_parts do |l|
    = l.collection_check_boxes :part_ids, Part.all, :id, :style, checked: @car.part_ids ,include_hidden: false do |b|
      label { b.check_box + b.text }
  = f.submit
```

### 本題
同じテーブル間でチェックを入れて追加し合う場合
アイテムをひとまとめにする機能を例に挙げてみます。

### テーブル設計
items
| カラム名 | 型 |
| ------ | ------ |
| id   | integer   |
| name   | string  |

item_relations
| カラム名 | 型 |
| ------ | ------ |
| item   | reference |
| item_selection | reference |

item_selection（クラス継承）
理解しやすくするための便宜上、テーブル設計に挙げています。
| カラム名 | 型 |
| ------ | ------ |
| Itemテーブルと同じ | Itemテーブルと同じ  |

itemモデル
```ruby:item.rb
class Item < ApplicationRecord
  has_many :item_relations, dependent: :destroy
  has_many :item_selections, through: :item_relations

  accepts_nested_attributes_for :item_relations, allow_destroy: true
end
```

- 中間テーブルとなるitem_relationモデル
```ruby:item_relation.rb
class ItemRelation < ApplicationRecord
  belongs_to :item
  belongs_to :item_selection, class_name: 'Item'
end
```


[単一テーブル継承(STI)](https://qiita.com/OHKN/items/b7a9066267de55c07421)を使って
Itemクラスを継承したItemSelectionクラスを用意

```ruby:item_selection.rb
class ItemSelection < Item
  has_many :item_relations, dependent: :destroy
  has_many :items, through: :item_relations

  accepts_nested_attributes_for :item_relations, allow_destroy: true
end
```

チェックボックスとして表示させるフォーム
```slim
= form_with model: @item, local: true do |f|
  = f.fields_for :item_selections do |l|
    = l.collection_check_boxes :item_selection_ids, ItemSelection.all, :id, :style, checked: @item.item_selection_ids ,include_hidden: false do |b|
      label { b.check_box + b.text }
  = f.submit
```

コンパクトに実装ができました🎉

## 参考記事
非常にわかりやすい構成で執筆の際に参考にさせていただきましたmm

https://qiita.com/supercell1023koeda/items/4e49d85cc15ab3160be8

https://qiita.com/OHKN/items/b7a9066267de55c07421
<div> cannot appear as a child of <tbody>について

## `<div>` は `<tbody>` の子要素としては利用できない

HTMLでテーブルを作成する際には、しっかりとした構造が求められる。 `<table>`, `<thead>`, `<tbody>`, `<tr>`, `<td>` などの要素があるが、これらの要素の中に不適切な要素を入れると、ブラウザのレンダリングエラーや意図しない表示が生じることがある。

## エラーの原因

`<div>` を `<tbody>` の中に直接置くと、このエラーが発生する。`<tbody>` の直接の子要素として許可されているのは `<tr>` のみ。

```html
<!-- これは間違い -->
<table>
  <tbody>
    <div>
      <tr>
        <td>データ1</td>
      </tr>
    </div>
  </tbody>
</table>
```

## 正しい方法
テーブル内の要素をグループ化したい場合、`<div>` ではなく `<tr>` を利用する

```html
<!-- これが正しい -->
<table>
  <tbody>
    <tr>
      <td>データ1</td>
    </tr>
    <tr>
      <td>データ2</td>
    </tr>
  </tbody>
</table>
```

:::note
まとめ
HTMLのテーブル要素は、特定の構造を持っているので、`<div>` を `<tbody> `の中に入れることは避け、適切な要素を使用する。
:::
Pythonの並列処理で任意の順番＆形で結果を取得する

## はじめに
最近Pythonで大量の演算処理を行うプログラムを書いた際，あまりにも計算に時間がかかるので並列処理を勉強し始めました．
そこで，自分の思い通りに使えるようにするにはどうすれば良いか考えていた所，とある形に落ち着いたので共有したいと思いました．

並列処理を使えるモジュールは，multiprocessingやconcurrentなどがありますが，この場ではconcurrentを用います．

(勉強が不十分でもっと良い書き方があるかもしれないので，もし左様でありましたら，ご教授いただけると幸いです．)

## 定番　コード①
まずPythonで並列処理を行いたい場合，大体このような形になると思います．
(本当はfor文でリスト内包表記を使用するべきなんですが，目を瞑っていただけると助かります．)
```python
import time # 処理時間を測定するため
from concurrent import futures

ln = 40 # 適当な数字
data = list(range(ln))

def calculation(index): # 簡単な演算処理，普通に回すと大体17秒~18秒かかった．
    num = 0
    for i in range(10000000): num += 1
    return num, index

def main(): # メイン
    t0 = time.time()
    with futures.ProcessPoolExecutor() as executor:
        map_result = executor.map(calculation, data) # calculation()を40回分計算する
        result = list(map_result)
    t1 = time.time(); print(f'{t1-t0:.2f}秒\n')

if __name__ == '__main__':
    main()
```

これを実行すると計算の結果はこのようになります．
```
result = [(10000000, 0), (10000000, 1), ...省略... (10000000, 38), (10000000, 39)]
```

とてもシンプルで基本的にこれで十分だと思います．
しかし，個人的な意見として，今後 複雑な計算処理を行いたいとき，この出力結果の取得方法はとても分かりづらく，自由が効かないと感じました．

自分が求める要件はこんな感じです．
- 決まった順番，ランダムな順番ではなく，自分で定めた任意の順番で出力結果を得たい
- 自分の好きな形(numpyの行列など)で出力結果を格納出来るようにしたい
- 状況に応じて複数の値を入力，出力出来るようにしたい．
- 今後numbaを使う可能性を考えて，なるべく外部変数へのアクセスを避けたい．
- tqdmを用いてfor文の進捗を表示させるとき，自分の思う通りに簡単にカスタマイズ出来るようにしたい．

そこで色々いじってみた結果，最終的に以下のコードを簡単なテンプレートとして今後使いまわそうと考えました．

## 最終案　コード②
```python
import time # 処理時間を測定するため
import numpy as np # 行列の演算では不可欠．
from concurrent import futures

ln = 40 # 適当な数字
data = list(range(ln))

def calculation(index): # 簡単な演算処理，普通に回すと大体17秒~18秒かかった．
    num = 0
    for i in range(10000000): num += 1
    return num, index

def main(): # メイン
    t0 = time.time()
    log = np.zeros((ln,2)) # 出力結果格納用
    with futures.ProcessPoolExecutor() as executor:
        for i in range(ln): # 計算開始
            # 変数(プロセス?)の名前を変えながら，演算処理のプロセスを開始，順番はほぼ関係ない．
            exec(f'result{i} = executor.submit(calculation,{i})')
        for i in range(ln): # 結果を待つ，
            # rangeの中身などを変えることで任意の順番で結果を受け取る．
            exec(f'log[{i},:] = result{i}.result()') # 任意の形で結果を格納．
            # 今回は40x2の行列に格納．
    t1 = time.time();print(f'{t1-t0:.2f}秒\n')

if __name__ == '__main__':
    main()
```
これを実行すると，計算の結果はこのようになります．先程よりは見やすく，整理しやすい結果になったと思います．
```
log = [[1.0e+07 0.0e+00]
      [1.0e+07 1.0e+00]
      [1.0e+07 2.0e+00]
      ...省略...
      [1.0e+07 3.7e+01]
      [1.0e+07 3.8e+01]
      [1.0e+07 3.9e+01]]
```
このような感じで作成すれば，今後どのような計算プログラムを組みたくても上手く対応できそうに感じました．

## 実行速度に影響はあったか？
コード②では，プロセスの開始や結果の取得にfor文を用いましたが，ほとんどの場合実行速度に影響はないと見てよさそうです．このfor文は演算処理自体には影響を与えていないはずです．

コード①とコード②を何回か実行してみたところ，寧ろコード②の方が安定して速かった印象を受けました．以下に処理時間をまとめました．(大体の目安で，しっかりとデータを取った訳では無いです)
- 並列処理を使わない場合：およそ17~18秒．
- 並列処理を使う場合：
    - コード①：約3.4 ~ 4秒．バラツキが大きかった．(原因は分からないです)
    - コード②：約3.3 ~ 3.5秒，バラツキが小さかった．

## 追記
コード②ではグローバル宣言しなくても動作しましたが，
基本```exec```で変数を作成するときは，グローバル宣言をするか，第2引数に```globals()```を渡さなくてはいけないです．
例：
```python
exec('global a; a=1')
exec('a=1', globals())
```

## 実行環境
Windows 11，Ryzen 7 5800H，RAM16GB（DDR4）
πを求めるシミュレーション

一辺の長さが 1 の正方形内に原点を中心とする四分円を描き，ランダムに点を打って，四分円内に入った点の割合の4倍がπに近いというよくあるシミュレーション

```julia
n = 100000000
4sum(sum(rand(n, 2) .^ 2, dims=2) .< 1)/n
```
ネットワークセキュリティについて整理②

# 様々な脅威
#### ①ポートスキャン
システムに侵入する前の予備調査
【対策】
・ファイアーウォール
・IDS・IPS(監視システム)など

#### ②パスワードクラシック
パスワードの解読(オンライン攻撃、オフライン攻撃)、盗聴
【対策】
・パスワードポリシー(運用ルール)
・生体認証
・暗号化
・多要素認証(MFA)

#### ③バッファオーバーフロー、セキュリティホール
プログラムの不具合を突いた攻撃
【対策】
・バージョンアップ
・パッチ適用
・Windows Updateの実行

#### ④オンライン攻撃
ウェブサイトのアクセス時に情報を盗みだしたり、破壊する攻撃
・SQLインジェクション
・クロスサイトスクリプティング(XXS)
・クロスサイトリクエストフォージェリ(CSRF)
【対策】
・Webサイトチェックツールの導入
・ポリシー設定


#### ⑤盗聴
通信データをネットワーク上で盗み取る攻撃
【対策】
・暗号化(SSL, VPN)
・物理セキュリティ(セキュリティゲート)

#### ⑥キーロガー
キーボード操作を全て記録し、パスワードや個人情報、クレジットカード番号などの情報を盗みだすソフトを使った攻撃。
キーロガーには「ハードウェアタイプ」と「ソフトウェアタイプ」の二種類がある。
・「ハードウェアタイプ」は標的のパソコンに不正なUSBメモリなどが接続されることで感染する。
・「ソフトウェアタイプ」はメールのリンクをクリック、ないしWEBサイトにアクセスするだけで感染する。

【対策】
・スクリーンキーボードの使用
・ウイルス対策ソフトの導入

# 攻撃者の作業イメージの1例
Linuxコマンド

①自分のipアドレスを確認
$ hostname -i 
10.1.1.5/24

②nmapコマンドでネットワークアドレス上の全てのコンピュータへの疎通確認を自動化する
$ nmap -sn 10.1.1.0/24
nmapコマンドで表示された結果から、サーバのコンピュータを予測する。
例：同じような名前のコンピュータはクライアントPCが並んでいる可能性があるため、選択肢から省くなど。
ルータとサーバでは、サーバの方が機能が多いため、サーバが狙われやすい。
※nmapコマンドなどのネットワーク調査コマンドで指定する範囲を誤ると、攻撃を受けたとみなされる場合があるため、注意して使用する。

③nmapコマンドで特定のIPアドレスのコンピュータの詳細調査
$ nmap -A 10.1.1.2
どんなミドルウェアが動いているかなどの情報を取得することができる。
→古いバージョンのアプリケーションが動いていれば、その脆弱性を調べられる。
・「<アプリケーション名> <バージョン番号> vulnerabilities」でググる
・「CVE details」でググる
【Rails】Could not open library 'libvips.so.42'解消法

## 状況

ActiveStorageで画像処理をしたところ以下のようなエラーが発生しました。

```terminal
LoadError: Could not open library 'vips.so.42': vips.so.42: cannot open shared object file: No such file or directory.
Could not open library 'libvips.so.42': libvips.so.42: cannot open shared object file: No such file or directory
```

## 解決方法

`libvips42`をインストールしたところ解消しました。

```terminal
apt-get update -qq && apt-get install -y --no-install-recommends libvips42
```
【bat】fileをD&Dしたらfilepath取得する.batを作る


# 概要
WindowsでファイルをD&Dしたらファイルパス取得するバッチファイルを作る

[ファイルパスをクリップボードにコピーする方法](https://ygkb.jp/4890)
上記のような方法でも良いがダブルクォートが入ったり少し面倒な為、メモ

# 成果物

作成したファイルに
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67904/eb55c011-6a11-4578-05be-3b37ea47ea92.png)
pathを調べたいファイルをD&Dすると
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67904/da3a571a-b169-aaa6-8f2e-9ce771b6df2d.png)


```
クリップボードに下記のように保存される
C:\Users\hoge\Desktop\fuga\hoge.txt 
```
# 作成方法

下記内容のバッチファイルを作る

```batchfile
<nul set/p=%1|clip
```
Microsoft 365 のユーザーを強制サインアウトさせる方法

# 方法１　Microsoft 365 管理センターから対象ユーザーを開き、アカウントのサインアウト箇所から強制サインアウトさせられます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592268/cd0494fc-5503-43d8-2a29-81f925c43aca.png)

								
# 方法2　PowerShellで強制サインアウトする								
	PowerShell の Revoke-AzureADUserAllRefreshToken で強制サインアウト							
								
		1.AzureADモジュールのインストール						
			Install-Module -Name AzureAD					
								
		2.AzureADに接続						
			Connect-azureAD					
								
		3.ユーザーオブジェクトを調べる						
			Get-AzureADUser -ObjectID <ユーザーのUPN>
			例：
			$User = Get-AzureADUser -SearchString 'user@hogehoge.com'			
			$User 

		4.強制サインアウトする						
			Revoke-AzureADUserAllRefreshToken -ObjectId $User.ObjectID"	

# 方法3　Power Automateで強制サインアウトする
Power Automateの、AzureAD アクションを使って、Power Automate で処理。
※Azure ADを操作できる権限でフローを作る必要。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592268/aa897583-e724-245e-8249-8348316c1750.png)

UPNで設定も可能。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592268/03426566-4f10-1320-4201-11db650d5823.png)
ROS Noeticのインストール【Ubuntu 20.04】

# はじめに
　`ROS Noetic`のインストール方法について記します。前提条件として、ROS Noeticを使用するには、`Ubuntu 20.04`である必要があります。Ubuntuのバージョンに合ったROSをインストールしましょう。Ubuntuのバージョンは以下のコマンドで確認できます。

```
cat /etc/issue
```

　ROS1の最新バージョンはNoeticであるため、ROS1を使用したい方はUbuntu 20.04をインストールしてNoeticのインストールを推奨します。公式もNoeticを推奨しています。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3561867/39d6b81a-260a-69ea-9bf6-f9a0c527b620.png" width="300">

:::note warn
2025年5月にNoeticは公式のサポートが終了します。Noetic以降、ROS1のディストリビューションは登場していません。**ROS2**の使用も視野に入れましょう。
:::

# 環境
+ Ubuntu 20.04LTS

# インストール手順
　以下のコマンドを上から順にターミナルで実行してください。うまく行けば、10分もかからずにインストールが終わると思います。
### 1. sources.listの設定
```Bash
sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list'
```
### 2. 鍵の設定
```Bash
sudo apt-key adv --keyserver 'hkp://keyserver.ubuntu.com:80' --recv-key C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654
```
### 3. Ubuntuの更新
```Bash
sudo apt update
```
### 4. ROSのインストール
```Bash
sudo apt install ros-noetic-desktop-full
```
### 5. 環境変数の設定
```Bash
echo "source /opt/ros/noetic/setup.bash" >> ~/.bashrc
source ~/.bashrc
```
### 6. 依存パッケージのインストール
```Bash
sudo apt install python3-rosdep python3-rosinstall python3-rosinstall-generator python3-wstool build-essential
```
### 7. rosdepの初期化と更新
```Bash
sudo rosdep init
rosdep update
```
### 8. catkin buildを使用するためのツールのインストール
```Bash
sudo apt-get install python3-catkin-tools
```
### 9. ワークスペースの作成
```Bash
mkdir -p ~/catkin_ws/src
cd ~/catkin_ws/
catkin build
```
### 10. catkin_wsのオーバーレイ
```Bash
echo "source ~/catkin_ws/devel/setup.bash" >> ~/.bashrc
source ~/.bashrc
```
### 11. インストールできているか確認
```Bash
roscore
```
エラーなく表示されれば問題なし.

# 参考
https://wiki.ros.org/noetic/Installation/Ubuntu

https://wiki.ros.org/Distributions
ライブラリを使わずにOpenAI API を呼び出す

# 概要

一般的には、pythonで開発している人は、OpenAIのChatGPTをAPIで使いたいとき、```openai```ライブラリを使いますよね。

（どんな状況かはわかりませんが）ライブラリを使わずにOpenAIのAPIを呼び出して、ChatGPTを利用するためのコードを作成したので、その共有です。


# コード解説

早速コード解説です。

コードそのものは、『コードの中身』で書いているので、コードが気になる方はそちらを見てください。

## コードを作ろうと思った理由
OpenAIのChatGPTをライブラリ経由で使うときは実はAPIという仕組みを利用しています。細かいことを言うと、これはライブラリを使ってみなさんのパソコンの中でChatGPTが動いているわけではなく、OpenAI社のサーバに皆さんが入力したプロンプトがインターネット経由で飛ばされています（もちろん、OpenAI社側もセキュリティ対策を取っているので、あまり心配に思う必要は無いですが、自分が入力したデータやプロンプトがOpenAI社にインターネット経由で飛んでいるのです）。


これは、"API"という仕組みであり、一般的によく使われているモノです（OpenAI社独自のモノではない）。

したがって、ChatGPTをAPI経由で呼び出して使うためには、正直、```openai```ライブラリを使う必要は実はありません。便利だから使っているというだけです。

**だったら、ライブラリを使わずにChatGPTをAPI経由で使ってやろうではないか**！ということで今回はコードを作ってみました。



## コードの中身

```python
import json
import requests

API_KEY = 'sk-' # ご自分のAPIキーに書き換えてください
API_URL = 'https://api.openai.com/v1/chat/completions'

# プロンプト
PROMPT = '最初に学習するプログラミング言語のおすすめを理由付きで3つ教えて'
MESSAGE = [{'role':'user', 'content':PROMPT}]

# ヘッダの設定
headers = {'Content-Type': 'application/json'
          ,'Authorization': f'Bearer {API_KEY}'}



# POSTするデータ
data = {
    'model': 'gpt-3.5-turbo-16k'
    ,'messages': MESSAGE
}


# POSTメソッドでAPIをコール
response = requests.post(API_URL
                        ,data    = json.dumps(data)
                        ,headers = headers)


# ステータスコードチェック
if response.status_code == 200:
  result = response.json()
  result = result["choices"][0]["message"]["content"]
  print(result)
  #print(response.json())  # レスポンスがJSON形式の場合
else:
  print('Error: ' + str(response.status_code))
```

実行結果は↓。

![Untitled.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/687015/77ae873f-4e46-9705-3901-b67ca836550e.png)
flutter build iosでWarning: CocoaPods is installed but broken. Skipping pod install. You appear to have CocoaPods installed but it is not working

flutter build iosを実行したら
Warning: CocoaPods is installed but broken. Skipping pod install. You appear to have CocoaPods installed but it is not working
というエラーが発生しました。

# 解決策
rbenv versions
でバージョンを確認

*2.7.6
3.0.1
3.1.2

と過去にinstallしたrubyのバージョン一覧が出てきます。

sudo rbenv uninstall 3.0.1

sudo rbenv uninstall 3.1.2

と不要なrubyのバージョンを削除したことで解決しました。
inside flutterを理解するために読むべき良記事をまとめた。[ロードマップ]

## はじめに

flutterのレイアウトが描画される仕組みを理解するためには、以下の公式ドキュメントを読み込む必要があります。

https://docs.flutter.dev/resources/inside-flutter

ですがこれがまあとっつきにくいですよね。。
自分も何度挫折したことか。。

もちろん最終的には読むべきだとは思いますが、今の時代、優秀なエンジニアがinside flutterに対して、わかりやすく噛み砕いて解説して下さっている良記事に無料でアクセスできます。
これを使わない手はないですよね。

なのでまずは、**公式ドキュメントを読む前にこれから紹介する記事を読んで大枠を掴んだ上で、公式ドキュメントに挑むのが賢い戦略**と言えそうです。

今回は自分がinside flutterを学習する上で参考になった記事をご紹介します。

## 参考になった記事一覧

個人的に読むべきと思う順番に紹介していきます。


#### 日本人のためのinside flutter用語解説

https://zenn.dev/chooyan/articles/545ad661bea2f8

この記事は公式ドキュメントの翻訳というわけではないですが、難しい和訳の部分などを、噛み砕いて説明してくださってます。
この記事だけでもざっくり、inside flutterのざっくりした概要を掴むためのヒントになるかと思います。


#### 【Flutter】Navigator.of(context) から理解する 3つのツリー

https://zenn.dev/chooyan/articles/77a2ba6b02dd4f

この記事もflutterのレイアウトの仕組みに対して、とてもとっつきやすい内容になっています。
widget,Element,RenderObjectの三つのツリーに対してそれぞれの役割が説明された上で、Navigator.of(context)を例にしてコードベースで三つのツリーが実際どのように使用されているのか学習できます。



#### Flutter の Widget ツリーの裏側で起こっていること

https://medium.com/flutter-jp/dive-into-flutter-4add38741d07

ElementからWidgetとRenderObjectがどのように生成されるのかに加えて、statefulWidgetのUI作成の仕組み（stateやelement）などの解説もあり、面白いです。
また、swiftのUIKitとの比較でいかにflutterが宣言的なUI構築にこだわっているかなど、別の視点からの考察があり、理解を深めることができました。

#### 「Flutter 完全に理解した」状態を抜けた時に書いた記事たち

https://qiita.com/chooyan_eng/items/0354083e62c012cf49ba

少し発展的な内容にはなりますが、setState()やText、など普段見慣れているものが、三つのツリーとどう関わっているかなど上記で紹介した内容を理解していないと理解できない内容の記事がいくつか紹介されています。
上記三つの記事を周回した後に少し覗いてみるといい勉強になるかもしれません。


## 最後に


前提として、inside flutterを完全に理解するのは難しいし時間がかかると思います。

公式ドキュメントも含めて、今回紹介した記事を何度も何度も読み込んで少しずつ理解を深めるのが正しい学習法なんだと思います。

それにしても本当にエンジニアにとっては恵まれた時代だなと思います。
多くの優秀なエンジニアが時間を捻出して書いてくださった記事に無料でアクセスできるのは本当にありがたいです。
ぜひ活用させてもらいましょう！

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

根気強く良く一緒に頑張ってつよつよエンジニアを目指しましょう！！
APIとはそもそもなんぞや

# APIとはそもそも何ぞや
APIとは他社が提供するサービス内の情報や機能を扱えるようにする仕組み
リクエスト＜＝＞レスポンス

# RESTful API
RESTful APIとは・・・４つの原則から成り立ってる

- アドレス可能性

バラバラのURIより１意のURI目指そうぜ。
（ご飯、パン、味噌汁じゃなくて、食料みたいな）

- ステートレス可能性

すべてのリクエストが完全に分離してセッション管理など行われていないこと。
（渡されたレスポンスを前提にしない）

- 接続性

情報に「別の情報へのリンク」を含めることができることを指し、リンクを含めることで別の情報に接続することが可能になる。

- 統一インターフェイス

情報の取得、作成、更新、削除といった操作一式はすべてHTTPメソッドを利用。
8th Wallで 動くBIOカードを作る(その３)

# 8th Wallアカウントの作成
まずは8th Wallのアカウントを作成します。無料トライアルの場合もクレジットカードが必要となりますので手元に用意してください。

１．8th Wallのサイト上段にある「無料トライアルを開始」をクリックします。
![website.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296487/2e748228-0696-2ad4-7293-9b35b5f35bd2.png)
２．アカウント作成に必要な情報を入力し、次へを押下します。この後、入力したEメールアドレス宛に認証コードが送信されるので、登録を行います。
![website_regist1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296487/8987f73d-877c-ca0d-864c-e701bb5384b8.png)
３．次に決済情報の入力を行います。「プランを選択する」のリストをクリックすると選択項目が表示されます。長期に利用するつもりでないなら、とりあえず「Starter $12」を選択しておきます。
![website_regist3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296487/5ddb140e-dcb4-c13c-867d-5a49b186d72a.png)
![website_regist4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296487/25c1086d-122e-8cf7-e7b6-94372f714505.png)

# プロジェクトの作成
アカウントが作成できたら、いろいろプロジェクトの作成です。
１．Topページの「マイプロジェクトへ」をクリックします。
![toppage.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296487/81bec81d-fd51-1db9-fc86-766a6a25402c.png)
２．マイプロジェクトのページへ遷移します。私はいくつかプロジェクトを作成していますので「最近のプロジェクト」が表示されています。
今回はサンプルプロジェクトをもとに作成していきますので、「A-Frame: Image Targets Flyer」というクラゲの画像のプロジェクトを探して選択します。
![myproject1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296487/96e61e6c-2763-037c-42d2-7cc3b8c5dc79.png)
３．サンプルプロジェクトの詳細が表示されますので「プロジェクトをクローンする」を選択します。
![myproject2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296487/6b0ec745-1222-93e2-896a-d8b98ed9964a.png)
４．プロジェクトURL、プロジェクト名を入力します。
ここでは両方とも「biocard01」と設定し。作成ボタンを押下します。
![myproject3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296487/a4210eaf-5237-790d-2eab-43de71c692df.png)
５．サンプルに含まれるファイル一式がコピーされ、新しいプロジェクトが出来上がりました。
![myproject4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296487/c8cd3338-8297-40de-8a1e-0070a1e8f71e.png)

ここから、先に作成した画像、動画を設定していきます。
(次の記事へ続く)

https://qiita.com/minakuchiya/items/bcb815e7524067c6f23f