OmniAICreator/Qiita-1.07M huggingface dataset:
Next.js(Typescript) + Three.js(Fiber,Drei)で3Dモデルファイルを読み込んで表示するまで

## 環境

- react: 18.0.0
- react-dom: 18.0.0
- three: 0.139.2
- next: 12.1.0
- react-three/drei: 9.2.0
- react-three/fiber: 8.0.10
- typescript: 4.6.2

## 1. 導入

そもそも、この構成でやっている記事が少なく、動くようになるまで少し手間取ったため記事を書くことにしました。
もっと良い方法があったら教えて頂けると助かります。

## 2. 手順

①プロジェクトを作成
```
yarn create next-app
```

②各種 yarn add

③ディレクトリ構成
```
components/
  ┣ Model.tsx
  ┣ DrawCanvas.tsx 
pages/
  ┣ _app.tsx
  ┣ index.tsx
public
  ┣ モデルファイル
```

④モデル用コンポーネント定義

```Model.tsx
import { useGLTF } from "@react-three/drei"

const Model = () => {
  const gltf = useGLTF('/house.glb')
  return (
    <primitive object={gltf.scene} />
  )
}

export default Model
```

⑤キャンバス用コンポーネント定義

```DrawCanvas.tsx
import { Suspense } from 'react'
import { OrbitControls, Stage } from '@react-three/drei'
import { Canvas } from '@react-three/fiber'
import dynamic from 'next/dynamic'

const Model = dynamic(() => import('../components/Model'))

const DrawCanvas = () => (
  <Suspense fallback={<span>loading</span>}>
    <Canvas>
      <OrbitControls />
      <Stage>
        <Model />
      </Stage>
    </Canvas>
  </Suspense>
)

export default DrawCanvas
```

⑥pageに配置

```index.tsx
import type { NextPage } from 'next'
import DrawCanvas from '../components/DrawCanvas'


const Home: NextPage = () => (
  <>
    <DrawCanvas />
  </>
)

export default Home
```

## 3. 注意点

- useGLTFなどのモデル読み込みを、キャンバスを定義するコンポーネント(DrawCanvas.tsx)のスコープの中で行うとうまく行かなかった
- モデル用のコンポーネントを別に定義する必要がある
- 別ファイルに定義したモデル用コンポーネントは dynamic import する必要がある
- Suspenseを使う場合、Suspenseの中にCanvasを配置する必要がある
- 表示されたキャンバスはデフォルトでは大きさや比率がおかしいので、cssなどでスタイリングする必要がある
Salesforce のロングテキストエリアはレポートに利用できないのでサーチエンジンを実装した

Salesforceのビューやレポート。お手軽に情報の取りまとめが出来て便利ですよね。よく使っています。
弊社リバネスのSalesforceは、Herokuで構築したリバネスIDという会員サイトと接続しており、様々な情報が入ってきます。
例えば、[リバネス研究費](https://r.lne.st/about/)の申請書であったり、[TechPLANTER](https://techplanter.com/)の申請書といった情報が登録されます。
これらの申請書に含まれるフィールドには、ロングテキストエリアやリッチテキストエリアが存在しますが、この中に様々なキーワードが含まれる状態です。
弊社のニーズとしては、これらの情報の中から、ある特定のキーワードを含む人をリスト化してアプローチしたいというものがあり、これまでビューとかレポートで作っていたのですが、ここには大きな落とし穴があることに気付きました。

仕様はこちらに
https://help.salesforce.com/s/articleView?id=sf.fields_rich_text_area_limitations.htm&type=5

>レポートの検索条件の「次の文字列を含む」演算子では、リッチテキストエリアまたはロングテキストエリアの最初の 254 文字のみがサポートされます。

え。最初の254文字しかサポートされてなかったの！？と、2022年にもなって今更気付くことに相成りました。

## なぜこんなことになるのか
実は、ロングテキストエリアはApexのクエリ言語であるSOQLでもサポートされていません。検索出来ない事になっています。
そしてレポートはSOQLでも出来ないことを実現しているということになる訳です。
では現実的にどうするかというと、一度データローダでデータをダウンロードし、Excel等で検索せざるを得ません。
そんな面倒なことできるか！ってなりますよね。


## 代替案はないのか
先程SOQLというSELECT文では検索出来ない、レポートやビューも使えないと書いたのですが、ロングテキストエリアを含む検索が実装されている箇所が一つだけあります。
そう、グローバル検索窓です。
こちらについては全ての項目を対象として検索をしてくれます。
唯一の全文検索方法はグローバル検索を使うしか方法がありません。

## プログラム的に解決する方法を探すと
SalesforceにはSOQLの他に、SOSLというクエリ言語があります。

https://developer.salesforce.com/docs/atlas.ja-jp.soql_sosl.meta/soql_sosl/sforce_api_calls_sosl_find.htm

SOSLこそがグローバル検索で使われている機能だと言えます。
今回はこちらを使ってサーチエンジンを書いてみました。

## リバネス用の検索エンジン Loorule(るーるる)
![Loorule検索.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22294/5065407d-5672-23c7-c86c-d5966a4ec129.png)

実装自体はVisualforce + Apexという仕様です。
これで検索すると、こんな形でテーブルが返ってきます。(名前等はDataMask使って変換済み)

![Loorule検索.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22294/017d4905-3015-1f15-dd50-9d437fed3836.png)

なんでテーブルなのかというと、このテーブル自体をコピペしてPardotに取り込むことでメールリストが作成できる為です。

## SOSLの書き方

```Loorule.cls
            String findQuery = 'FIND \'' + keywords + '\' IN ALL FIELDS RETURNING LnestID_Project_Associations__c(id, theme__c, purpose_of_research__c, research_background__c, research_plans__c, theme_discription_overview__c, social_issues_overview__c, social_issues_longtxt__c, core_tech_overview__c, core_tech_longtxt__c, Native_language_Name__c, company__c, division__c, Title__c, Email_LnestID__c, Lnest_projects_Name__c WHERE status__c != \'Draft\' ORDER BY CreatedDate DESC)';
            List<List<sObject>> results = search.query(findQuery);
```

こんな風になっています。
RETURNINGのあとにsObjectを指定し、カッコの中にかえしてほしいカラム名を指定します。
keywordsには、サーチエンジンに入力した文字列が入ります。
これでList<List<sObject>>という、sObjectのリストのリストが返ってきます。
なぜsObject型で受けるのかというと、Findの中では、複数オブジェクトを指定することが出来ます。それが返ってくるからですね。

## まとめ
以上で、ロングテキストエリアも対象とするリストを作成することができます。
SOSLこれまで使ったことなかったのですが、便利な機能ですね。
SQL(Part2)

```
INSERT into login_register.test_table (name , age) values ('名前1'  ,19);
//レコードの挿入

INSERT into login_register.test_table (name , age) values ('名前2'  ,19),
('名前3' , 19),('名前4' , 19);//複数レコードの挿入

select 取得する属性 [as label] from テーブル名 [as alias];//レコードの取

属性一覧
*//全て取得
count(*)://レコード件数を取得
distinct:重複を省く
as:列ラベルの変更

delete from テーブル名//レコードの削除

条件句
SELECT * from test_table
WHERE name = '名前2';//一致するものを取得

order by// 昇順、降順の指定
desc //降順
asc //昇順

limitとoffset
limit //取得数を制限する
offset //取得レコードの開始位置を変更する。

update //値を更新する

テーブルの結合
select テーブル
inner join テーブル
on 結合条件;

select * from 左テーブル(右テーブル)
left join(right join) 右テーブル(左テーブル)
on 左テーブル.一致する属性 = 右テーブル.一致する属性;

```
条件句を詳しく → https://www.sejuku.net/blog/51583
rebootの確認

FreeBSD/mipsのRT3050なNTPサーバをwatchdogで再起動するようにしたので、おうちモニターにcgiを追加して確認できるようにしました。

```ruby:reboot.cgi
#!/usr/local/bin/mruby

ip = ENV['REMOTE_ADDR']

db = SQLite3::Database.new('/tmp/server.db')
tc =  db.execute("select count(*) from sqlite_master where type='table' and name='reboot'").next[0]
if tc == 0
  db.execute_batch("create table reboot(date default CURRENT_DATE, time default CURRENT_TIME, host TEXT)")
end
db.execute_batch("insert into reboot(host) values(?)", ip.to_s)

print "Content-type: text/html\n\n"

print "OK"
```

それぞれのモジュールで起動するときにこのcgiを叩くようにします。

後日追記：データーベース作成の処理は別にしました。


最後のrebootをブラウザで表示できるようにjsonにしてみました。

```ruby
#!/usr/local/bin/mruby

db = SQLite3::Database.new("/tmp/server.db")

val = Array.new
# get last recode by JST
sel = "select date(date, time, '+9 hours'), time(time, '+9 hours'), host from rebootorder by date desc, time desc limit 1"

db.execute(sel) do |row, fields|val[0] = row[0]
val[0] = row[0]
val[1] = row[1]
val[2] = row[2]
end
if val.length == 0 then
val[0] = ""
val[1] = ""
val[2] = ""
end

print "{ \"a\": "
print "\"Re: " + val[2].to_s + "\", "
print "\"b\": { \"c\": \"" + val[0].to_s + " " + val[1].to_s
print "\"} }"
```

気温などを計っている、bcmbmなmruby on YABMのモジュールも起動時にアクセスしてログを落とすようにしました。
American Megatrends International における セキュアブートの無効のやり方

ver.2.21で確認しています
# セキュアブートの無効化
UEFIを起動(Window再起動を押す際にshift同時押し→トラブルシューティング→詳細オプション→UEFIファームウェアの設定を選び再起動)

Security→Delete all Secure Boot Variable

# セキュアブートの有効化
同様にUEFIを起動しSecurity→enroll all factory default keys
IBM Cloud ALBがヘルス・チェックで送信する内容

# ALBがヘルス・チェックで送信する内容

IBM Cloud ALB (Application Load Balancer for VPC) でヘルス・チェックを設定した際に、
届いたパケットをサーバー(Nginx)側でキャプチャーした結果を記載する。


## 構成

* ALB
    * フロントエンド・リスナー：Http port 80
    * バックエンド・プール
        * ヘルス・チェック(HTTP) : GET / HTTP/1.0
        * ヘルス・チェック(TCP)  : TCP port 80
        * サーバー：HTTP port 80
* サーバー
    * Nginx version 1.16.1


## キャプチャー結果 (HTTP)

Nginx上で`tcpdump -w ファイル名`で取得

|  | ALB<br>(192.168.0.8)| 向き | サーバー<br>(192.168.0.4) | 説明         |
|--|----------    |------|-------------|-------------|
| 1| TCP Syn      | →    |             |TCP 3 hands shake Port 80|
| 2|              | ←    |TCP Syn-Ack  |TCP 3 hands shake|
| 3| HTTP Get     | →    |             |GET / HTTP/1.0\r\n|
| 4| TCP Ack      | →    |             |TCP 3 hands shake |
| 5| TCP Psh Ack  | →    |             ||
| 6|              | ←    |HTTP Response|HTTP/1.1 200 OK Connection:close|
| 7| TCP RST      | →    |             ||
| 8| TCP RST      | →    |             ||

- サーバーからHTTP/1.1 200 OK Connection:closeのレスポンスを受け取ると、ALBはRSTで切断した。
- ALBはサーバーからStatus Code 200 OKの応答があるとSuccess(合格)と判定する。

## Wiresharkでの表示結果

|<img width="1200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329464/ab60a0e4-d94e-6d35-7f9d-ca50043d6db7.png">|
|:--|


## キャプチャー結果 (TCP)

Nginx上で`tcpdump -w ファイル名`で取得

|  | ALB<br>(192.168.0.8)| 向き | サーバー<br>(192.168.0.4) | 説明         |
|--|----------    |------|-------------|-------------|
| 1| TCP Syn      | →    |             |TCP 3 hands shake Port 80|
| 2|              | ←    |TCP Syn-Ack  |TCP 3 hands shake|
| 3| TCP RST      | →    |             ||

- サーバーからTCP Syn-Ackのレスポンスを受け取ると、ALBはRSTで切断した。
- ALBはサーバーからTCP Syn-Ackの応答があるとSuccess(合格)と判定する。


# 参考リンク 

IBM Cloud Application Load Balancer for VPC についての FAQ
https://cloud.ibm.com/docs/vpc?topic=vpc-load-balancer-faqs&locale=ja

※上記ヘルス・チェックの送信内容についての記述はありません。
論理削除と物理削除について

# はじめに
システム上のデータの管理において重要な「削除」機能。
一言に削除機能といっても
・ 論理削除
・ 物理削除
の二つがある。
それぞれの内容、メリット、デメリットをまとめておく。

# 論理削除
文字通り「論理的な」削除を示す。
表面上はデータを削除したように処理するが、データそのものは残っている状態。
下図の例は、バックエンドのデータ項目に「Delete」を追加しフラグを立てることで
フロントへのレスポンスにデータを含めないという処理を行っている。
![スクリーンショット 2022-04-13 11.11.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1595331/9ec36f0f-27b2-954b-d419-df1fba37ad40.png)
論理削除＝非表示処理、と認識できる。

## 論理削除のメリット
データを消さない、つまり<B>元の状態に戻すことができる！</B>これに尽きる。
例えば、アプリケーションの仕様が途中で変わり、削除済みデータが必要になったとする。
そんな場合でも、フラグを修正するだけで過去の削除データを簡単に復元することができる。

## 論理削除のデメリット
データを消さない、つまり<B>延々とデータが蓄積されていく。</B>
軽量データなら大きな影響はないかもしれないが、塵も積もればなんとやら。
気付いたら大量のデータが蓄積され、ローディングなどの挙動に影響する場合もある。

# 物理削除
データを抹消する「物理的な」削除を示す。一般的に削除と言ったらこちらだろう。
論理削除とは異なり、データそのものを消去する。
下図の例は先述した論理削除の構成と同じだが、削除により完全にデータが消え
バックエンドにもデータが残っていない状態になっている。
![スクリーンショット 2022-04-13 15.05.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1595331/a9777871-bdc2-cb13-141b-4bdf17573e47.png)
物理削除＝廃棄処理、と例えられるだろう。

## 物理削除のメリット
<B>不要なデータが蓄積せず、コードを単純化できる。</B>
文字通りデータが消去されるので、論理削除とは異なりデータの蓄積はされない。
データそのものがないのだから、ロジックを間違えて表示されたりすることもない。
不要なデータがないので、データとロジックの最適化がされている状態になる。

## 物理削除のデメリット
<B>削除したデータの復旧はできない。</B>
当然だが、後で必要になっても復旧させることはできない。
重要なデータほど、物理削除は慎重に行うべきだろう。

# 使い分けとベストプラクティス
以上、論理削除と物理削除について記述した。
簡単にまとめると
<B>・論理削除＝非表示にしてデータを残す
・物理削除＝データの完全消去</B>
と言えるだろう。
どちらも一長一短で、場面によって使い分け、もしくは組み合わせることが必要になる。
個人的に考えるベストプラクティスとしては
<B>基本は論理削除とし、一定期間使用しなかった削除データに対し物理削除を行う</B>
という二段構えだ。
多少の手間はかかるかもしれないが、安定したデータ管理ができると考える。

# 最後に
データを管理する上で避けられない「削除」ではあるが、その削除には種類があり、
性質をしっかり把握し適切に用いることで、より安全なデータ管理を図れることがわかった。
今後はシステムのアーキテクトを考慮し、より適切な削除方法を組み込んでいくこととする。
【Mac】iTerm2の自動ログ取得設定

# はじめに
今まで業務でWindowsを使用しており、ターミナルは「TeraTerm」を使用してきました。
しかし、これからはMacを使用することになりそうなので、「iTerm2」の使用に慣れておく必要があると思っています。
そこで、今回はiTerm2の自動ログ取得設定について記事を書きたいと思います。

# iTerm2とは？
Macで使用されるコマンドラインツールの1つになります。
Macには標準でターミナルが付いておりますが、より使用しやすくしたものがiTerm2になります。

iTerm2の主な機能としては、以下になります。
- フルスクリーン表示
- 画面分割機能
- インスタントリプレイ機能
- オートコンプリート機能

詳しくは、以下の記事をご覧頂ければと思います。
[iTerm2 とは](https://it-kyujin.jp/word/382/)

# 自動ログ取得設定手順
※iTerm2は既にMacに導入済みであることを前提とした手順になります。

**1.iTerm2を起動し、上部のメニューより「Profiles」→「Open Profiles」と開く。**
![スクリーンショット 2022-04-13 14.43.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/636476/043f7e52-d068-7957-6c9d-b045ce6b3905.png)

**2.「Default」を選択し、「Edit Profiles」を選択する。**
![スクリーンショット 2022-04-13 14.43.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/636476/592cdee8-e6e4-52c2-4102-58164454f098.png)


**3.設定画面が起動する。**
- 「Profiles」→「Session」と選択。
- 「Automatically log session input to files in:」にチェックを入れる。
- 「Change」をクリックし、ターミナルのログを格納するフォルダを指定する。

![スクリーンショット 2022-04-13 14.45.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/636476/21b92325-35dc-7b89-d979-b9f27bb8faf5.png)

:::note info
フォルダの指定のみでOKです。
(ファイル名は自動で付与される仕様です。)
:::

**4.設定画面を閉じた後に、iTerm2のターミナルを開き直すと、設定したログ格納フォルダにログファイルが作成されていることを確認。**
![スクリーンショット 2022-04-13 14.46.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/636476/02e79649-6ad0-ffd1-bec0-8bcff5ed7f1c.png)

ファイル名は`20220413_144634.Default.w0t0p0.081A64DC-0826-4F52-A0E0-45CD29D8465A.69963.1237453808.log`になっています。

# 参考記事
[iterm2でターミナルログを自動的に取得させる](https://orebibou.com/ja/home/201512/20151205_002/)
JavaScript MikotoStudio 保存版 2022

# 概要

しまぶーさんのIT大学を基にまとめました
<iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/De9PH3EAz7c" title="YouTube video player"frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

- 歴史と変遷
- 重要な３つの概念
- 変数宣言
- モジュールのImport/Export
- パッケージ管理
- バージョン管理
- CSS
- Mikoto プロフィール

# 歴史と変遷
JavaScriptは、昔シェアを占めていたブラウザーのNetScapeの社員が開発したブラウザでの表示・振る舞いを拡張させるための言語です。
Javaとは別の言語ですが、当時のJava人気をあやかってJavaScriptと名付けられたそうです。（これが混同される元に…）
その後、Internet Explorerがリリースされ、IE用にもJavaScriptが開発されました。

エンジニアは双方のブラウザ用に開発していましたが、統一させるために中核となる言語としてECMAScriptが誕生しました。
Nodejsなどブラウザのみならずサーバー側とも共通の動作のみが定義されており、ES2015(ES6)リリース以降、毎年されています。


## 重要な３つの概念

1. **モジュール**
主に依存関係を解決させる目的で使用されるコードの影響範囲の単位
ES modulesのみでなくNodejsなどバージョンによってはCommonJSしか動かないものなどもあるため両方の形式を把握することが必要

2. **パッケージ管理**
そのプログラム全体を動かすために使用するために必要なすべてのソフトのバージョンなどをまとめた仕様書やレシピのようなものにまとめて管理すること
jsonファイルに保存されており、npmやyarnで取り込むことで

3. **ビルド**
異なる環境下でも同じコードを動かせるようするための事前準備がビルド
例）webpackやVite


## 変数宣言

- ``const`` :　重複、上書き不可
- ``let`` :　上書き不可
- ``var`` :　重複、上書き可　基本使わない

## モジュール　Import/Export

```` javascript:words.js
// 直接Named import --- (1)
const greeting = "Hello";

// コンソールで受け取った値を出力
export function log(value){
 console.log(value);
}

// まとめてNamed exportする場合 --- (2)
export { greeting };
````

```` js:bridge.js
// まとめて再エクスポート
export * from "words.js";
````

```` js:index.js
// 直接words.jsから(1)(2)をNamed import
import { greeting, log } from "./bridge.js";
// 間接的にbridgeファイルからインポート
// import * from "bridge.js";

// コンソルに出力するログを指定（ブラウザ影響なし）
log(greeting);

// ブラウザのボディに出力するテキストを指定
document.body.textContent = greeting;
````

## パッケージ管理

.json　このファイルで依存関係のあるインストール必須なパッケージを管理

ライブラリをClone先でインストールさせるための準備
````.gitignore
node_modules
````

``npx``　自分の環境にインストールせず一度限りアプリを実行する
``yarn dlx``で同じように実行できるが、Yarnの次期バージョンの使用はまだ普及されていない
※　打ち間違いなどを狙った類似コマンドによるウイルスインストールに注意
例　``npx create-next-app``


## バージョン管理
``yarn update [Pakcage]``でlockfileをアップデート

チルダ表記 ~
コンパレータでマイナーバージョンが指定されている場合、パッチレベルの変更を許可します。 
そうでない場合は、マイナーレベルの変更を許可します。
~1.1.2 = 1.1.2 <= version < 1.2.0 [^1]
~1.1 = 1.1.x
~1 = 1.x

キャレット表記 ^
X.Y.Z = [メジャー、マイナー、パッチ]
タプルの左端のゼロ以外の数字を変更しない変更を許可する。
"^1.2.3" = 1.2.3 <= version < 2.0.0
"^0.2.3" = 0.2.3 <= version < 0.3.0
"^0.0.3" = 0.0.3 <= version < 0.0.4

Lockファイルでバージョン管理
````json:.lock.json
{ "dependencies" :
  { "foo" : "1.0.0 - 2.9999.9999"
  , "bar" : ">=1.0.2 <2.1.2"
  , "baz" : ">1.0.2 <=2.3.4"
  , "boo" : "2.0.1"
  , "qux" : "<1.0.0 || >=2.3.1 <2.4.5 || >=2.5.2 <3.0.0"
  , "asd" : "http://asdf.com/asdf.tar.gz"
  , "til" : "~1.2"
  , "elf" : "~1.2.3"
  , "two" : "2.x"
  , "thr" : "3.3.x"
  , "lat" : "latest"
  , "dyl" : "file:../dyl"
  }
}
````
【備忘録】MAVProxy経由でNTRIPデータをAutopilotへ送信する

QGrround Control（QGC）上でNTRIPを使う為、MAVProxy経由でNTRIPデータの入れ込みを行ったので、その方法を記載する。

## イメージ
![zu.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1064722/e063edcc-c4e5-278a-9170-a75ebcf40428.png)

## 手順
1.MAVProxyをラズパイにインストール
2.AutopilotとラズパイをUSBで接続
3.MAVProxyを起動
4.NTRIPサーバの情報を入力する
5.GCSを起動する

## 1.MAVProxyをラズパイにインストールする
MAVProxyをラズパイにインストール

```
sudo apt-get install python3-dev python3-opencv python3-wxgtk4.0 python3-pip python3-matplotlib python3-lxml python3-pygame
pip3 install PyYAML mavproxy --user
echo 'export PATH="$PATH:$HOME/.local/bin"' >> ~/.bashrc
```

## 2.AutopilotとラズパイをUSBで接続
AutopilotのUSBとラズパイをUSBで接続する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1064722/06c79ec8-c19a-6807-aa3e-d8e1fcf168ef.png)

## 3.MAVProxyを起動
SSHでラズパイにアクセスし以下のコマンドを入力してMAVProxyを起動します。
```
pi@raspberrypi:~ $ mavproxy.py --master=/dev/ttyACM* --baudrate 115200 --out 192.168.xx.x:14550
```
もしくは
```
pi@raspberrypi:~ $ mavproxy.py --baudrate 115200 --out 192.168.xx.x:14550
```
:::note info
※ xx.xはGCSのIPを記載します
※ ttyACM*はautopilotと接続しているシリアルポートを記載します
　　確認方法 ⇒ https://qiita.com/m2_labo/items/7823fb26197fa5f5ff23
:::

## 4.NTRIPサーバの情報を入力する
```
module load ntrip
ntrip set caster XXXXX
ntrip set port XXXXX
ntrip set mountpoint XXXXX
ntrip set username XXXXX
ntrip set password XXXXX
ntrip start
```
:::note info
※ XXXXはNTRIP配信先の情報を入力する
:::

## 5.GCSを起動する
MAVPoxy経由経由でNTRIPサーバよりRTCMデータを受信しAutopilotへ送信し、GPSは自動的にRTK Float モードへ移行する（演算終了と同時にFIXへ変わる）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1064722/34ce3c63-2cb3-b92e-d7da-b4fe0e3abb8f.png)

## 参考
https://ardupilot.org/mavproxy/docs/getting_started/download_and_installation.html#linux

https://www.ardusimple.com/send-rtk-base-station-corrections-to-ardupilot-with-missionplanner-qgroundcontrol-and-mavproxy/
安全書類の仕様まとめ　作業員名簿編

建設業業で公共事業とかを受注すると必須な安全書類

| 項目| 説明　|
| :-- | :-- |
|事業所名|施工体制台帳|
|所長名|施工体制台帳|
|一次会社名|施工体制台帳|
|X次会社名|受け会社|


| 項目| 説明　|
| :-- | :-- |
|ふりがな|対象のふりがな|
|氏名|　対象の氏名|
|※|　ｓ|
|雇入日|　入社日|
|期間|　対象の業務に従事した期間、雇入前に経験した期間も対象になるので雇用期間より多い場合もある|
|生年月日|　対象の生年月日|
|年齢|　対象の年齢|
|現住所|　対象の住所|
|家族連絡先|　対象の家族の住所|
|最近の健康診断日|　年一回の健康診断を実施日|
|血圧|　対象の血圧|
|血液型|　対象の血液型|
|特殊健康診断日|　業務（高気圧業務・放射線業務・特定化学物質業務・石綿業務・鉛業務・四アルキル鉛業務・有機溶剤業務）によって義務付けられた健康診断実施日|
|種類|　高気圧作業健康診断、電離放射線健康診断、特定化学物質健康診断、有機溶剤健康診断、石綿健康診断、じん肺健康診断、鉛健康診断、四アルキル鉛健康診断（現場によって行政指導の情報機器作業健康診断、騒音健康診断、振動業務健康診断が対象になる場合もある）|
|雇入・職長特別教育|　各種教育の記述|
|技能講習|　各種技能講習を記述|
|免許|　各種免許を記述|
|入場年月日|　入場日を記述|
|受入教育実施日|　教育実施日を記述|
ChromeOS FlexでshellやLinuxを使いたい

# 三行で説明
- Googleは、ChromeOSのx64ジェネリック版であるChromeOS Flexを公開しています
- ところがどういうわけか、shellコマンドを使えなくしていて、せっかくのChromeBookの利点である、Linux端末として全く使えません
- これを解除する方法のテストを行ったのでメモです。

# 具体的なやりかた
- https://www.youtube.com/watch?v=EZe20wsWMgc
- 上記Youtubeを見て、その通りにします。

自分が行ったのは

- ChromeOS FlexをインストールしたHDDを別のLinuxに接続する
- 最後のパーティション(EFI BOOTパーティション）をマウントする
- 以下の4つのcfgファイルの cros_legacy などが書かれているところの後ろに、cros_debug というカーネルパラメータを追記する

```
efi/boot/grub.cfg
syslinux/usb.A.cfg
syslinux/root.A.cfg
syslinux/root.B.cfg
```

- HDDをもとのPCに繋ぎなおして再起動します。
- Ctrl + Alt + 'T' で端末を起動して、shell が使えるようになりました。

# 蛇足
- 自分が行った機材では、残念ながら、Crouton のインストールに失敗するようです。
- そのあたりの追及はまた後日。（力尽きたので）
アルゴリズム・プログラミング的思考を学べるアプリを作りました

1年近く前に作ったものですが、載せておきます。

## アルゴパズル

https://play.google.com/store/apps/details?id=com.NishikiHase.algoPuzzle

### 概要
- アルゴリズム・プログラミング的思考を学ぶためのアプリ
- 日常生活やゲームを題材にし、身近な例で考えられるように
- 順序、繰り返し、分岐など基本的な要素から学べる

### 良いところ
- 何かを参考にせずに自力で作れた
- Unityでコードを書かずに作成
- 日常やゲームといった身近ものを落とし込めた（と思っている）

### 悪いところ
- UIがしょぼい
- 画面サイズの調整ミスってる？（機種によっては左右上下はみ出す）
- 操作説明が少ない？

### 所感
- 個人的にはすごくおしい（良い線いってる）感じがするが、プログラミングを知らない人からしたらそもそも意味が分からないかも
- UI・UXが良くないんだろうなと感じている（全体的に記号的過ぎる）
- 作るのは楽しかった
- 問題はいくらでも増やせそう
- 問題を作るゲーム・機能があってもいいかも

広告とかもつけてないので、プレイした人の感想が欲しいです。
AdSenseを遅延読み込みさせるツール作ったらスコアが40点上がった

**Googleアドセンスを遅延読み込みさせるコードの生成ツール**を公開して実際にどれ位高速化したのか検証しました。
結論の通り40点もLighthouseのモバイルスコアが上昇しました

https://tools.ic731.net/seo/adsense/

https://0115765.com/archives/7729

## ツール概要
Webサービスを収益化しようとした際に必ず直面するのが**Google AdSenseを使うとPagespeed InsightsやLighthouseのモバイルのスコアが露骨に激落ちする**問題。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513165/35573b1c-9954-49f1-82e4-50c753392292.png)

一応 AdSenseコードにも`async`属性がついており非同期で読み込むようになっていますが、如何せんスクリプトが肥大化しているため、パフォーマンス低下の要因となります。
別にInsightsやLighthouseのスコアが直接SEOに関係するわけではないのですがページの読み込みは遅いより早い方がもちろんSEO的にも有利です。

そこで今回作ってみたわけです。

### 使い方
AdSenseの設定画面で取得できる**自動広告コードを貼り付けるだけ**。

https://tools.ic731.net/seo/adsense/

あとは遅延読み込みを施したコードに変換します。![Inkedスクリーンショット 2022-04-13 020744_LI.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513165/4d58516f-d04f-f10d-f623-884642e7c040.jpeg)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513165/57d0b0b0-d342-72f8-253e-b3893e9e1be9.png)


## Lighthouseスコアが58点→99点に
実際に遅延読み込みコードを入れる前と後でどれくらいLighthouseスコアが変わったかを調査しました。
結果は58点から99点と、41点ほどの大幅な速度向上実現できました。

![ogp.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513165/77246338-f617-d5c2-f2e3-eb29f1e299ed.jpeg)


https://pagespeed.web.dev/

配置している広告の数やタイプによって大きく変わります。**自動広告を1･2個程度しか挿入していない場合58点程にはなりません**。精々70点くらいです。
編集時点で気づいたのですが画像のWebP置換も行っていたので正確な値ではないですごめんなさい

## 遅延させる仕組み
遅延させるコードと手法自体は**真新しいものではなく、2019年頃からあり結構有名です**。今回公開した物はそれらの操作を超簡単に行うためのツールという位置づけです。
仕組みとしては以下のとおり

1. DOMを構築させる（通常だとここで読込開始）
2. DOM構築完了（まだ読み込まない）
3. ユーザーがページを**スクロールさせる**（**この時点で読み込み開始**）
4. 0.5〜1秒後に広告が表示される

### DevToolで見ると分かりやすい
ChromeのDevToolのネットワークタブを一緒に見ると読み込みの様子がよく分かると思います。以外録画した映像

<iframe width="560" height="315" src="https://www.youtube.com/embed/ZvN3KYOCjWE" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

見れば分かる通りユーザーがスクロールイベントを行ったタイミングでAdSenseが読み込まれます。

勿論、モバイル全画面広告やアンカー広告も問題なく表示できています。
※このツールでは以下のブログのコードを一部改修して利用しています。

https://blog.zdienos.com/2019/03/mempercepat-loading-blog-yang-terpasang-iklan-google-adsense.html

## (おまけ)使用技術等
さいごにおまけですがツール開発に使ったものを羅列

- FW: Vue.js 2
- CSS FW: PicoCSS ←これ超おすすめ。NoClassで綺麗に作れる

VueはCDNで読み込んで使いました。なんせ仕組みも簡単だし**ミニツール**なのでわざわざVue-Cliでプロジェクト作って…といった面倒なことは勘弁(´・ω・`)
v2なので従来のOptions APIです（~~Composition APIってReact Hooksのパチモンってイメージ…好きだけど~~）

以上。良いAdSenseライフをお過ごし下さい！

https://0115765.com/archives/7729
Tomcatで「Port 8080 required by Tomcat v9.0 Server at localhost is already in use.」となった時の対処法


windows
cmd（コマンドプロンプト）で、次に順にコマンドを実行します。

ポート8080を使用しているプロセスを探します。

netstat -ano | findstr 8080

taskkill /F /pid xxxx
【BigQuery】 ラテン文字の正規化

# 概要
ラテン文字をアルファベットに正規化したかったときのメモ

# BigQuery

```sql
WITH data AS(
  SELECT 'èòa™' AS text
)

SELECT
  text,
  REGEXP_REPLACE(NORMALIZE(text, NFD), r'\pM', '') nfd_result,
  REGEXP_REPLACE(NORMALIZE(text, NFKD), r'\pM', '') nfkd_result
FROM data
```

# 結果
```
1	 èòa™   eoa™   eoaTM
```

# 参考
- [Link](https://stackoverflow.com/questions/48509104/how-to-remove-diacritic-marks-such-as-accents-using-unicode-normalization-in-s/48509105#48509105)
MySQL 文字コードの混乱

備忘録的記録集
業務で利用しているMySQLについて、いきなり文字化けが発生…
MySQLのバージョンを新しくした直後に発生のため調査し、わかったことを記載していきます。

1.MySQLデフォルト文字について
MySQLでは、デフォルト設定としてlatin1という文字コードが設定されています。（初めて聞いた…）
この文字コードが日本語に対応していないため、文字コードを変更してあげましょう。
今現在設定されている文字コードについては、`SHOW VARIABLES`を実行すると確認できます。
（charだけを見たい、という場合は、後ろに`LIKE 'char%'`などをつけるのがいいです。）

2.おすすめ文字コードについて
おすすめも何も…という感じですが、以下の文字コードを設定するのがよさそうです。（統一推奨。）
・utf8
・utf8mb4
my.cnfにある特定の箇所の文字コードを、上記文字コードを設定後、MySQLを再起動して文字化けが解消しました！

…台無しですが、もしかしたら古いバージョンのままでよかったかもしれない。

※MySQLにて、`SHOW CHARACTER SET`を実行すると、設定可能な文字コード一覧が表示されます。
　それほど使うことが多くはないと思いますが、頭の片隅に入れておくといいかもしれません。
　↓こんな感じ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/605483/b464c303-348d-277b-3225-8e60614c4442.png)
Android EditTextで大文字英数字のみ入力可能とする

# はじめに
EditTextにて大文字の英字と数字のみ入力可能としたかったので、android:inputTypeで良いものがないかを探していました。
`textEmailAddress` `textUri`等は日本語も入力できてしまうのでダメでした。

結論、色々試したところ`textVisiblePassword`を使うとIMEから日本語がなくなったためこれを使用しました。
また、大文字を強制したいため`textCapCharacters`も追加し、android:digitsの指定も行いました。

IMEを開いた時点で大文字入力モードとなっており、小文字は入力できません。
# コード

```xml
                    <EditText
                        〜省略〜
                        android:inputType="textVisiblePassword|textCapCharacters"
                        android:digits="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
                        〜省略〜
                    />
```

# 終わりに
16進数での入力制限を行いたい場合は、digitsをFまでにすれば良いです。
`android:digits="0123456789ABCDEF"`
Raspberry Pi4, Ubuntu21.10, OpenVINO2022.1, NCS2環境構築

MYRIAD X の後継って出さないんですかね。Neural Compute Stick 2 の次バージョンは出ないんですかね。

チップ開発は終わっているけどIntelの戦略変更のため外販しないという噂は本当なんですかね？

## これは何？

Raspberry Pi4, Ubuntu21.10(aarch64) で OpenVINO2020.1のビルドできたよ、動くよ。それと同じ物をM1 MacBook PROのDocker上でビルドできるよ、というお話です。

需要がないかもしれないけど、自分用の手順メモとして。だってさ、最新バージョンの追っかけ、ビルドが趣味だからね。

## build

以下の手順でビルドします。

```
git clone https://github.com/kose/build-OpenVINO.git
cd build-OpenVINO
git checkout 2022.1
git submodule update --init --recursive --depth 1


cd opencv
mkdir build
cd build
../../Ubuntu/opencv.sh
make -j 7
sudo make install

cd /opt/intel
sudo ln -s openvino_2022.1 openvino_2022
```

```
export INTEL_OPENVINO_DIR=/opt/intel/openvino_2022
export OpenCV_DIR=$INTEL_OPENVINO_DIR/extras/opencv/lib/cmake/opencv4

cd openvino
mkdir build
cd build
../../Ubuntu/opencv.sh
make -j 7
sudo make install
```

```
export INTEL_OPENVINO_DIR=/opt/intel/openvino_2022
source $INTEL_OPENVINO_DIR/setupvars.sh

re-build OpenCV （OpenVINO付きOpenCVをビルドする）
```

## Docker

M1 MacBook Pro上のDockerで上のビルドができます。Raspberry Pi4の３倍ぐらい速いです。（Intel上でもビルドできるけどqemuが遅いのでRaspi nativeより遅いです）

```
git clone https://github.com/kose/dockerfiles.git
cd dockerfiles/openvino

run.sh: USER=your-use-name ・・・変更します。
mkdir $HOME/docker  　　　　・・・ここがマウントされます。

./run.sh   ・・・・ パスワードを入力します。それでsudoができます。

これで login しているので、上記のbuildを実行します。
```


### Raspberry Pi4にコピー

Dockerの /opt/intel/openvino_2022.1 を丸ごと Raspberry Pi4にコピーします。

## PYTHONPATH

pythonでcv2がないって言われるならPYTHONPATHに以下を追加。
(extras/opencv/setupvars.shでセットされることを期待してる、なのかな）


```
/opt/intel/openvino_2022/extras/opencv/lib/python3.9/site-packages
```

## Raspberry Pi4でNCS2を使えるように udev を設定

- https://github.com/openvinotoolkit/openvino/wiki/BuildingForRaspbianStretchOS

このページの下の方を実行します。

```
sudo usermod -a -G users "$(whoami)"

cat <<EOF > 97-myriad-usbboot.rules
SUBSYSTEM=="usb", ATTRS{idProduct}=="2485", ATTRS{idVendor}=="03e7", GROUP="users", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1"
SUBSYSTEM=="usb", ATTRS{idProduct}=="f63b", ATTRS{idVendor}=="03e7", GROUP="users", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1"
EOF

sudo cp 97-myriad-usbboot.rules /etc/udev/rules.d/
sudo udevadm control --reload-rules
sudo udevadm trigger
sudo ldconfig
rm 97-myriad-usbboot.rules
```

## ARM CPU plugin

- https://github.com/openvinotoolkit/openvino_contrib/blob/fa6000a2fc1046aa92798cb583c4285ee553086e/modules/arm_plugin/README.md

openvino_with-arm-plugin.shを使えばビルドできて動きます。でもね、Open Model Zooのサンプル動かすと、なんたらが未サポートとメッセージ出て終了しちゃう。

今後に期待ですね！！ M1サポートも入っているようだしね。
C＃を使用してExcelドキュメントを保護する方法

Excelドキュメントの保護に関して、最初に頭に浮かぶのはパスワード保護の方法ではないでしょうか。しかしWordとは少し違って、一般に、各Excelワークブックには、多かれ少なかれ特定の数のワークシートが含まれているため、したがって、Excelドキュメントを保護するのは、ワークブックの保護とワークシートの保護という2つの種類に分類されます。Excel 2013で、左上隅にある「ファイル」->「情報」をクリックして、ワークブックの保護と当のワークシートの保護である2つのオプションを見つけます。ファイルのパスワード保護を設定することで、ドキュメントのプライバシーを保護したり、他のユーザーがファイルを変更できないようにしたりできます。もちろん、それを実現する方法がいろいろあります。今日は主にC＃プログラミングおよび使いやすいコンポーネントである[Spire.XLS for .NET](https://www.e-iceblue.com/Download/download-excel-for-net-now.html)を使用してExcelドキュメントを保護する方法を記述しています。

## パート1：ワークブックを保護する

詳細な手順：

ステップ1：名前空間を使用する：

新しいVisual C＃プロジェクトを作成し、参照を追加して、次の名前空間を使用します。
```
using Spire.Xls;
```
ステップ2：新しいワークブックオブジェクトを作成し、保護するExcelドキュメントを読み込みます。
```
Workbook book = new Workbook();
book.LoadFromFile(@"C:\Users\Administrator\Desktop\sample.xlsx");
```
ステップ3：パスワードで保護されたブックを設定します。
```
book.Protect("abc-123");
```
## パート２：ワークシートを保護する

ここでは、保護ワークシートをパスワード保護とパスワードおよび操作モード保護の2つのカテゴリに分けられます。

パスワード保護：パスワード保護が設定された後、ユーザーはワークシートに変更を加えることができなくなります。これは読み取り専用に相当します。変更する場合は、パスワードを入力して保護を解除する必要があります。

パスワードと操作モードの保護：このモードでは、ユーザーは一部の操作を変更できます。

ステップ4：ブックの保護と同様に、保護する必要のあるワークシートを取得し、パスワードと操作保護を設定します（ここでは、最初のワークシートとパスワード保護方法を選択します）。
```
Worksheet sheet = book.Worksheets[0];
sheet.Protect("def-345", SheetProtectionType.None);
```
ステップ5：ドキュメントを保存して再起動します。
```
book.SaveToFile("ProtectExcel.xlsx", ExcelVersion.Version2010);
System.Diagnostics.Process.Start("ProtectExcel.xlsx");
```
ワークブックを保護する結果を示す画像：
![01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278784/39b3ebbb-3f25-1555-899d-f342eaf73962.png)

ワークシートを保護する結果を示す画像：
![02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278784/a00069c3-be85-6654-c1c3-5b243c590556.png)

## 完全なるコード一覧
```
using Spire.Xls;

namespace Protect_Excel_Document
{
    class Program
    {
        static void Main(string[] args)
        {
            //ワークブックをロードする
            Workbook book = new Workbook();
            book.LoadFromFile(@"C:\Users\Administrator\Desktop\sample.xlsx");

            //ワークブックを保護する
            book.Protect("abc-123");

            //パスワードでワークシートを保護する
            Worksheet sheet = book.Worksheets[0];
            sheet.Protect("def-345", SheetProtectionType.None);

            //ドキュメントを保存する
            book.SaveToFile("ProtectExcel.xlsx", ExcelVersion.Version2010);
            System.Diagnostics.Process.Start("ProtectExcel.xlsx");
        }
    }
}
```

今回のExcelドキュメントを保護する方法は以上でした、最後まで読んでいただきありがとうございました。
CRUDのAPIにPUTは要らないのでは説

# はじめに
データベースのテーブル単位でCRUDのAPIを作成している中で、「別にこれPUT要らなくね？」となったのでそのケースについて書いていきます。
「CRUDのAPI」というと複雑で大きな処理も考えられると思いますが、シンプルなレコードの読み書きレベルの想定で書いていると思ってください。

# CRUDのAPIにPUTは要らないのでは説
CRUDのAPIの設計をどうしようか検討している時に事例を調べてみると、よく下記のような例が見つかります。

```
[POST]   /data      ← 作成(C)
[GET]    /data/:id  ← 読取(R)
[PUT]    /data/:id  ← 更新(U)
[DELETE] /data/:id  ← 削除(D)
```
うん、代表的なRestAPIって感じの綺麗さでいいですね。ここまでは分かります。

でもこれで作っていくと「冪等ってなんだ…？」問題と「コーディング上の都合」問題にぶち当たることになり、**PUTはやめてPOSTでいいんじゃないか**という気がしてきます。

これから2点、PUT要らない説の話をするので「それはおかしいやろ😠」という内容があればコメントにてご指摘ください。

# 「冪等ってなんだ…？」問題
PUTの定義を調べると「冪等(べきとう)」でなければいけないと書かれています。
https://developer.mozilla.org/ja/docs/Web/HTTP/Methods/PUT

つまりCRUDのU、更新は送信値で上書きする処理なので何度やっても変わらないから冪等であり、PUTが適しているということですね。これも分かります。
ただ実際のAPIにおいては単純な話で済まないことが多く、更新のAPIには下記のような副作用があることがあります。

- レコードに更新日時を設定
- 更新ログの追加
- 重要なデータの場合はメール等の通知

上記のような副作用がある時にも「冪等」と言えるかというと多分厳しくて、じゃあそれはPOSTにするべきじゃないか、となります。
すると更新のAPIがデータの重要度によってPUTだったりPOSTだったりまちまちになってしまい、使い手側がいちいち「このデータの更新APIはどっちだっけ？」となるのが嫌なので結局「どちらかで統一しようよ」という話になる気がします。
※ここで使い手が都度確認するべきで別に統一しなくても良くない？という話になるならこの話は以上です😞

そこでPOSTとPUTのどっちに統一する？といった話になるんですが、そもそもPUTが冪等であって嬉しいことの1つに「呼ぶ度にリソースが増えたりしない何度呼んでも問題ないAPI」として安心して使えることだと思うんですよね。
ここで実は裏でちゃんと副作用があって呼ぶ度にどんどんリソースが変わってます/増えてます、となると使う側からすると「冪等って言ったじゃん😩」になるのでPUTで統一するのはよろしくない気がします。
(もちろんAPIのマニュアルを書くべき＆読むべきというのはそれはそうなんですが名が体を表していないのは問題なので)

すると結局更新はPOSTで統一するのが使う側も細かいこと考えずに済むので良いような気がします。

# コーディング上の都合
これは言語などにもよると思うんですが、自分はよくNode.js+expressの環境でコーディングしていて「PUTじゃなくてPOSTのが楽なんだよなあ」となります。
結局CRUDのCもUも「Write」で、コーディング上はCRUDの4つに分かれているよりRead/Write/Deleteの方が扱いやすい気がするんですよね。
具体的にはCRUDのAPIを作っている時は下記のようなコードで書きたくなります。

```js
// Read
app.get('/data/:id', (req, res) => {
  let data = Data.getById(req.params.id);  // URLの:idでデータを取得
  res.json(data);                          // JSONで返す
});

// Write
app.post('/data(/:id)?', (req, res) => {
  // idがあるかどうかで新規かどうか分岐
  let data = req.params.id ? Data.getById(req.params.id) : new Data();

  /*** dataに値を設定する処理 ***/

  // 保存
  data.save();
  res.json(data.id);
});

// Delete
app.delete('/data/:id', (req, res) => {
  let data = Data.getById(req.params.id);
  data.delete();
  res.json(data.id);
});
```

ここでCとUがPOSTとPUTに分かれてるとめんどくさいんですよ。いや別にロジックを外にまとめればいいだけの話でそんなめんどくさいってほどじゃないんですけど。
もちろん新規と更新で権限チェックだとかそういう箇所が違うこともあるでしょうけど、複雑なものじゃない限りこのパターンの方が楽なんじゃないかなあと思っています。

# 最後に
もちろん最初に書いた通りこれはテーブル単位でCRUDのAPIを作るシンプルなケースを想定して書いているので、当てはまらない場合もいっぱいあると思います。ただ「みんなCRUDと対応した4つのメソッド使ってるから自分もそうしよう」みたいな状態になっているなら一考の価値はあるかなーと思いこの記事を書きました。

あとみんながPUTのどういうところにメリットを感じて使っているのかが分からなかったのでこの記事によってツッコミをもらいたいというのもあります。PUTを使うと何が嬉しいのか補足できる方は教えてください🙏
日本の証券業界のトップが語る「運」とはっ！

## 前書き

『「運」という不確実なものについて、世の先人たちが語る「運」には、ある種の共通項があるのではないか？』
毎日続けている読書感想文「１日１話」の記事の読書の中で、何度か「運」について語る先人たちの記事を読んできた私は、「運」について語る記事について「運シリーズ」というタグを振る感想文をQiitaの中でも書くことを始めた。
先人たちが語る「共通項」について考察し、エンジニアとして、人間として生きるためのヒントを掴もうというためである。

今日読んだ記事、致知出版社[『1日1話、読めば心が熱くなる365人の仕事の教科書』][1]の【12月19日】目。
大和證券グループ本社のトップが語る「運」である。

[1]:https://www.amazon.co.jp/1%E6%97%A51%E8%A9%B1%E3%80%81%E8%AA%AD%E3%82%81%E3%81%B0%E5%BF%83%E3%81%8C%E7%86%B1%E3%81%8F%E3%81%AA%E3%82%8B365%E4%BA%BA%E3%81%AE%E4%BB%95%E4%BA%8B%E3%81%AE%E6%95%99%E7%A7%91%E6%9B%B8-%E8%97%A4%E5%B0%BE%E7%A7%80%E6%98%AD/dp/4800912474




## 本題【12月19日】 実力より評判だよ　 鈴木茂晴 大和証券グループ本社社長

鈴木茂晴。実業家。大学卒業後、大和證券に入社しトップに上り詰めた。日本証券業協会長、東京都顧問も務めた。
1947年生まれ。御年、今年で75歳。

鈴木が語るのは「運」。おや、「運」シリーズだ。この記事は2010年の雑誌「致知」の対談記事。
Wikiによると、前年の2009年、「2億2700万の役員報酬を受ける」とある。
日本の証券業界のリーディングカンパニーのトップが語る「運」とは？

>私は決して一番ではなかったんです。
私より優れたセールスマン、頭のいい社員は山ほどいましたが、そういう人たちが必ずしも上に立ったわけではない。
若い人たちのために何か参考になるとしたら、自分の上に立つ人のすることをよく見たほうがいいと思います。
例えば営業員の場合、年次や役職によって目標が課せられます。その時、自分の目標だけを追いかけてもまず達成できません。
上司の目標以上はやろうと思わないと、自分の目標は果たせないんです。
それから目標数字を果たすために、あらゆるお客様の所を苦しんで駆けずり回るでしょう。
そうやって必死に頑張って達成すると、次の月はとても楽なんですね。多くの人に会って、見込みもいっぱいできているわけですから。
ところが、お客様を回ってもいないのに、たまたま大きな契約が取れて、その月の目標は達成したとする。
そうすると、次の月にとても苦しむことになります。
ですから、運というのは闇雲に下りてくるものではありませんね。
見る目を持って一所懸命努力している人のところにしか訪れてこないということです。
何もしていない人のところにはやってこない。
これははっきりしています。運は実力そのものなんです。

　ほう。「運も実力のうち」とはよく言うけど、『運は実力そのもの』と言い切るか。
　自分は人一倍努力してきたんだぞ、っていう自負心が見え隠れするが、まあ、実際そうなのであろう。

>もう一つは、運は人が持ってきてくれるんですね。
だから、人との関係はとても大切にしておかねばならないと思います。
私はよく「実力より評判だよ」と言うのですが、いくら実力があっても評判が立たなくては運はつきません。
反対に実力はそれほどでなくても、評判が立ったら自分がそれに追いつかざるを得ない。
そうして皆の期待に応えようと努力していく中で運をつかんでいくわけです。
一方でこういう見方もできるのではないですか。
ついている人の周りにはついている人しか集まってこない、と。

>幸いなことに、私の周りには運の悪い人がいないんですね。
だいたい世の中で社長と呼ばれている人に「あなたは運がいいですか」と聞いてみると、ほとんどが「運がいい」と答えると思います。


日本の証券業界のトップが語る「運」。
それは **『見る目を持って一所懸命努力している人のところにしか訪れてこない』** ということ。
このことは、この本に登場する他の先人たちの語る「運」と共通しているな、と思った。

違和感を覚えたところは、先にも触れた『運は実力そのもの』という発言と、世の中の社長と呼ばれている人たちのほとんどが「運がいい」と答えると思うだろうと発言しているということ。

鈴木さんが考える「運がいい」とは、どういう状態をいうのだろうか？　
「人より金持ち」なことが「運がいい」というように感じた。

引用はしないが、鈴木さんは日経新聞のコラム『私の履歴書』で連載をしていた。
その中で自分の体験した昔話として、当時の証券業界の今なら完全アウトな話を語っている。

私の履歴書の記事を読んで思った。
鈴木さんはそのような証券業界の修羅場を潜ってきて、トップまで昇りつめたた兵（つわもの）なんだなーと。


（参考）

https://ja.wikipedia.org/wiki/%E9%88%B4%E6%9C%A8%E8%8C%82%E6%99%B4

https://moneytimes.jp/money/investment/japanese-securities-company-ranking

## 後書き
以上、「運シリーズ」第8弾、**日本の証券業界のトップが語る「運」とはっ！** でした。
最後までお読みいただきありがとうございました。

よろしければ、過去の「運シリーズ」も読んでいただければ幸いです。

https://qiita.com/takeC74/items/73763dc10d4e33439449

https://qiita.com/takeC74/items/9030941082d9e08782e9

https://qiita.com/takeC74/items/30bcef3dbcfb595864d6

https://qiita.com/takeC74/items/fcc22c9a0e27bc8b0f46

https://qiita.com/takeC74/items/c496778447ea86ce8769

https://qiita.com/takeC74/items/5801a8e53e63153f86a6

https://qiita.com/takeC74/items/386a20e56d2cffa3bd94

https://qiita.com/takeC74/items/e2f51d395a6efc94d8c5
Android Studio 最新版で Lombok plugin が使えなくなったときの対処法

# (2023/01/30追記) Lombok Pluginは使わないほうが良い気がする
最近のAndroid Studio （2022.1.1あたりのバージョン）で下記の手順通りに Lombok Plugin を導入すると、Android Studio が挙動不審になるようです。例えばコードのサジェストが動かなくなり、生産性が著しく低下します。
ということで、Lombok は使わない方向にしたほうが良いかもしれません。
例えば、Android Studio には Getter/Setter を生成してくれる機能があるので、それで Lombok の `@Getter` `@Setter`のアノテーションの代わりになります。そのような方法で Lombok に頼らない実装をしたほうが良いかもしれません。

それでも試してみたい方は、以前に書いた以下の記述をご参照ください。

--- 

# この記事について
タイトルの通りです。
Android Studio を 2021.1.1 あたりにバージョンアップすると、Lombok plugin がエラーとなり使えない状態となってしまいます。
その対処方法をまとめました。

# いきなりですが答え
以下のページに書いてあります。
https://stackoverflow.com/questions/70900954/cannot-find-lombok-plugin-in-android-studio-2021-1-1-build-of-2022

## 手順をざっくり書くと
1. Android Studio を起動し、メニューの Files → Settings → Plugins を開き、「Installed」のタブからエラーになっている Lombok plugin を削除します。
1. Android Studio をいったん終了させます。
1. ブラウザから https://plugins.jetbrains.com/plugin/6317-lombok/versions を開き、最新版の Lombok plugin (0.34.1-2019.1) の zip ファイルをダウンロードします。
1. zip ファイルを展開します。
1. 展開後のディレクトリ ( `/lombok-plugin` ) を、Android Studio の pluginディレクトリ (Windowsの場合だと `C:\Program Files\Android\Android Studio\plugins\` ) 以下に`/lombok-plugin`ディレクトリごとコピーします。
1. Android Studio を起動します。

これで Lombok Plugin が使えるようになります。
【合格体験記】AWS認定ソリューションアーキテクト–プロフェッショナル(SAP-C01)

# 本記事の概要

AWS認定ソリューションアーキテクト–プロフェッショナル(SAP-C01) を取得したので勉強方法を備忘録として投稿します。
AWS-SAPを受けようと思っている方や、現在勉強している方がこの記事を参考の一つにしていただけたら幸いです。

# 使用した教材

Udemy
・[Ultimate AWS Certified Solutions Architect Professional 2022](https://www.udemy.com/course/aws-solutions-architect-professional/)

・[AWS Certified Solutions Architect Professional Practice Exam
](https://www.udemy.com/course/aws-certified-solutions-architect-professional-aws-practice-exams/)

参考書
・[AWS認定ソリューションアーキテクト-プロフェッショナル ~試験特性から導き出した演習問題と詳細解説](https://www.amazon.co.jp/AWS%E8%AA%8D%E5%AE%9A%E3%82%BD%E3%83%AA%E3%83%A5%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%88-%E3%83%97%E3%83%AD%E3%83%95%E3%82%A7%E3%83%83%E3%82%B7%E3%83%A7%E3%83%8A%E3%83%AB-%E8%A9%A6%E9%A8%93%E7%89%B9%E6%80%A7%E3%81%8B%E3%82%89%E5%B0%8E%E3%81%8D%E5%87%BA%E3%81%97%E3%81%9F%E6%BC%94%E7%BF%92%E5%95%8F%E9%A1%8C%E3%81%A8%E8%A9%B3%E7%B4%B0%E8%A7%A3%E8%AA%AC-%E5%B9%B3%E5%B1%B1-%E6%AF%85/dp/4865942483/ref=tmm_pap_swatch_0?_encoding=UTF8&qid=1649814155&sr=8-1)

# 勉強の流れ

AWSについては、AWS-SAA、AWS-SOA、AWS-DVAを取得済み程度の知識を持ってます。
[AWS-SAA合格体験記](2020-12-04_AWS_191dc5c77fbaf238ce28.md)
[AWS-SOA合格体験記](2021-01-17_AWS_da6faebbf934e11bc643.md)
[AWS-DVA合格体験記](2021-03-07_AWS_ff4c478c1b10c34577d9.md)

基本的な流れは以下の通りです。

1. 参考書
2. Udemy (Ultimate AWS Certified Solutions Architect Professional 2022)
3. Udemy (AWS Certified Solutions Architect Professional Practice Exam)

## 1. 参考書

AWSからしばらく離れていたので、まずは参考書を頭から実施し記憶を呼び戻しつつ
SAPで問われる知識をインプット。
3週ほど回しましたが、すべての内容を完璧に理解するまではやらずに次の教材に移りました。

## 2. Udemy (Ultimate AWS Certified Solutions Architect Professional 2022)

この教材は、AWS-SAPで問われる範囲のサービスの具体的な知識やユースケースを教えてくれます。
全編通して実施すると長いので、1.25倍速で不安なサービスに絞り実施しました。
英語ですが、Microsoft Edgeで開き翻訳すると字幕をリアルタイムで翻訳してくれるので、
英語が不安な方でもおおよそ理解できると思います。

## 3. Udemy (AWS Certified Solutions Architect Professional Practice Exam)

この教材は、25問 × 6セット分の試験問題を実施出来ます。
他の教材では、同じ値段で本番と同じ75問 × 4セット分入ってるものもありますが、
Udemyの仕様上、75問解き終えないと回答がわからないので、こちらの教材にしました。
問題のレベルも本試験とほとんど変わらなかったと個人的には思います。
本試験でほとんど同じ内容と問われた問題もあったので、この教材はオススメします。

# 試験結果

受験日：2022年4月10日
スコア：768
合格ライン：750
結果：pass

[証明バッヂ](https://www.credly.com/badges/0e64841e-0d18-4652-83a7-6b450ba3399d/public_url)

はい、つらつらと偉そうなこと書いてきましたが、**ギリギリ合格です。**
190分で75問はやっぱり集中力続かないですね。60問あたりから頭がふわふわしてる状態で
解き進めてしまいました。

# 受験後の感想

今回の勉強期間は1ヶ月半くらいでした。

沢山の方が合格体験記を書いてくださっているので、受験にあたり読みましたが、
皆さんこの試験をAWS認定試験では一番難易度が高いと仰っていますね。
専門資格やDevOps資格を取得してないのでわかりませんが、
これから受けるAWS試験は皆、今回以下の難易度だと思うと気が楽になります。

個人的には、LPIC-202試験のほうが範囲が広かったので、勉強自体それほど苦にはなりませんでした。
ただ、LPICはほぼ暗記で解答できるのに対し、こちらはしっかりと思考しないと解答出来ないので、
本試験時の疲労感が桁違いですね。

今後は、実は持っていない基本情報技術者試験に向けて頑張ります。

この記事を開いていただき、また、
ここまで読んでいただきありがとうございました。
useEffectを理解する（概要）

# 概要
- useEffectは関数コンポーネント内で使用することができる
- useEffectの発火には3種類ある

## 毎回のレンダリングの時の書き方
```.js
useEffect(()=> {
    console.log('毎回レンダリングのたびに呼ばれる')
})
```

## 初回のレンダリング時に呼ばれ発火する
```.js
useEffect(()=> {
    console.log('初回時のみ呼ばれる')
},[])
```

## 設定した値が変化した時に発火
```.js
useEffect(()=> {
    console.log('sampleの値が変化した時に呼ばれる')
},[sample])
```
ScoringACを使って写真を解析

仕事で、フォトスタジオを紹介するサイトを運営してるのですが、
（フォトッチ : https://ptc.canon.jp）
訪問者が好む写真を撮ってくれるスタジオをAIで判断できないかと、考えてます。

ScoringAC（https://scoring-ac.com/）というサービスがあり、写真をMean Opinion Score、Brightness、Colorfulness、Contrast、Sharpnessの５項目で評価できるようです。
なお、芸術性は評価出来ないとのこと

スタジオさんのインスタ写真をscoringACで評価して、スタジオ毎に特徴が出るか調べてみようと思います。

インスタ画像は、instaloaderで収集します、

結果です
（個人を特定できないように、わざと画像を荒くしています）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136795/f501db9c-ea88-dea7-d4d1-36fa5327149e.png)

点数が表示されるだけなのですね、５項目の評価が出るのかと思っていました。残念。

今回は、scoringACを利用しましたが、Googleさんのnimaていうのもあるので、次回は、それを使ってみたいと思います。
Haskell入門からモナドまでを最速でマスターする Part 0: 準備

# はじめに

この記事は Haskell 入門からモナドまでを最速でマスターするための方法をまとめたシリーズの Part 0 です。対象読者は Haskell におけるモナドを理解して、使いこなせるようになりたいすべての人です。

Haskell といえばモナドですが、モナドの習得は簡単ではありません。Google でモナドについて検索しても、圏論との関係性について力説した記事や、ある程度 Haskell を理解していないと読み解くことが困難な記事が多く、その記事を読むだけでは習得できません。しかし、モナドは一部の頭の良い人しか理解できない概念というわけではありません。

プログラミング初学者がC言語を勉強する場合、多くの人はポインタで一度躓きます。ですが、代入や参照、そしてアドレスなどポインタを知る上で必要な概念を一つひとつ確実に理解していくことで、ポインタを使いこなすことができるようになるでしょう。Haskell におけるモナドも同様に、モナドを理解するために必要な概念を段階を踏んで理解していくことで確実に習得できます。

このシリーズでは、モナドを理解するために必要な概念を、Haskell の基礎的な内容から順番に紹介していきます。そして、実務で Haskell を使えるレベル、つまり、自分の作りたいアプリケーションに応じてモナドを組み合わせて実装できるレベルまで導きます。

# モナドマスターまでの道のり

このシリーズでは、以下の道のりでモナドをマスターしていきます。

- Part 0: 準備
    - はじめに
    - モナドマスターまでの道のり
    - GHCのインストール
- Part 1: 型クラス
    - 関数と型
    - 様々な構文
    - 型クラスとインスタンス
- Part 2: Monad
    - Functor, Applicative Functor, Monad
    - do 記法と様々なモナド
- Part 3: Real World
    - Cabal, Stack
    - Monad Transformer

Part 0 では準備段階としてモナドをマスターするための道のりを紹介し、Haskell を実行できる環境づくりのために GHC のインストール方法を紹介します。

Haskell におけるモナドは型クラスの一種です。したがって、モナドを理解するためには型クラスについても理解する必要があります。そのため、Part 1 では Haskell の機能の一つである型クラスの習得をゴールとして、Haskell の基礎である関数や型から順番に紹介します。

型クラスについて理解できても、いきなり Monad 型クラスを理解することは困難です。Functor 型クラスと Applicative Functor 型クラスを順番に理解することで、Monad 型クラスが理解しやすくなります。Part 2 では、Functor, Applicative Functor, Monad の順にそれぞれの型クラスを紹介し、モナドを使ったプログラムに必須な do 記法と様々なモナドの紹介を行います。

そして、Part 3 では現実世界に存在する様々なモナドと向き合うための準備として、Haskellのパッケージ管理ツールである Cabal と Stack について紹介し、Monad Transformer によるモナド組み合わせる方法について紹介します。

# GHCのインストール

モナドまでを最速でマスターするためには、手を動かすのが一番の近道です。このシリーズでは Haskell の 代表的なコンパイラ GHC が提供するインタプリタ GHCi を使って Haskell の説明を行います。

GHC は様々なインストール方法が存在しますが、最終的にモナドをマスターして使いこなすレベルまで到達したいのなら、 GHCup によるインストールをおすすめします。GHCup は Part 3 で紹介する Cabal と Stack のインストールもできるようになっているので、一石二鳥です。

https://www.haskell.org/ghcup/

OSによってインストール方法が異なるため、ここではインストールの手順の紹介は省きます。

GHCのインストールが完了し、 `ghci` コマンドが実行できたら Part 0 は終了です。

```bash
$ ghci --version
The Glorious Glasgow Haskell Compilation System, version 8.10.7
```

# 次回予告

次回は「Part 1: 型クラス」です。モナドへの第一歩として、Haskellの基礎から型クラスまでを説明します。

投稿したら、こちらにリンクを張ります。

この記事をストックしておくと、通知が送られるので、続きが気になる方はぜひストックしてみてください！

# おまけ

次回の記事がいつ投稿できるかは未定です。投稿を待つよりも、自分で本を読んで手を動かした方が最短でモナドをマスターできます。

「すごいHaskellたのしく学ぼう！」と「プログラミングHaskell 第2版」はHaskellについて基礎から説明されている本なので、はじめて読むHaskellの本として最適です。

https://www.ohmsha.co.jp/book/9784274068850/

https://www.lambdanote.com/products/haskell

「Haskell入門 関数型プログラミング言語の基礎と実践」と「入門Haskellプログラミング」はHaskellの基礎だけなく、よく使われるパッケージの紹介やHaskellの実践的な活用方法が書かれているため、二冊目以降に読む本としておすすめです。

https://gihyo.jp/book/2017/978-4-7741-9237-6

https://www.seshop.com/product/detail/22688

また、本以外にもネット上には様々なHaskell入門のサイトがあり、特に、モナドに到達するための方法がまとめられた別の記事も Qiita にいくつか存在するので探してみてはいかがでしょうか。

https://qiita.com/lotz/items/8e66442a329183d5a3ce
Go言語 : for - select in ゴルーチン

## for - select
複数のゴルーチンからの、チャネルを介した値受け渡しを実現させるための構文
selectを使用することにより対象のチャネルからピンポイントで値を受け渡せる。

## Code
```Go
// ある数以上の素数を、1つ求める関数
func primeRoutine(targetLine int, primeChan chan int) {
	fmt.Printf("%d Line Target Goroutine Wake UP \n", targetLine)
	i := 0
	for {
		// 値のインクリメント
		i++
		// 素数チェック
		if checkPrime(i) && targetLine < i {
			fmt.Printf("%d Line Target Goroutine Shut Down \n", targetLine)
			// チャネルにデータ送信
			primeChan <- i
			return
		}
	}
}

// メイン関数
func main() {

	// 求める素数の基準値
	targetLine1 := 100000
	targetLine2 := 150000
	targetLine3 := 200000
	targetLine4 := 250000
	targetLine5 := 300000

	// チャネルの作成
	primeChan1 := make(chan int)
	primeChan2 := make(chan int)
	primeChan3 := make(chan int)
	primeChan4 := make(chan int)
	primeChan5 := make(chan int)

	// 複数のGoroutineを起動して、素数を求める
	go primeRoutine(targetLine1, primeChan1)
	go primeRoutine(targetLine2, primeChan2)
	go primeRoutine(targetLine3, primeChan3)
	go primeRoutine(targetLine4, primeChan4)
	go primeRoutine(targetLine5, primeChan5)

	loop:
		// Goroutineからの返答を、selectを使って待ち受け
		for {
			select {

			case primeResult1 := <-primeChan1:
				fmt.Printf("Answer1 : %d \n", primeResult1)

			case primeResult2 := <-primeChan2:
				fmt.Printf("Answer2 : %d \n", primeResult2)

			case primeResult3 := <-primeChan3:
				fmt.Printf("Answer3 : %d \n", primeResult3)

			case primeResult4 := <-primeChan4:
				fmt.Printf("Answer4 : %d \n", primeResult4)

			case primeResult5 := <-primeChan5:
				fmt.Printf("Answer5 : %d \n", primeResult5)
				// 5つ目を受信したら、forループを抜ける
				break loop

			default:
		}
	}
}
```

## Output Sample
~ $ go build -o main main.go  
~ $ ./main  
100000 Line Target Goroutine Wake UP  
200000 Line Target Goroutine Wake UP  
150000 Line Target Goroutine Wake UP  
250000 Line Target Goroutine Wake UP  
300000 Line Target Goroutine Wake UP  
100000 Line Target Goroutine Shut Down  
Answer1 : 100003  
150000 Line Target Goroutine Shut Down  
Answer2 : 150001  
200000 Line Target Goroutine Shut Down  
Answer3 : 200003  
250000 Line Target Goroutine Shut Down  
Answer4 : 250007  
300000 Line Target Goroutine Shut Down  
Answer5 : 300007  

## GitHub
https://github.com/GL-Kageyama/Go_Goroutine_select
【GitHub】Goのインデントがおかしい問題を解決する

## 原因
GitHub上でデフォルトのタブサイズが8になっているから。
つまり、`1tab = 8 半角スペース`という状況です。

## 解決策
1. `https://github.com/settings/appearance`へ行きます。
1. Tab Sizeを4にします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2611835/6301cf1b-1933-9747-becb-fe173ccc7698.png)

## 余談
chromeの拡張機能だったり、クエリパラメータでタブサイズを変える方法がググると出てきたのですが、最近デフォルトの設定になったんですかね？
LINE連携でngrockが使えへんやないかーい！！

# この記事について

LINE連携でローカルのサーバーを外部公開するためにngrockを使おうとしたけど使えかったので、現在代わり使っているサービスを紹介する記事。（railsでの連携）

「ngrockの使い方をメモ代わりにQiitaに掲載してよかったー」と思っていた矢先、使えなくてガッカリ。。。

https://qiita.com/ashketcham/items/c743e31f818534b828be

## ngrock
LINE公式に問い合わせている方がいらっしゃいました。

https://www.line-community.me/ja/question/5f07c0fb851f74ab9c18e8dc/ngrok%E3%81%A7%E5%A4%96%E9%83%A8%E5%85%AC%E9%96%8B%E3%81%97%E3%81%9Furl%E3%81%A7webhook%E6%A4%9C%E8%A8%BC%E3%82%92%E6%88%90%E5%8A%9F%E3%81%95%E3%81%9B%E3%81%9F%E3%81%84


# 代わりのサービス - localtunnel

https://github.com/localtunnel/localtunnel

## 使用方法

### インストール

```
$ npm install -g localtunnel  
```

### rails server立ち上げ

```
$ rails s -b 0.0.0.0   
```

※`0.0.0.0`で外部からのアクセスを許可する。

### localtunnel 立ち上げ

```
$ lt --port 3000    

your url is: https://×××××-○○○-△△△△.loca.lt
```

立ち上げると「your url is: https://×××××-○○○-△△△△.loca.lt」 みたいなURLが表示されるので、URLをクリック。以下のページが表示されるので、「Click to Continue」をクリックすると、外部公開される。


![スクリーンショット 2022-04-13 10.50.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653956/5feb4c98-c446-3140-6559-064c8ce64e59.png)


## サブドメインを固定する

上記で[localtunnel 立ち上げ](https://qiita.com/ashketcham/items/33f1713c25299e13188f#localtunnel-%E7%AB%8B%E3%81%A1%E4%B8%8A%E3%81%92)を記載したが、デフォルトだとサブドメインはランダムに設定されてしまうので、その度にWebHookURLを登録し直すというめんどくさい作業が発生してしまう。

そこで、以下のようにサブドメインを指定する。

```
$ lt --port 3000 --subdomain rails-local
your url is: https://rails-local.loca.lt
```
AWS CLIに慣れる旅

# ありがたく、普段業務でAWSを使う機会が上々に増えます。
その時に毎回GUIで操作、クロスチェックしてもらってましたがそろそろ手に負えないし、ミスも怖いので、<del>一番は目が痛い</del>
IaCの練習にもなると思うのでできるたけCloudShellで操作しようと思います。その旅のはじまり・・・

### AMIを削除する作業をやりました。

```aws.CloudShell
以下の手順に従い、Amazon EBS-backed AMI をクリーンアップする。
※n-うんぬんかんぬんは各IDに変換して利用する。 ❓は後ほどの獲物（疑問点）

AMI の登録を解除する  →なぜ「削除」ではなく、「登録解除」と呼ぶのだろう❓

1. deregister-image コマンドを使用して AMI の登録を解除します。
$ aws ec2 deregister-image --image-id <ami-うんぬんかんぬん>

2. 不要になったスナップショットの削除(AMI作成するとスナップショットも一つ作成されるので不要であれば忘れずに)
$ delete-snapshotコマンドを使用して、不要になったスナップショットを削除します。

3. インスタンスの削除 (オプション)
aws ec2 delete-snapshot --snapshot-id <snap-うんぬんかんぬん>

AMI から起動したインスタンスの使用を終えた場合には、terminate-instances コマンドによりそのインスタンスを削除できます。

aws ec2 terminate-instances --instance-ids <i-うんぬんかんぬん>
```
https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/deregister-ami.html

### 次の作業は・・・Elastic IP付け替え
https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/elastic-ip-addresses-eip.html
loki usage


https://levelup.gitconnected.com/how-to-setup-grafana-loki-for-free-log-management-ceb60558503c

https://sublimer.hatenablog.com/entry/2021/09/16/185110

https://www.qikqiak.com/post/grafana-loki-usage/

https://jeffwen0105.com/%E8%BC%95%E9%87%8F%E6%97%A5%E8%AA%8C%E6%8E%A1%E9%9B%86-loki-%EF%BC%8C%E6%88%91%E7%94%A8%E6%B4%9B%E5%9F%BA-python%E7%99%BC%E9%80%81log-part-2/

https://github.com/GreyZmeem/python-logging-loki

https://medium.com/geekculture/pushing-logs-to-loki-without-using-promtail-fc31dfdde3c6