OmniAICreator/Qiita-1.07M huggingface dataset:
【SwiftUI】Viewの中でなるべくif文を使いたくない

# はじめに
View内にif文があると美しくないので、View内でif文を使う時用のViewを用意してみました。

# 実装
```swift:PlaceholderView
import SwiftUI

struct PlaceholderView<Content: View, Placeholder: View>: View {
    var `if`: Bool

    @ViewBuilder var content: () -> Content

    @ViewBuilder var placeholder: () -> Placeholder

    var body: some View {
        if `if` {
            content()
        } else {
            placeholder()
        }
    }
}
```

# 使い方
```swift:ContentView
import SwiftUI

struct ContentView: View {
    @State var isLoading: Bool = false
    var body: some View {
        VStack(spacing: 50) {
            PlaceholderView(if: isLoading) {
                Text("コンテンツ")
            } placeholder: {
                Text("プレイスホルダー")
            }
            
            Button {
                isLoading.toggle()
            } label: {
                Text("切り替え")
            }
        }
    }
}
```

# 動画
![Simulator Screen Recording - iPhone 14 Pro - 2023-04-14 at 22.20.46.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/84a651b0-68a0-cc4d-691d-f83700099f26.gif)

# おわり
最近、TCAを勉強してるのですが、`ReducerProtocol`が追加される前の記事が多くて辛いです笑
AWS CodeWhispererがGAされたので登録してみる(個人利用)

# この記事で書くこと
[AWS CodeWhisperer](https://aws.amazon.com/jp/codewhisperer/)の個人利用のための登録方法を書きます。
どのようなサービスか、使い方等は書きませんので[こちら](https://dev.classmethod.jp/articles/amazon-codewhisperer-ga/)をご参考ください。
(個人的に好きなクラメソさんのリンクを貼りました。)

# 事前準備
- vscodeの準備(neovimとかでは現在利用できない模様)
- [aws toolkitの拡張機能](https://aws.amazon.com/jp/visualstudiocode/)
- aws 
- 

# 登録方法
### セットアップ

vscodeを開きます。(aws toolkitが入っていることを想定)
aws toolkitの拡張機能から, `DEVELOPER TOOLS -> CodeWhisperer -> Start`をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722539/a42adf42-dfcf-ee32-af37-7529b9cea571.png)

### 認証

ポップアップが出るので、`Use apersonal email to sign up and sign in with AWS Builder ID`をクリック。(ブラウザに飛ばされます。)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722539/34365f1f-c563-5e22-0304-42866962ce70.png)

`code`の入力を求められます。

**これはメールで送られてきません。**

vscodeの右下に`code`が出ててます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722539/d78aeb5c-80e2-cbac-0d08-04c3d22cef6e.png)

AWS Builderへのログイン.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722539/e9ee76de-cd98-baae-77fb-9facf77d84ec.png)

### 注意

こちらに同意する。この文章を読む限り、CodeWhispererが脆弱性分析をするとは書いてあるが学習に使う使わないは不明。
組織的な導入を見据えている方はご注意ください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722539/e5fb360d-adfe-ea85-ff06-8566d5e3a1c4.png)

これで使えるようになりました。

# 感想
無料なのはいいが、試しにgoで簡単なhttpリクエストをするものを書いたが、`<script>`タグの提案をされて:thinking:となった。
現時点ではCopilotの方が優秀だと思う。
ChatGPTでPowerPointを作ってみた

# 初めに
唐突ですがChatGPTでPowerPointを作りたい！と思いませんか？
私はサークルの新入生向けの講座スライドを作る際にChatGPTに大枠を作ってほしいと今日思い。思い立ったが吉日、ググって作ってみようとしましたがマークダウンにしてみたり、HTMLにして変換しているもので、求めていたものは出てきませんでした。そこでChatGPTに聞いたところ、"python-pptx"を使ってみると出来るよと言われました。

以下に早速使い方を書いていきたいと思います。

# 導入
pythonをインストールしていることは前提として話を進めていきます。インストールしていない人は「python　インストール」でググってください。

python2を使用している場合はコードの初めに以下の一文を追加してください。
```python:
# -*- coding: utf-8 -*-
```
python3使用している場合はpython-pptxはpython3.10以上と互換性が無いそうなのでpython3.9以下を使用してください。

今回のメインとなるpython-pptxをインストールします。

```cmd:cmd
pip install python-pptx
```
# python-pptxを使ってみる
下記がサンプルコードです。改造して使ってみてください。
画像のようなスライドができます。
![2023-04-14 (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632959/3808e6da-b987-107f-2d8f-4582e620c0a4.png)


```Python:sample
from pptx import Presentation
from pptx.util import Inches

# 新しいプレゼンテーションを作成する
presentation = Presentation()

# タイトルスライドのレイアウトを選択
title_slide_layout = presentation.slide_layouts[0]

# 新しいスライドを追加
slide = presentation.slides.add_slide(title_slide_layout)

# タイトルとサブタイトルのプレースホルダーを取得
title = slide.shapes.title
subtitle = slide.placeholders[1]

# タイトルとサブタイトルにテキストを設定
title.text = "Hello, World!"
subtitle.text = "This is an example PowerPoint presentation created using python-pptx."

# 新しいスライドを追加
bullet_slide_layout = presentation.slide_layouts[1]
slide2 = presentation.slides.add_slide(bullet_slide_layout)

# タイトルとポイントのプレースホルダーを取得
title2 = slide2.shapes.title
points = slide2.placeholders[1].text_frame

# タイトルとポイントにテキストを設定
title2.text = "Important Points"
point1 = points.add_paragraph()
point1.text = "This is the first point"
point2 = points.add_paragraph()
point2.text = "This is the second point"
point3 = points.add_paragraph()
point3.text = "This is the third point"

# プレゼンテーションをファイルに保存
presentation.save('example_presentation.pptx')
```
私の説明で足りない部分は下記リンクのドキュメントを参考にしてみてください。

https://python-pptx.readthedocs.io/en/latest/

# ChatGPTにコードを生成してもらう

さて、本題はpython-pptxでスライドを作る事ではありませんでしたね。早速ChatGPTに聞いてコードを生成してもらいます。今回はGPT3.5(default)で検証してみます。

```cmd:GPT3.5
Pythonを初心者に教えます。教える内容を考えてください。
また作成するスライドの内容を考えてください、
その内容をpython-pptxでスライドを作ってください
```
以下のように出力されました。

![2023-04-14 (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632959/0a0f2c64-2c3a-c6ff-b038-26f8bb2ffd1a.png)
![2023-04-14 (4).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632959/8ae959df-7625-d182-f040-1e7c802972e5.png)

まだ、色々改善する箇所はありそうですが大枠を作る分には十分使えると思います。
SNMPの疎通不可時に確認する項目

# 概要
SNMPを使用して、データを取得しようとしても、以下のように表示されうまくいかない事がある。

ここでは、snmpで監視情報を取得される対象を192.168.160.10とする。
SNMP情報を取得するサーバを、監視サーバと故障する。（Zabbixで使用していたため。）


```txt:コマンド
 snmpwalk -v 2c -c public 192.168.160.10 .1
```

```txt:出力
Timeout: No Response from 192.168.160.10
```

上記の時の場合に、主に確認すべき項目を記載します。

# 確認項目

### 疎通確認

 まずは、監視サーバから、snmpの対象まで、pingが通るかを確認する。ルーティング、経路情報に間違いないかを確認する
```txt:コマンド
ping 192.168.160.10
```
これで疎通ができなければ、snmpも通らない。通るなら次。
### サービス起動確認
監視サーバと、snmpの対象の両方で、snmpdが起動している事を確認する。

【監視サーバとsnmp対象の両方で実施】
```txt:コマンド
systemctl status snmpd.service
```

Activeになっている事を確認する。
```txt:コマンド
● snmpd.service - Simple Network Management Protocol (SNMP) Daemon.
   Loaded: loaded (/usr/lib/systemd/system/snmpd.service; enabled; vendor preset: disabled)
   Active: active (running) since 金 2023-02-24 17:26:51 JST; 1 weeks 6 days ago
 Main PID: 950 (snmpd)
```

### firewallの確認
firewalldとか、iptablesを確認。【監視サーバとsnmp対象の両方で実施】
経路の途中でFW機器が挟まっているのであればそこも確認
`service snmp`もしくは、161ポートが空いている事を確認する事。

```txt:コマンド
以下のコマンドで、trustedなどに入っているかを確認
sudo firewall-cmd --get-active-zones
また、zoneを適応させているなら以下のコマンドで。
sudo firewall-cmd --list-all --zone=Zone名
```
iptablesなら、以下コマンドで確認する。
```txt:コマンド
sudo iptables -L
```

### /etc/snmp/snmpd.confの確認

第一の候補で、全体を見て、`community名`が合っているかを確認する。ここでは`public`という名前で設定している。以下のcom2Secなどの確認をするときに、タイポしていないかを確認する。

次に、監視サーバと、snmp対象が同じセグメントにいる場合、
snmp対象サーバの/etc/snmp/snmpd.confを、以下の項目を変更or追加する必要がある
```txt:/etc/snmp/snmpd.conf
変更前
rocommunity public 127.0.0.1

変更後
#rocommunity public 127.0.0.1 <-- コメントアウト
rocommunity public 192.168.160.0/24 <--- 追加
```

また、com2secにて、許可しているセグメントを確認する。

notConfigUserと、defaultは、全てのアドレスを指す。そのためこの場合は、コミュニティ名の全てのユーザがアクセスできるという事になる。

```txt:/etc/snmp/snmpd.conf
com2sec notConfigUser(セキュリティ名) default コミュニティ名
```

アドレス帯で指定するなら、以下のような形式で設定する。セキュリティ名は今回は適当にmynetとした。これにより、192.168.162.0/24のネットワークからのみsnmpの接続が可能となった。

```txt:/etc/snmp/snmpd.conf
com2sec mynet  192.168.162.0/24  public
```

もし修正を行ったら、snmpをリスタートさせる。

```txt:コマンド
sudo systemctl restart snmpd.service
```
そして、監視サーバから、snmp対象にsnmpwalkを実行してみる。snmpの情報が大量に出てくれば問題ない。
```txt:コマンド
snmpwalk -v 2c -c public 192.168.162.10 .1
```

参考サイト

https://www.suse.com/ja-jp/support/jp/kb/tids/00100058/

https://www.server-memo.net/server-setting/snmp/net-snmp.html
バックエンドロードマップ基礎知識

# 個人勉強用
参考
[具体的にどう本物のエンジニアになるかというお話（バックエンドエンジニアのロードマップ付）](https://qiita.com/mackeee-orange/items/afbed5ec3816d4af2e58)
[SSHとは？【分かりやすい解説シリーズ #65】【プログラミング】](https://www.youtube.com/watch?v=nkqdhXSwEVs)
[公開鍵認証とは？【分かりやすい解説シリーズ #24】【プログラミング】](https://www.youtube.com/watch?v=uURs8HnzCQU)
[【Linux】パスを通すとは？【謎の文言】](https://www.youtube.com/watch?v=j1hEFSWYO5s)
[Linuxディレクトリ構造を完全解説！](https://www.youtube.com/watch?v=bzqrlef15wI)

## SSH(Secure SHell)
ネットワークを介して、別のコンピュータを遠隔操作するためのツール。
同じようなものにTelnetがあるが、違いは暗号化されるかされないか。SSHは通信データが暗号化される。

**どんな時に使うのか**
サーバーのセットアップやメンテナンス作業を行う場合。
サーバーを置いたり、復旧したりする作業はSSHを使って自宅のPCからリモートで操作を行う。

**どう使うのか**
PCに導入されている「SSHクライアント」というソフトを使う。macからターミナルを起動し「ssh」と入力することで使える。
```
ssh ユーザー名@サーバーアドレス
その後パスワードを入力するとサーバーに入れる。ちなみにSSH接続はサーバー側も対応していないと行うことはできない。
```
**SSHの認証方式(パスワード認証より公開鍵認証)**
パスワードでの認証の他に「公開鍵認証」という認証方式もある。これはパスワードを使わず、「公開鍵」と「秘密鍵」という仕組みを使い、より安全に接続を行う方法。

**秘密鍵**は「電子署名」というデータを作ることが出来る。
**公開鍵**は「電子署名」というデータを正しいか検証することが出来る。

秘密鍵は自分のパソコンの中に大切に保管しておく。一方、公開鍵はサーバー側に保管しておく。
流れとしては、自分のパソコンの秘密鍵を使い電子署名データを作成し、サーバーに送信する。サーバーでは、その電子署名データを受け取り公開鍵を使って検証してみる。検証に合格すれば認証成功で、リモート接続を許可する。電子署名データはめっちゃ複雑だから盗まれる可能性は低い。しかし、ちゃんと秘密鍵は守らなければならない。

## パスを通す
パスを通すとは「新しくコマンドを登録する」ということ。
例えばwhich lsと打てば、lsの場所を教えてくれるが、それはいろんなファイルの中からlsというファイルを探せたから表示できている。これがパス(道のり)が通っているということ。
逆にどこにあるかがわかならないことをパスが通ってないっていう。
```
教えたいファイルまでのパスを記録
export PATH=$PATH:(パス)　これでパスを追加
これがパスが通っている状態
```

## Linuxのディレクトリ構造
**/bin** OSが正常に動作するための実行ファイル(cpコマンドやらkillコマンドやら)
**/boot** システムの起動に必要なファイル(自分でいじることはほぼない)
**/dev** ハードウェア機器を表すファイル(Linuxではハードウェア機器をファイルで表す。その置き場)
**/etc** 設定ファイル(設定ファイル置き場)
**/home** ユーザーのホームディレクトリ(最初にいる場所)
**/lib** OSに必要なライブラリファイル
**/media** 外部の記憶媒体をマウント(自動)(マウントとはルートディレクトリのどこかに登録すること。登録しないとLinuxは何もできない。外部の記憶媒体はUSBとか)
**/mnt**　外部の記憶媒体をマウント(手動)
**/opt** 追加のアプリケーションがインストール(Chromeとか)
**/proc** OSのシステムをコントロール
**/root** rootアカウントのホームディレクトリ(ルートユーザーのホームディレクトリ)
**/sbin** ルートユーザーのみ実行できるプログラム(システムを管理するようなコマンド)
**/sys** OSの現在の状況に関する情報(システムの全般的な状況に関する情報が入ってる)
**/usr** 全ユーザーが共通して利用するプログラムのデータ(全ユーザーが共通して利用するプラグラムやライブラリデータが入っている)
**/var** システム運用中に生成、あとから削除されるデータ(ログファイルとか)
GCP deployment-managerでnetworkを作成してみた

# 概要
デプロイメントマネージャでネットワークを作成してみました。
デプロイメント名：my-first-deployment
ネットワーク名：a-new-network

参考にしたページは以下の通り。
https://cloud.google.com/deployment-manager/docs/deployments/updating-deployments?hl=ja
https://cloud.google.com/deployment-manager/docs/configuration/use-references?hl=ja

# ソースコード
以下の通りYAMLで記述した。
```network.yaml
resources:
- name: a-new-network
  type: compute.v1.network
  properties:
    routingConfig:
      routingMode: REGIONAL
    autoCreateSubnetworks: true
```

# 実行結果

まずは以下で認証してもらう。

```
$ gcloud auth login
```

YAMLを読み込んで、プレビュー状態にする。

```
$ gcloud deployment-manager deployments create my-first-deployment --config network.yaml --preview
The fingerprint of the deployment is 0GcTB20tvYp_NL4tfUjPWg==
Waiting for create [operation-1681473514752-5f94a8f8bcabb-f0c62b2a-83339091]...done.                                                                                                                      
Create operation operation-1681473514752-5f94a8f8bcabb-f0c62b2a-83339091 completed successfully.
NAME           TYPE                STATE       ERRORS  INTENT
a-new-network  compute.v1.network  IN_PREVIEW  []      CREATE_OR_ACQUIRE
```

デプロイメントを更新する。無事リソースの作成が完了。

```
$ gcloud deployment-manager deployments update my-first-deployment 
The fingerprint of the deployment is C3-t8xuNooa1IGYShQiMhw==
Waiting for update [operation-1681473752498-5f94a9db781cf-da01e28b-b1c45a54]...done.                                                                                                                      
Update operation operation-1681473752498-5f94a9db781cf-da01e28b-b1c45a54 completed successfully.
NAME           TYPE                STATE      ERRORS  INTENT
a-new-network  compute.v1.network  COMPLETED  []
```

ネットワークが作成されたかをCUIで確認。

```
$ gcloud compute networks list
NAME             SUBNET_MODE  BGP_ROUTING_MODE  IPV4_RANGE  GATEWAY_IPV4
a-new-network    AUTO         REGIONAL
datalab-network  AUTO         REGIONAL
default          AUTO         REGIONAL
```

ネットワークが作成されたのをGUIで確認。

![Screenshot from 2023-04-14 21-06-08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3192024/0c0697c2-472c-1c14-75d9-ecbc8afebf56.png)

デプロイメントの中身もGUIで確認。

![Screenshot from 2023-04-14 21-07-33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3192024/521083df-aad2-e3c4-e631-942533fe809b.png)


何かの役に立てばと。
TypeScriptとReact/Next.jsでつくる 実践Webアプリケーション開発のアプリで「カートから削除」ボタンを押すとカートに入っているすべての商品が削除される

この記事は書籍「[TypeScriptとReact/Next.jsでつくる 実践Webアプリケーション開発](https://gihyo.jp/book/2022/978-4-297-12916-3)」に関するものです。

TypeScriptとReact/Next.jsでつくる 実践Webアプリケーション開発のアプリで「カートから削除」ボタンを押すとカートに入っているすべての商品が削除されてしまいます。
[removeProductFromCart関数の不具合修正](https://github.com/gihyo-book/ts-nextbook-app/pull/26)のように修正すると所望の動作になります。

以下詳細です。
カートへの商品追加と削除は以下のようにReducerを使って実装されています。
```TypeScript
/**
 * ショッピングカートのReducer
 * @param state 現在の状態
 * @param action アクション
 * @returns 次の状態
 */
export const shopReducer: React.Reducer<Product[], ShopReducerAction> = (
  state: Product[],
  action: ShopReducerAction,
) => {
  switch (action.type) {
    case ADD_PRODUCT:
      return addProductToCart(action.payload, state)
    case REMOVE_PRODUCT:
      return removeProductFromCart(action.payload, state)
    default:
      return state
  }
}
```

カートから商品を削除するremoveProductFromCartの実装は以下のようになっています。
```TypeScript
/**
 * 商品削除アクション
 * @param product 商品
 * @param state 現在の状態
 * @returns 次の状態
 */
const removeProductFromCart = (productId: number, state: Product[]) => {
  const removedItemIndex = state.findIndex((item) => item.id === productId)

  state.splice(removedItemIndex, 1)

  return [...state]
}
```

[useReducer – React](https://react.dev/reference/react/useReducer#my-reducer-or-initializer-function-runs-twice)によると、
> In Strict Mode, React will call your reducer and initializer functions twice.

とのことなので、removeProductFromCartは2回呼ばれます。
removeProductFromCartの1回目の実行では与えられたproductIdのProductを削除しますが、2回目の実行では
```TypeScript
  state.splice(removedItemIndex, 1)
```
の部分でstateが変更されている(与えられたproductIdのProductは削除されてしまっている)ので、
```TypeScript
const removedItemIndex = state.findIndex((item) => item.id === productId)
```
の実行結果は-1になります。その後
```TypeScript
state.splice(removedItemIndex, 1)
```
が実行されると、removedItemIndexは-1なので、stateは空になります。
```TypeScript
  const newState = [...state];
  newState.splice(removedItemIndex, 1);
  return newState;
```
と、stateを変更しなければ所望の動作になります。
【git , Linux】git log -p で差分を表示すると「ESC」という文字列がたくさん出てくる

## 概要
差分を表示した際に出てくる「ESC」の消し方。
![スクリーンショット 2023-04-14 20.43.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3071346/79630be9-5ed9-0f5c-aad9-1cce74a50864.png)
邪魔です。

## LESS="-R"を設定する
`~/.bashrc`もしくは`~/.zshrc`などに記述すると設定が保存されます。
```:~/.bashrc
#追記
export LESS="-R"
```

`git log -p`による表示結果は、Linuxの`less`コマンド形式で表示されています。
そして、どういう訳かパソコンが認識するための制御文字である「ESC」などの黒い文字が表示されていました。
その制御文字を表示しないオプションが`-R`になります。
ファイルツリーのファイルの左に、ファイルだとわかる印をつけたい

ファイルツリーのファイル名の左に、ファイルであることを示す記号を表示したい。

CSSのcontentプロパティを使って、ファイル名の左にファイルアイコンを表示することができる。

HTMLファイルのファイルリストの例:
```html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="styles.css">
  <title>ファイルツリー</title>
</head>
<body>
  <ul class="file-tree">
    <li class="html-file">index.html</li>
    <!-- 他のファイルを追加する場合は、このようにリストアイテムを追加する -->
  </ul>
</body>
</html>

```
スタイルシートで、ファイルアイコンをcontentプロパティを使って表示する:
```css
.file-tree {
  list-style-type: none;
  padding-left: 0;
}

.html-file::before {
  content: "📄";
  margin-right: 5px;
}
```
この方法では、::before疑似要素とcontentプロパティを使って、ファイルアイコンを表示している。
絵文字を使う代わりに、他の文字やアイコンフォントをcontentプロパティに設定することもできる。
アルファベットの辞書を3行で作成する方法

https://onlinejudge.u-aizu.ac.jp/courses/lesson/2/ITP1/8/ITP1_8_C

を解いててアルファベットの辞書列を作成するのを自動化したかった。備忘録的に保存

参照：https://teratail.com/questions/71512

コード
```
python3
alpha_dict = {}
for i,c in enumerate(range(ord('A'),ord('Z')+1)):
    alpha_dict[chr(c)] = i + 1
```
出力
```
{'A':1, 'B':2, 'C':3, ... 'Z':26}
```
・enumerate：for文内で値のみならずインデックスも取得できる
・ord(str)：Unicordを取得できる。例） ord("A") = 65, ord("Z") = 90

という感じ
WindowsでSlackのSample curl request to post to a channel

Slackの公式に書かれているSample curl request to post to a channelをWindows環境で実行した時の覚書です。そのままSampleを実行すると「invalid_payload」や、「Invoke-WebRequest : パラメーター 'Headers' をバインドできません」のエラーが出ます。
環境：Windows11

---

![](https://storage.googleapis.com/zenn-user-upload/6345a58519ed-20230414.png)


### 1. Curlをインストール
https://curl.se/download.html
Windows 64-bit	8.0.1	binary	the curl project
zipを展開して、binフォルダ直下のcurl.exeを使う

Windowsにもともと入っているcurlコマンドは、オプションなどが異なるため。今回はSampleの書式に合わせるために新たにインストールして使います。

### 2. Sampleコマンドを実行
#### コマンドプロンプトなら
```
curl.exe -X POST -H "Content-type: application/json" --data "{\"text\":\"Hello, World!\"}" https://hooks.slack.com/services/・・・WebhookのURL
```

- ' を " に変更する（文字列は " で囲む）
- " は \ でエスケープ処理をする

#### Powershellなら
```
curl.exe -X POST -H "Content-type: application/json" --data "{'text':'Hello, World!'}" https://hooks.slack.com/services/・・・WebhookのURL
```
- 文字列は"で囲む
- --dataの中の"を'に変更する
分散トランザクションでエラーが発生する原因

問題
MSDTC トランザクションマネージャーが通信の問題のため、送信元のトランザクションマネージャーからトランザクションをプルできませんでした。原因として、ファイアウォールが存在していて MSDTC プロセスの例外がないこと、2 台のコンピューターが NetBIOS 名でお互いを識別できないこと、または 2 つのトランザクションマネージャーのいずれかでネットワークトランザクションのサポートが有効になっていないことが考えられます。

解決方法
ファイアウォールの設定を確認し、MSDTC プロセスに対して適切な例外が設定されていることを確認します。ファイアウォールを一時的に無効にすることで、問題がファイアウォールに関連しているかどうかを判断できます。

両方のコンピュータがお互いを NetBIOS 名で識別できるようにします。これを確認するには、コマンドプロンプトで ipconfig /all を実行し、各コンピュータの NetBIOS 名を確認します。必要に応じて、コンピュータ名を変更して問題を解決します。

コンピュータ名が長すぎる場合、NetBIOS 名として使用できない場合があります。NetBIOS 名は最大 15 文字までの制限があります。そのため、問題を解決するには、コンピュータ名を 15 文字以内に短縮します。

MSDTC サービスがネットワークトランザクションをサポートするように設定されていることを確認します。

これらの手順に従って問題を解決できるはずです。



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2715983/eee2dc14-a737-6b1b-1023-d9d0b3413fd4.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2715983/a34d45ad-02cd-0f61-18a5-2839139050ef.png)
インスタンスサイズダウン時のチェックリスト ~ EC2編 ~

# はじめに
インスタンスのサイズダウンは何度か実施した記憶があるのですが、そのたびに何を調査すべきか調べなおしている気がしたのでまとめてみました。
既出でしたらすみません。

## 1. サーバレス化の検討
そのサーバ、本当に自前で管理する必要がありますか？
サーバレス化には様々なメリットがあります。
個人的には特に「運用の簡素化」の恩恵が大きいと考えています。
サービス改善にかけれる時間がその分増えると思うとワクワクしますね(しない)。
サイズダウンを考えるこのタイミングでサーバレスアーキテクチャに移行できないのか検討・提案してみるのはいかかでしょうか。

↓サーバレス化のメリット例 (by chatgpt)
- コスト削減: サーバレスアーキテクチャでは、リソース使用量に応じて課金されるため、アイドル状態のインスタンスに対して余分なコストがかかりません。
- スケーラビリティ: サーバレス環境では、リクエスト量に応じて自動的にスケーリングされるため、ピーク時のトラフィックにも柔軟に対応できます。
- 運用の簡素化: サーバレスではインフラ管理やサーバのパッチ適用などの運用タスクが減るため、開発者はアプリケーションの開発に専念できます。
- 高い可用性: サーバレスプロバイダーは高い可用性を提供しており、障害が発生しても迅速に復旧することができます。

## 2. リソース使用状況の確認
### 2.1 CPU使用率(CPUUtilization)
CloudWatch の標準メトリクスで確認できます。
特に t系に変更する場合は、CPUクレジットの概念についてちゃんと調べましょう。
バースト可能って100%を超えていいって意味じゃないので勘違いしないように。

### 2.2 メモリ使用率(MemoryUtilization)
カスタムメトリクスです、取得してない場合はこれを機に取得することをお勧めします。
メモリは基本的に単調増加なので計算もしやすいですね。
メモリ解放のタイミング(インスタンス再起動など)や GC の仕様を把握しておくといいです。
アプリケーションの成長にも気を付けたいところ..

## 3. ストレージパフォーマンスの評価
### 3.1 EBS 帯域幅(DiskReadBytes/DiskWriteBytes)
標準メトリクスです。
「最大」という数値に惑わされないでください。CPUとは異なり、クレジットは蓄積される仕様ではないようです。
> アスタリスク (*) が付いているインスタンスでは、最大パフォーマンスを 24 時間につき少なくとも 30 分間維持することができます。その後、ベースラインの性能に戻ります
Read/Write で同じ帯域を使用している(たぶん)ため合計値がベースラインを超えていないか確認しましょう。
Byte, bit の単位に注意。

### 3.2 EBS IOPS(DiskReadOps/DiskWriteOps)
標準メトリクスです。
帯域幅と同じように「最大」という数値は参考程度に見ましょう。
同様に Read/Write の合計値がベースラインを超えていないか確認しましょう。
EBS ボリュームにも IOPS の制限があるのでどちらがネックになるかはちゃんと見た方がよいです。

## 4. ネットワーク性能の確認
### 4.1 ネットワーク帯域幅 (NetworkIn/NetworkOut)
インスタンスのネットワーク入力/出力バイト数を示す標準メトリクスです。
ストレージパフォーマンスと同じように「最大」という数値は参考程度に見ましょう。
同様に In/Out の合計値がベースラインを超えていないか確認しましょう。
ENA がサポートされているインスタンスを使用していて有効化している場合には、変更後のインスタンスで ENA がサポートされているかは忘れずに確認しましょう。

## 5. パフォーマンスモニタリングとアラート設定の確認
インスタンスサイズダウン後はメトリクスが以前より高い値を記録することが容易に想像できます。
変更前後で同じ60%にアラートを設定していても、パフォーマンス的余裕は以前より減っているはずです。
必ずアラートラインが適切か見直しましょう。
t系にしたときはクレジット消費量のメトリクス監視も入れたいですね。
顧客のためではありません、休日の夜中に起こされた時の調査難易度を下げるためです。

## 6. スケーリングポリシーの調整
アラートを設定したらオートスケーリング設定が適切に機能するかどうかを確認し、必要であれば設定を調整してください。
顧客のためではありません、休日の夜中に起こされないようにするためです。

## 7. コスト削減効果の評価
これを見ている方は既に実施済みだとは思いますが今一度確認しましょう。
このサイズダウンにどれほどの価値があり、誰がその価値を生み出したのか正当に評価されるために..

## 8. 上司(顧客)の顔色の確認
要するに「リスクとコスト削減効果のバランスの共有」です。
大幅に削減ができる時ほど怪訝な顔されがちな気がします。
少ししか削減できないことは分かってもらえることが多い気がします。
当然ですがどちらの時でもちゃんと説明できるようになるといいですね。

# まとめ
後半は少しふざけた記述になってしまいましたが、おおむね確認すべき項目はまとめられたのではないかと思っています。
漏れている項目があればコメントに書いていただいたり、編集リクエストをいただければと思います。
ほかにもプロジェクト毎に要件があると思いますし、これが全てと断言するのは無理なので参考程度に見ていただければと思います。

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


# 参考
[EC2 パフォーマンス(AWS 公式 doc)](https://aws.amazon.com/jp/ec2/instance-types/)
[EBS パフォーマンス(AWS 公式 doc)](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/ebs-optimized.html#current-general-purpose)
[ネットワークパフォーマンス(AWS 公式 doc)](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/general-purpose-instances.html#general-purpose-network-performance)
React Routerについて

## React Routerとは
**複数のページで構成されたReactアプリケーションをルーティングするライブラリ**です。React Routerを使用することで、ページの遷移に伴うコンポーネントのレンダリングやURLパラメータの受け渡しが簡単になります。

URLにアクセスした際に、どのコンポーネントを表示させるのかといったルーティングの設定をReact Routerを利用して行います。

## ユースケース
SPAでのページ遷移のために使用されます。ログインページやユーザ登録ページなど複数のページが必要なアプリケーションをReact Routerを使用することで、ユーザーがアプリケーション内でページを遷移した際に、画面の再描画を行わずに、必要なコンポーネントだけをレンダリングすることができます。また、URLパラメータの取得や操作が容易になります。

:::note info
通常はページを移動する度に全体のリロードが必要になります。しかし、React Routerを利用した場合はページ移動の際に、最初にアクセスした時にダウンロードしたJavaScriptを使って更新が必要な場所のみ更新し、データが必要な場合はfetch関数やaxiosライブラリを利用してサーバからデータの取得を行い描写します。
:::

## React Routerの使用
まずreact-router-domパッケージをインストールします。

```npm
$ npm i react-router-dom -D
$ npm i @types/react-router-dom -D
```
<br>

以下、ドキュメントより。

https://reactrouter.com/en/main/start/overview

```js:App.tsx
// Configure nested routes with JSX
createBrowserRouter(
  createRoutesFromElements(
    <Route path="/" element={<Root />}>
      <Route path="contact" element={<Contact />} />
      <Route
        path="dashboard"
        element={<Dashboard />}
        loader={({ request }) =>
          fetch("/api/dashboard.json", {
            signal: request.signal,
          })
        }
      />
      <Route element={<AuthLayout />}>
        <Route
          path="login"
          element={<Login />}
          loader={redirectIfUser}
        />
        <Route path="logout" />
      </Route>
    </Route>
  )
);
```
##### `<Route path="dashboard" element={<Dashboard />} loader={({ request }) => fetch("/api/dashboard.json", {signal: request.signal})} />`

ルートが `/dashboard` であることを示しています。`loader`は、このルートが表示される前に非同期にデータを取得するための関数を定義します。`fetch`メソッドにて、非同期で外部のリソースを取得しています。

##### `<Route element={<AuthLayout />}>`

認証が必要なすべてのルートをラップするためのものです。

##### `<Route path="login" element={<Login />} loader={redirectIfUser} />`

最後に、2行目で作成したルートを`createBrowserRouter`に渡してルーターオブジェクトを作成しています。
AWS認定資格SAP-C02とDOP-C02取得したので勉強したことをまとめた

# はじめに
**AWS認定資格**

Solutions Architect - Professional SAP-C02 `(2022/12/27)`
DevOps Engineer - Professional DOP-C02 `(2023/03/29)`

この2つの資格を無事、取得できたのでアウトプットとして残していきます。

## 取得済みの資格
- **AWS**
  - Solutions Architect Associate
  - Developer Associate
  - SysOps Administrator Associate
- **GCP**
  - Associate Cloud Engineer

## 実務経験
業務ではAWSやAzureなどを触っていて、サーバレス系が多いです。

# SAP-C02 について

### 参考書2冊
AWS認定ソリューションアーキテクト-プロフェッショナル ~試験特性から導き出した演習問題と詳細解説

https://www.amazon.co.jp/dp/4865942483/

AWS認定資格試験テキスト&問題集 AWS認定ソリューションアーキテクト - プロフェッショナル

https://www.amazon.co.jp/dp/4815609063/

:::note warn
買うなら紙の本がお勧めです！
電子だと問題集を解くときにページの移動でしんどくなります。
:::

1冊だけで十分な気もしますが、心配性なので2冊買いました。
2冊を勉強するメリットとして、カバー範囲が若干異なり知識が補完できる点や、
どちらにも書かれている内容が試験に重要であることが分かる点、
片方で理解が曖昧な部分がもう片方で理解できる点が挙げられます。

（大体この本の受け売りです。）

https://www.amazon.co.jp/dp/B0BF469YLK/

# DOP-C02について

### Udemy
AWS Certified DevOps Engineer Professional 2023 - Hands On!

https://www.udemy.com/course/aws-certified-devops-engineer-professional-hands-on/

参考書が見つからなかったのでUdemyのハンズオン形式で勉強しました。
時間はかかりますが、実際に操作しながら学習できるため、理解が早く効率が良いです。
英語が苦手な自分でも、Udemyの翻訳機能で何とか対応できました。

### 公式の模擬問題集

https://aws.amazon.com/jp/training/digital/

新試験に対応した20問の模擬問題集をやりました。
可能であればやっておきましょう。

# 問題集について

問題集を解くときに以下の点を心がけると良さそうです。
- 最低でも300問を3週繰り返し解く（[忘却曲線](https://keiei-shinri.or.jp/word/%E3%82%A8%E3%83%93%E3%83%B3%E3%82%B0%E3%83%8F%E3%82%A6%E3%82%B9%E3%81%AE%E5%BF%98%E5%8D%B4%E6%9B%B2%E7%B7%9A/#:~:text=%E3%82%A8%E3%83%93%E3%83%B3%E3%82%B0%E3%83%8F%E3%82%A6%E3%82%B9%E3%81%AE%E5%BF%98%E5%8D%B4%E6%9B%B2%E7%B7%9A%E3%81%A8,%E5%BF%98%E3%82%8C%E3%81%A6%E3%81%97%E3%81%BE%E3%81%86%E3%80%8D%E3%82%82%E3%81%AE%E3%81%A7%E3%81%99%E3%80%82)を意識して、同じ問題を繰り返し解く）
- 理解が浅いサービスがあれば、BlackBeltやドキュメント、解説サイトを参照する
- わからない単語があれば、きちんと調べる
- 解説があれば、理解できるまで読み込む
- 間違った解答の解説も、なぜ間違いなのかを理解する
- 問題文を読んだらある程度解答を推測できるようになっておく

プロフェッショナルレベルになると問題自体の難しさやわからない部分を調べていると、
たとえば15問解くだけでも1時間掛かったりしますが、めげずに頑張りましょう。

# 試験について

自分は問題を解くとき以下を意識しています。

- 問題文を読んで「コストを重視」しているのかなど設問で求められているものを考える
- わからないときは消去法で「ないな」と思うものを選択肢から消していく
- 基本的にはAWSのサービスを上手く活用しているものを選択する
- 最終的にはこうだったら楽だなとかいいなという願望で選択する


リラックスして集中して受けられるように準備をすることが大事だと思っています。
自分は本番で体力を残すために当日は問題集は解かないようにしています！

あと、あまり関係ないですが自分は試験前にチルアウト飲んでます。

https://butfirstchillout.com/

:::note alert
トイレには事前に行っておきましょう。
:::

# さいごに
これから試験に挑戦しようと考えている人の役に立てれば嬉しいです。
どちらも試験の内容が更新されたあとに取得しているので、おそらく役立つはずです！

試験合格を目指して頑張ってください！
順番付きリストの数字を四角で囲う

# コード
自分用としてコードを残しときます。
くそ投稿でごめんね。

```html:index
<ol>
    <li>テスト１</li>
    <li>テスト２</li>
</ol>
```

```css:css
ol {
    list-style:none;
    counter-reset: count;
    padding:0;
    
}

li::before {
    content: counter(count);
    counter-increment: count;
    display: inline-block;
    width: 1.2em;
    height: 1.2em;
    line-height: 1.2em;
    text-align: center;
    border-radius: 4px;
    margin-right: 0.5em;
    font-size: 20px;
    color: white;
    background-color: rgb(50, 50, 50);
    margin-bottom: 10px;
}
```

下のような感じの表示になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3331076/e1f11e0c-7d68-5412-016e-d3faa4bc9dd9.png)
クラウドコンピューティングの仕組み

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92345/822aeb36-5fc5-47d3-371b-e0707827c27e.png)

クラウドコンピューティングには、オフサイトのデータセンターと、そこにアクセスするためのインターネット接続という2つの共通要素があります。オフサイトのデータセンターは、企業が所有・維持する場合と、Amazon Web Services（AWS）、Microsoft Azure、Google Cloud Platform（GCP）などのサードパーティーのクラウドプロバイダーが所有・維持する場合がある。

これらのデータセンター内のサーバーリソースはプールされ、仮想サービスをホストする準備が整った非常に大規模なプラットフォームが構築されます。クラウドコンピューティングモデルの種類によって、ユーザーがサービスのメンテナンスやインフラ管理をどの程度必要とするかが決まります。

しかし、これらにはすべて同じ共通点があります： サービスは使用量に応じた課金方式で、多くの場合、月単位で課金されます。
また、このような大規模なリソースのプールは、需要の増加に応じてリソースのスケールアウトとアップを可能にし、需要が減少するとスケールインとダウンを可能にする、高い弾力性を持つように構成できることを意味し、コストを下げることができます。

使った分だけ支払う
ストレージ容量や処理能力の増加など、需要の種類は変化しますが、これらのサービスはこれに適応することができます。このようなプールが用意され、待機しているため、追加のリソースのプロビジョニングがオンプレミスのソリューションよりも迅速かつ容易であることも意味します。

このようにリソースをオンデマンドで利用できるため、クラウドコンピューティングのニーズの変化に応じて、ほぼ無限のスケーラビリティと柔軟性を提供します。

仮想化とクラウドコンピューティングが提供する物理的なハードウェア、インフラ、ソフトウェアの利点だけでなく、全体的なモニタリングの利点もあります。例えば、セキュリティ基準やコンプライアンスはクラウドプロバイダーが管理するため、セキュリティ問題を常に監視する必要がありません。

災害時には、より優れたデータ復旧も用意されています。クラウドプロバイダーは独自のデータ復旧プランを用意しており、オンプレミスと比較してより迅速かつ容易にデータを復旧できる可能性があります。

クラウドコンピューティングに関するもっと読む：
https://miichisoft.com/what-is-cloud-computing-benefits-and-how-to-execute-the-strategy/

Website: https://miichisoft.com/
まだChatGPT使ってるの？開発者向けAI検索エンジン phind

## Phindとは

[Phind](https://www.phind.com/)とは簡潔に言うと、開発者向けのAI検索エンジンです。
一応Phindとは何か、 https://www.phind.com/about より以下引用します。

> Phind is a search engine that simply tells users what the answer is. Optimized for developers and technical questions, Phind instantly answers questions with detailed explanations and relevant code snippets from the web.
> Phind is powered by large AI language models. Unlike some other AI assistants, Phind pulls information from the internet and is always up to date. It's smart enough to generate answers based on information from multiple sources. With Phind, finding information is as seamless and informative as talking to a friend.
>
> --- 日本語訳 ---
>[Phind](https://www.phind.com/
)は、答えが何であるかをシンプルにユーザーに伝える検索エンジンです。開発者や技術的な質問に最適化されたPhindは、詳細な説明とウェブからの関連するコードスニペットで即座に質問に答えます。
>Phindは、大規模なAI言語モデルを搭載しています。他のいくつかのAIアシスタントとは異なり、Phindはインターネットから情報を引き出し、常に最新の状態にしています。複数のソースからの情報に基づいて答えを生成するほど賢いのです。Phindを使えば、友だちと話すのと同じように、シームレスで有益な情報を見つけることができます。


説明を見るより実際に使ってみるとその凄さがわかると思うので、
是非すぐに触ってみてください！！


## ChatGPTとはどこが違う？
ChatGPTとの違いを確認しつつ、phindの良い点と良くない点を整理します。
（あくまで個人的な感想です）

### phindのgood
- ログイン不要
    - ChatGPTのログインやあのロボットでない確認に一手間かかるのが何気に面倒です
- 可読性が高い
    - 下にあるスクショ参照
- 出典元のソースを出してくれる
    - 情報の信頼性が高い、根拠を探しに行きやすい
- 新しい情報を提供してくれる
    - ChatGPTは2021年までの学習データに基づいているのでここは大きな違いになりそうです
- 質問をしたURLを共有すればそのまま同じ回答結果を共有できる
    - 他の人に共有する時にいちいちスクショやコピペしなくてもいい
    - これは翻訳アプリもChatGPTも同じくですが、実務で使用するのであれば**情報漏洩に注意**しましょう

---
[2023/11/4追記]
なんと、Phindが**コーディング能力でOpenAIのGPT-4を上回った**ようです。
開発という面ではますますChatGPTより優位に立つようになったのではないでしょうか。

https://gigazine.net/news/20231102-phind-gpt-4/

---

実際の画面はこんな感じです。
脚注をつけてくれて、横にソースの記事が並んでいます。
めちゃ良くないですか？

~~[Railsで非同期処理を行なっているActiveJobからsend_dataを使う]
(https://www.phind.com/search?cache=857a560f-82c7-4f62-9782-7d2e827d8c35&init=true)（※phindへ飛びます）~~
（※2023/10/25時点で確認したらurl使えなくなっていました。。）

![スクリーンショット 2023-04-14 19.20.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2259490/389647cb-48d8-eec1-dbe7-1d0823e298aa.png)


### phindのnot good
- まだ日本語に弱そう？
    - 日本語で質問してもちょくちょく英語で回答が返ってくる
    - [2023/11/4追記]これは執筆当初よりかなり改善された感覚があります。
- Enterで検索が実行されてしまうので使いづらい
    - 改行する時はShift+Enterでできます、Discord方式ですね（個人的に嫌いです。笑）
- URLの共有できる期間が不明
    - 共有しやすいのは良いが、URLがいつどのタイミングで失効するのか不明
    - [2023/11/4追記]正確な期間は不明ですが1年とかは持たないようです。半年ほどで上に添付したurlは失効していました。

## まとめ
使ってみたらわかると思うのですが、
ソースがすぐにわかるのはめちゃくちゃありがたいですね。

可読性もいいと思いますし、
実装の調査をしていて後からあの回答見返したい！となった時にURLを残しておけるので、
一定の期間だけとはいえURL共有できるのはかなり嬉しいポイントです。

ChatGPTしか使われてこなかったエンジニアの方は、
とりあえず一度は触ってみることをお勧めいたします。

## 最後に
[ChatGPTを実務使う上で注意すべきこと](https://qiita.com/miu-P/items/8bff9e6a3b2ad38de4ad)
という記事を以前書きましたので、こちらも読んでいただけると嬉しいです。

## 参考記事
https://www.kyoukasho.net/entry/phind

https://qiita.com/ProjectEuropa/items/42d7da0ac58cecc93fb0

https://qiita.com/ysv/items/b1db6c25656fafdb983a
Rails _pathと_urlの使い分け

`_path`はルートURL以下の文字列を返す
```
root_path -> '/'
```
`_url`は完全なURLの文字列を返す
```
'https://www.example.com/'
```
基本的には`_path`を使い、リダイレクトの場合のみ`_url`を使うとよい
これは、HTTPの標準としてリダイレクトのときには完全なURLが要求されるから。ただしほとんどのブラウザでは、どちらの方法でも動作する。

### 参考
* [第5章 レイアウトを作成する - Railsチュートリアル](https://railstutorial.jp/chapters/filling_in_the_layout?version=7.0#sec-users_controller)
サクラエディタで半角などのスペースをわかりやすくする方法

## ツールバーの「設定」
→O
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2703054/27457a12-94c5-e1b2-1897-090a163dd1a3.png)


## タイプ別設定を選択
→ctrl　5
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2703054/d182dd80-463a-d96a-abc3-39690629ccd2.png)


## カラータブを選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2703054/7d04e296-ab1e-fe37-4a68-c5168a6cf964.png)


## 半角空白を選択

色分け表示にチェック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2703054/5a1a9ffc-b44d-1ce3-93f8-2425a328a919.png)

OKを押したら終わり


対策
CSVとかで余計な空白が入っていても気づかなかった
これで気づくことができる
下にスクロールすると上に逃げ、上にスクロールすると戻ってくるヘッダ

多くのサイトで見られる邪魔にならないヘッダです。
スクロールに応じてhiddenクラスを追加したり消したりして実装します。

# JavaScript

``` javascript:JavaScript
const header = document.querySelector('header');
let prevY = window.pageYOffset; // 前回のスクロール位置を初期化

window.addEventListener('scroll', () => {
  const currentY = window.pageYOffset; // 現在のスクロール位置を取得
  if (currentY < prevY) { // 上にスクロールしている場合
    header.classList.remove('hidden'); // hiddenクラスを削除して表示する
  } else { // 下にスクロールしている場合
  if (currentY > 0) { //Safariなどのバウンススクロール対策
      header.classList.add('hidden'); // hiddenクラスを追加して非表示にする
    }
  }
  prevY = currentY; // 前回のスクロール位置を更新
});
```

# CSS
```css:css
header {
  width: 100%;
  height: 80px;
  position: fixed;
  z-index: 10;
  transition: transform 0.3s 0.3s; /* アニメーションの設定 */
}

header.hidden {
  transform: translateY(-80px); /* ヘッダの高さだけ上に移動 */
}
```

# デモはこちら！

<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="GRYoLpY" data-user="sogawa-BitStar" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/sogawa-BitStar/pen/GRYoLpY">
  下にスクロールすると上に逃げ、上にスクロールすると戻ってくるヘッダ</a> by sogawa-BitStar (<a href="https://codepen.io/sogawa-BitStar">@sogawa-BitStar</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>
Azure IoT Hub で受信したテレメトリデータを IoT Explorer で確認する方法

Azure Digital Twins の MS Learn 学習モジュールを試していたところ、デバイスシミュレーターから Azure IoT Hub へデータを送信する箇所があり、Azure Portal の IoT Hub リソースページで確認できるかと思っていたら出来なかった。Azure IoT Explorer (Preview) というツールが GitHub で公開されており、このツールを使えばテレメトリーデータの受信内容を確認できるらしいので、早速試してみたいと思います。

※ Azure IoT Explorer は 2023/4/14 現在、v0.15.8 プレビュー版として提供されています。

# 手順
1. [Azure IoT Explorer (GitHub) の リリースページ ](https://github.com/Azure/azure-iot-explorer/releases) から .msi ファイルをダウンロード & インストールする  
2. Azure IoT Explorer (Preview) を起動する
3. Add Connection ボタンをクリックする

<img width="700" alt="image.png (152.8 kB)" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180432/900aedf4-bc66-0368-957b-66d454672efb.png">

4. Azure Portal で IoT Hub リソースページを開き [セキュリティ設定] > [共有アクセスポリシー] から **iothubowner** を選択する

<img width="700" alt="image.png (231.5 kB)" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180432/977d7dd6-3121-7042-3d9d-438697ff5ceb.png">


5. プライマリ接続文字列をコピーします。

<img width="392.64" alt="image.png (138.4 kB)" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180432/b7a08438-d33f-e828-8055-7dc003bf6aa4.png">


6. Azure IoT Explorer に戻り、プライマリ接続文字列を貼り付けたあと、[SAVE] ボタンを押します。

<img width="257.28" alt="image.png (35.0 kB)" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180432/a6640b3d-5821-3995-fad2-fee84701a29f.png">

7. これまでの手順が正しく実施されていれば、IoT Hub のデバイス一覧が表示されます。  
試しにデバイスページに遷移してみます。

<img width="959.9999999999999" alt="image.png (81.5 kB)" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180432/9b6b3833-4635-455d-2373-cc5965b07296.png">


8. デバイスの認証情報等が表示されました。その他、デバイスツインやテレメトリーのタブもあるので、  
今回の目的である [Telemetry] タブを選択します。

<img width="960.4799999999999" alt="image.png (99.9 kB)" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180432/3f3fe2d3-dd1e-770d-264b-7f975ec2d938.png">


9. テレメトリーデータの受信を行うために [Start] ボタンをクリックします。  
(もちろん、Azure IoT Hub にデータを送信していないので、このままの状態だと何も表示されません。)

<img width="959.9999999999999" alt="image.png (177.2 kB)" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180432/bce2ca96-bf32-e1ac-d71d-c8e087d58454.png">


10. azure cloud shell を開き、シミュレーションデータを送信するコマンドを実行します。  
``az iot device simulate --device-id T105 --login <プライマリ接続文字列>``

11. Azure IoT Explorer で受信データを確認する。

<img width="728.64" alt="image.png (162.2 kB)" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180432/16c3f8e0-d406-78e3-aa84-23378778bea5.png">


無事データが受信されていることを確認できました。
curl コマンドのオプション①


**curlコマンドのオプション'-X', '-H', '-o' について**

>REST　APIのアクセスに、PostamanなどREST　Clientを使用するほか、curlを使用してアクセスできるが、ちっとも覚えられない、そして使えないのでまとめる

きっかけのよくわかんなかったcurlコマンドは以下
```ruby:
curl -X GET -H 'Authorization: Bearer access_token' -o 'myfile.zip' https://example.com/ic/api/endpoint/resource
```

>**そもそもcurlコマンドとは**
様々な通信プロトコルでデータの送受信を行うことができるコマンド
よく使われるのは、Webサイト等へのHTTPリクエスト
色々なオプションを指定することで、データ取得時の条件、取得情報を変更できる
　

**ーX (--request)**
HTTP　メソッドのを指定（GET,POSTなど）
デフォルト：GET　
PUTなどを使用する際は、特に指定とか必要そう。。。
```
curl -X GET https://example.com/ic/api/endpoint/resource
```

**-H (--header)**
HTTPリクエストのヘッダーなどの情報を渡せる
-H "Content-Type:application/json" とか、、、
```
curl -H 'Authorization: Bearer ***' -X POST
https://example.com/ic/api/endpoint/resource
```

**-o <file>(--output <file>) path**
ローカル・マシン上のレスポンス出力を指定
エクスポート操作とレスポンスをファイルへ保存するのに使用
```
curl -X GET -o 'myfile.zip' https://example.com/ic/api/endpoint/resource
```
>この場合、カレントディレクトリに'myfile.zip'でレスポンスが保存される
-o '/Users/USER_NAME/Downloads/myfile.zip'など、pathごと指定してなくて行方不明になったよ。

**☆まとめ☆**
以下のcurlコマンドは、
HTTP GETメソッドで取得したレスポンスをmyfile.zipとして保存している、らしい！
※そのアクセスの認証はBearer access_token
```ruby:
curl -X GET -H 'Authorization: Bearer access_token' -o 'myfile.zip' https://example.com/ic/api/endpoint/resource
```





:::note 
以下、おまけ
:::


**curlのバージョンの確認**

```ruby:
curl -version
'curl 7.79.1 (x86_64-apple-darwin21.0) libcurl/7.79.1 (SecureTransport) LibreSSL/3.3.6 zlib/1.2.11 nghttp2/1.45.1
Release-Date: 2021-09-22
Protocols: dict file ftp ftps gopher gophers http https imap imaps ldap ldaps mqtt pop3 pop3s rtsp smb smbs smtp smtps telnet tftp 
Features: alt-svc AsynchDNS GSS-API HSTS HTTP2 HTTPS-proxy IPv6 Kerberos Largefile libz MultiSSL NTLM NTLM_WB SPNEGO SSL UnixSockets'
```
>そもそも、curlがMacで使えるか忘れちゃうんだよね。から確認。



とりあえずの **-h（--help）** してみる
>簡易ヘルプが参照できるオプション
にしても、めっちゃ出てきた。。。
```ruby:
curl -h
'Usage: curl [options...] <url>
 -d, --data <data>   HTTP POST data
 -f, --fail          Fail silently (no output at all) on HTTP errors
 -h, --help <category>  Get help for commands
 -i, --include       Include protocol response headers in the output
 -o, --output <file>  Write to file instead of stdout
 -O, --remote-name   Write output to a file named as the remote file
 -s, --silent        Silent mode
 -T, --upload-file <file>  Transfer local FILE to destination
 -u, --user <user:password>  Server user and password
 -A, --user-agent <name>  Send User-Agent <name> to server
 -v, --verbose       Make the operation more talkative
 -V, --version       Show version number and quit'
Javac install



# 初めに

Mac上のMikatypeですが，少し深くなりそうです．Javaというソフトがdefaultで入ってないから．

Javaの開発環境(JDK)を入れる必要があります．それほどDLに時間がかかるようではないので，手順を示します．


# 手順

[Javaのホームページ](http://www.java.com) へ行きます．

この少し下にある"Java SE Development Kit"を選びます．

![dm20_java_home.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151211/29f0e870-5fa8-03b5-a7f0-bc8985e8ae89.png)

このタブのmacOSを選びます．その"Arm 64 DMG Installer"に対応する右側のDonwload リンクを選びます．

![dm21_java_mac_dmg_select.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151211/29980669-71a8-94c6-30ea-9d03bcc06a07.png)

終わったら，画面右下のダウンロードショートカットを押すと，中身がポップアップするので，そのjre-**\***-macosx-s64\_bin.dmgを選んで，ボタンを離します．

![dm22_java_jdk-20_popups.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151211/d658d128-b084-02ca-9b45-8e710c3ea612.png)

開いてもいいかという確認ウィンドウが出るかもしれません．

![dm231_java_installer_dd.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151211/94ca8c44-3cc0-3b60-40d6-c0573cc42c39.png)

JDK 20.pkgのパッケージ(小包)をダブルクリックし(開き)ます．

![dm23_java_jdk_20_installer.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151211/dce97630-af84-3a60-7b09-0b7450c7f25e.png)

多分，ロゼッタを入れる必要があるので，インストールボタンを押します．

![dm24_java_rosetta.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151211/d4afd494-b18e-3bbe-7616-67dea88938e5.png)

この後，何度かパスワードを聞いてきますがその度に入れます．

![dm25_java_password.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151211/f76afb54-b34d-01cf-1b3d-b9c16cece937.png)

インストール確認がありますが，そのままインストールします．「信頼できる？」という警告が出てきますが，開きます．

![dm27_java_jdk_installer.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151211/0df1d6c2-4418-1346-b368-26c0edd8a17a.png)

これでJavac(Javaのcompilerだから)が使えるようになりました．



------
 - **source** ~/Desktop/lecture_24s/comp_a24/d1_6_learning/d2_mikatype/d22_java_on_mac.org
[WSL・Docker Compose]別々のStacks同士で通信を行う方法[Docker Network]

## 概要
環境：Windows11 , WSL2 , Laravel9 , PHP8.1, nginx, mysql

![Q用.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/990851/f9902bed-3001-6549-828f-ffc93836f8ed.jpeg)



開発環境で、二つのサービスはそれぞれ[WSL]内に別の`docker compose`を使って作成されている。

きなこStacks内のPHPコンテナから、あんこStacksのDBコンテナを見たい！と思った時。
ネットサーバーにつなぐ時と同じように、`connection`を変えればいいものとばかり思っていたが、繋がらなかった。

```env:NG.env
HOST=localhost
PORT=7002
```

どうやらDockerコンテナ同士が通信するには**Docker Network**が必要だったよう。
・ 通常、コンテナどうしは自由に通信できるわけでは無い。
・ `docker compose`で`Stacks`を形成すると、自動的に`Network`が作成されることで、その`Stacks`内での通信が可能になっていた(...defaultのような名前のもの)。
・ 別Stacks同士で通信を行うには、この`Docker Network`を自分で作成しなければならない。

## 解決方法

### 1. 共有したいDBがある方の`docker-compose.yml`を修正する。

```yml:あんこディレクトリ＞docker-compose.yml
//...
services:
    db:
        networks:
            - default
            - omochi-shared-network

//...
networks:
    omochi-shared-network:
        internal: false
        name: omochi_shared_network
```


これで`Docker Network`が作成され、そのネットワークにあんこStacksの`db`コンテナが接続される。


### 2. 別StacksDBにアクセスしたい側の`docker-compose.yml`を修正する。

```yml:きなこディレクトリ＞docker-compose.yml
//...
services:
    php:
        networks:
            - default
            - omochi-shared-network
//...
networks:
    omochi-shared-network:
        external: false
        name: omochi_shared_network

```

これで`Docker Network`を通して、きなこStacksからあんこStacksの`db`コンテナへのアクセスが可能となる。

### 3. `env`のホスト設定
Laravelの場合、この方法でDBにアクセスするときは
```env:きなこPHP.env
HOST=dbコンテナ名
//例　HOST=あんこ-db-1
```
にすることでアクセスが可能になる。

## 解説(もどき)

オプションの`name`は作成するサービス名を指定できる。（指定しないとディレクトリの名前がくっついて長くなる。）
`internal`と`external`については<a href="https://www.timedia.co.jp/tech/20220628-tech/">こちら</a>の記事が詳しい。**というか全部この記事でよい。**

::: note warn
注意点
コンテナ起動時に、指定された`Docker Network`が見つからない場合、コンテナが起動できない。
起動順を気を付ける必要がある。
:::

なお、この記事にたどり着くまでにWSL内のコンテナがぐちゃぐちゃになっている場合、`docker compose up -d --build`だけではうまくいかないことがある。
その場合は`docker compose up -d --build --force-recreate`で治る場合がある。

そして、Laravelの`env`もいじりまくっている場合は
```
php artisan config:clear
php artisan cache:clear
#https://qiita.com/Ping/items/10ada8d069e13d729701
```
キャッシュの削除も忘れずに。これで30分消費した。

駄文失礼しました。ちなみに餅はきなこ派です。


参考
https://www.timedia.co.jp/tech/20220628-tech/
https://tech.anti-pattern.co.jp/docker-compose/
https://matsu.teraren.com/blog/2022/05/28/error-response-from-daemon-network-not-found/
https://knowledge.sakura.ad.jp/16082/
https://qiita.com/YuitoSato/items/4a4b46f5670b45739a37
ふつうのコンパイラをつくろう

# java11
    #sudo apt install default-jdk
    sudo apt install openjdk-11-jdk-headless
※openjdk version "11.0.18" 2023-01-17
# ant
    sudo apt install ant
# javaCC
    sudo apt install javacc

# クロスコンパイル用のライブラリをインストール
    sudo apt install gcc-multilib

# Parser.jjを修正
importをコメントアウト（java8以上でParameterが名前重複）
//import java.lang.reflect.*;

# GNULinker.javaを修正
LINKER = "/usr/bin/ld";
↓
LINKER = "gcc";

# リンカのパラメタ追加
        cmd.add("-m32");

# ライブラリ追加をコメントアウト
  //        if (! opts.noStartFiles) {
  //            cmd.add(opts.generatingPIE
  //                        ? C_RUNTIME_START_PIE
  //                        : C_RUNTIME_START);
  //            cmd.add(C_RUNTIME_INIT);
  //        }

# クリーン
    make clean

# ビルド
    make

# テスト
    make test
※まだ３つほどエラーが出る
06_variables.........................................................................................................................................................shunit: <private> expected

29_import....shunit[../bin/cbc vardecl.cb]: status 0 expected but was: 1
..shunit[../bin/cbc -fPIC vardecl.cb]: status 0 expected but was: 1
週一でPython勉強会やってみる②

前回の続き

https://qiita.com/Waddy675/items/5529cf3ee33abff09705

今回からエクセルの操作をする予定でしたが、そもそも書き方が分かってないということもあり基礎部分を勉強しました。（先やれよ！）

以下箇条書き

## Pythonの概要
Pythonはシンプルな言語で分かりやすい文法とのこと。（個人的には｛｝ないとスコープ見にくくて嫌い
オブジェクト指向を採用しており、整数や文字列もすべてオブジェクトになっている。
構文ブロックを表現するのに「**インデント**」を採用している。

## よく使う書き方
画面への出力は**print('hoge')**
1行コメントは **#** 。
複数行コメントはシングルクォートかダブルクォートを3つ使う。 **'''hoge'''** or **"""fuga"""** 
コメントではなくコードを1行で各場合は **;** で区切る。（基本は1行ずつ書く？）
逆に複数行で書きたい場合は行末に**バックスラッシュ**を書く。

## 計算式と演算子
四則演算は他の言語と差異はない。
足し算：+
引き算：-
掛け算：*
割り算：/
割り算商：//
割り算余り：%
累乗：**
初めて見たのが **//** で割り算の商を小数点以下切り捨てたものにする演算子。
例えば123.8//4=30.0(普通の割り算(/)だと30.95)
他の言語だと//はコメントアウトなのでそりゃ見ないよな・・・と。（どこで使うんだろ？

## 変数と代入
hoge = 100という感じで左に変数名、右に値で宣言できる。
驚くことに「ほげ = 100」と変数名をひらがなでも宣言できた。（使うことはないだろうが。
変数名の最初に数字を入れたり、予約語は宣言できない。
変数名は小文字+_で宣言することが一般的の様。キャメルケースではなくスネークケースみたい。



これだけでも結構違うなーという印象。
新しい言語を学ぶって楽しいね～
Pythonで挿入ソートを実装してみた

# 概要
Pythonで挿入ソートを実装してみました。以下のページを参考にしました。
http://www1.cts.ne.jp/~clab/hsample/Sort/Sort2.html

# ソースコード
上記のC言語のfor文をwhile文に書き換えました。あとはいっしょです。

```insertion_sort.py
import random

data = {}
data2 = {}
temp = {}
NUM = 10
i = 0
while i < NUM:
    data[i] = random.random()
    i = i + 1

#show
def show_data():
    print("==>> show data")
    i = 0
    while i < NUM:
        print ( str(i) + ":" + str(data[i]) )
        i = i + 1

def show_data2():
    print("==>> show data2")
    i = 0
    while i < NUM:
        print ( str(i) + ":" + str(data2[i]) )
        i = i + 1

#copy
def copy_data_to_data2():
    print("==>> copy data to data2")
    i = 0
    while i < NUM:
        data2[i] = data[i]
        i = i + 1

#insertion_sort
def insertion_sort(array, n):
    print("==>> insertion sort")
    i = 0
    j = 0
    temp = 0
    i = 1
    while i < n:
        temp = array[i]
        j = i
        while j > 0 and array[j-1] > temp:
            array[j] = array[j - 1]
            j = j - 1
        array[j] = temp
        i = i + 1

copy_data_to_data2()
show_data2()
insertion_sort(data2, NUM)
show_data2()
```
# 実行結果
実行できました。アルゴリズムは正常に動いています。

```
$ python insertion_sort.py 
==>> copy data to data2
==>> show data2
0:0.869473256419
1:0.257731491847
2:0.913115196463
3:0.201501660522
4:0.00858543758708
5:0.587123873954
6:0.23756328504
7:0.524541808381
8:0.776380856197
9:0.00613001602015
==>> insertion sort
==>> show data2
0:0.00613001602015
1:0.00858543758708
2:0.201501660522
3:0.23756328504
4:0.257731491847
5:0.524541808381
6:0.587123873954
7:0.776380856197
8:0.869473256419
9:0.913115196463
```

何かの役に立てばと。
ローカルスコープとグローバルスコープについて

ローカルスコープとグローバルスコープは、プログラミングにおいて変数や関数がどの範囲で有効かを定義する概念です。

ローカルスコープは、関数内で定義された変数や関数が有効な範囲を指します。つまり、その関数内でしかその変数や関数にアクセスできないということです。ローカルスコープ内で定義された変数は、関数の実行が終了すると同時に破棄されます。

一方、グローバルスコープは、プログラム全体で定義された変数や関数が有効な範囲を指します。つまり、どの関数からでもアクセスできるということです。グローバルスコープで定義された変数は、プログラムが終了するまで有効です。
ローカルスコープとグローバルスコープは、プログラミングにおいて非常に重要な概念であり、変数のスコープを正しく理解することは、プログラムのバグを防ぐ上で重要です。

# JavaScript・Ruby・PHPなどのプログラミング言語での扱いについて


- JavaScript
JavaScriptでは、letやconstを使って変数を宣言することができます。letで宣言された変数はブロックスコープを持ち、constで宣言された変数は再代入ができないため、定数として扱われます。

```javascript
function test() { let x = 1; // ローカルスコープ if (true) { let x = 2; // ブロックスコープ console.log(x); // 2 } console.log(x); // 1 } test(); 
```
上記の例では、test関数内でletで宣言された変数xはローカルスコープを持ち、if文内で再度letで宣言された変数xはブロックスコープを持ちます。console.logでの出力結果から、それぞれのスコープが異なっていることがわかります。
- Ruby
Rubyでは、ローカルスコープとグローバルスコープがあります。変数名の先頭に$を付けることで、グローバルスコープの変数を宣言することができます。
```ruby
def test x = 1 # ローカルスコープ if true x = 2 # ローカルスコープ $y = 3 # グローバルスコープ puts x # 2 puts $y # 3 end puts x # 2 end test puts $y # 3
 ```
上記の例では、testメソッド内でxという変数がローカルスコープを持ち、if文内で再度xという変数が宣言された場合でも、ローカルスコープ内のxと同じ変数として扱われます。一方で、$yという変数はグローバルスコープを持ち、どこからでも参照することができます。
- PHP
PHPでも、ローカルスコープとグローバルスコープがあります。グローバルスコープの変数を宣言するためには、変数名の先頭に$GLOBALSを付けます。

```php
function test() { $x = 1; // ローカルスコープ if (true) { $x = 2; // ローカルスコープ $GLOBALS['y'] = 3; // グローバルスコープ echo $x; // 2 echo $GLOBALS['y']; // 3 } echo $x; // 2 } test(); echo $GLOBALS['y']; // 3 
```
上記の例では、test関数内で$xという変数がローカルスコープを持ち、if文内で再度$xという変数が宣言された場合でも、ローカルスコープ内の$xと同じ変数として扱われます。一方で、$GLOBALS['y']という変数はグローバルスコープを持ち、どこからでも参照することができます。最後に、グローバルスコープの変数$yの値をecho文で出力すると、3が表示されます。
SQL・Databesを基本からまとめてみた【入門】

## データベース(DB)とは？
- 検索や蓄積が容易にできるように整理された情報の集まり
- 全てのシステムがデータで取り扱っている
- データを取り扱う手段として、ほぼ全てのシステムが何らかのデータベースを使用
- データベースは複数テーブルの集合

## SQLとは?
- Structured Query Language(構造化問い合わせ言語)
- データベース、テーブル、行や列を扱うための言語をSQLと呼ぶ
- リレーショナル・データベース（RDB）に問い合わせできる
- データの取得、追加、更新、削除
- データベースやテーブルの作成、追加、削除
- 大文字・小文字の区別はない
- SQL文の最後は必ずセミコロンをつける『;』

## テーブル
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/939638/e2fe455b-c863-55ba-d45a-40c72036f9ac.png)

- 上記の表なようなものを『テーブル』といい、意味的なまとまりを持ったデータを整理・管理する
- テーブルにおける行を『レコード』、列を『カラム』、1つ1つのデータのことを『フィールド』という
- データベースで管理するデータは型を持ち、型はカラムごとに設定が可能で以下のようなものがある

整数型・・・INT、TINYIN、BIGINTなど
小数点数型・・・DOUBLE、FLOAT
文字列型・・・CHAR、VARCHAR
日時系・・・DATE、TIMESTAMPなど

- 型以外にカラムごとに設定できる代表的なもの

主キー（PRIMARY KEY）・・・データの整合性を守るための制約
NOT NULL・・・カラム内でNULL（データなし）を認めない


## データ型
- テーブルの各カラムには型がある
- データベースでは、テーブル作成をする時に、それぞれの列（カラム・フィールド）に指定した形式のデータしか、入力できないように設定する
- この時、指定するデータの形式を『データ型』という


## 代表的なデータ型

| 型 |   |  例 | 
| --- | ----------- | ------- |
| STRING型 |  文字列  |  名前、男性、音楽etc.. | 
| INTEGER型 | 小数点を含まない整数 | 1,12,50,120,1100 etc..  | 
| FLOAT型 | 小数点を含む整数 | 1.1,0.12 etc..  | 
| TIMESTAMP型 | 日時 | 2023-4-5 20:15 etc..  | 









## 参考サイト

[データベースの構造はどうなっているの？](https://xtech.nikkei.com/it/article/COLUMN/20130416/471169/)
[【SQL】未経験者もこれ一本でOK！MySQLで学ぶ「SQL」「データベース基礎」講座【プログラミング初心者向け】](https://www.udemy.com/course/uz-sql-kiso/learn/lecture/22245592#overview)
（忘備録）Linuxデスクトップにショートカットを作成する


# 忘備録
デスクトップにシェルスクリプトを実行するためのショートカットを作成する

# 作成手順
1. **シェルスクリプトを用意する**
   ```hello.sh
   #!/bin/bash
   echo 'Hello!!'
   ```

2. **シェルスクリプトのパーミッションを変更**
   ```terminal
   $ chmod 755 hello.sh
   ```


2. **ショートカットファイルを作成する**
:::note warn
デフォルトでショートカットは **/usr/share/allications/** 下に作成されているため，同一場所に作成しておくことを推奨
**※作成したファイルをデスクトップにコピーする**
:::
 
  ```SHORTCUT.Desktop
   [Desktop Entry]
    
    #アイコンの名前を指定
    Name=ICON-NAME
    
    #ターミナルを起動する（指定した方が良い）
    Terminal=true #true/false
    
    #起動するコマンドを絶対パスで記述
    Exec=/home/{USERNAME}/hoge/hello.sh

    #ショートカットのアイコンを絶対パスで記述（無くてOK）
    Icon=/usr/share/icons/Humanity/apps/64/access.svg
    
    #タイプを指定
    Type=Application
   ```

:::note info
拡張子は **.desktop** にする
:::


4\. **ショートカットのパーミッションを変更**
```terminal
$ chmod 755 SHORTCUT.Desktop
```

5\. **アイコンを右クリックして「起動を許可」**