OmniAICreator/Qiita-1.07M huggingface dataset:
AWS CloudShell でEC2へのログインが出来なくなった

# 課題
AWS CloudShell に鍵ファイルを置いて、EC2へログインを試したらエラーが出てログイン出来ない
```shell-session
[cloudshell-user@ip-x-x-x-x ~]$  ssh -i "hoge.pem" ec2-user@ec2-y-y-y-y.ap-northeast-1.compute.amazonaws.com
<省略>
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@         WARNING: UNPROTECTED PRIVATE KEY FILE!          @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions 0664 for 'hoge.pem' are too open.
It is required that your private key files are NOT accessible by others.
This private key will be ignored.
Load key "hoge.pem": bad permissions
Permission denied (publickey,gssapi-keyex,gssapi-with-mic).
[cloudshell-user@ip-x-x-x-x ~]$
```

# 課題の原因
hoge.pem の権限が 0644 と広い。
与える権限を変えて狭めてあげるとログイン出来る。

# 実装の流れ
1. AWS CloudShell で hoge.pem の権限を変更

# 手順1. AWS CloudShell で hoge.pem の権限を変更
```shell-session
[cloudshell-user@ip-x-x-x-x ~]$ ls -l
total 20
-rw-rw-r-- 1 cloudshell-user cloudshell-user 1675 Jan 25 06:41 hoge.pem
[cloudshell-user@ip-x-x-x-x ~]$
[cloudshell-user@ip-x-x-x-x ~]$ chmod 600 hoge.pem
[cloudshell-user@ip-x-x-x-x ~]$
[cloudshell-user@ip-x-x-x-x ~]$ ls -l
total 20
-rw------- 1 cloudshell-user cloudshell-user 1675 Jan 25 06:41 hoge.pem
[cloudshell-user@ip-x-x-x-x ~]$
```
# 実装後
ログインを試みた際にエラーは出なくなり、ログイン出来るようになる。
```shell-session
[cloudshell-user@ip-x-x-x-x ~]$ ssh -i "hoge.pem" ec2-user@ec2-y-y-y-y.ap-northeast-1.compute.amazonaws.com

       __|  __|_  )
       _|  (     /   Amazon Linux 2 AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-2/
8 package(s) needed for security, out of 9 available
Run "sudo yum update" to apply all updates.
[cloudshell-user@ip-x-x-x-x ~]$
```
【TypeScript】keyofとtypeofの使い方備忘録

# はじめに

先輩が書いたコードを眺めていると、**keyof**とか**typeof**を使ったコードがよく出てきます。
その度に「どういう使い方だっけ」って調べるのも面倒なのでまとめることにしました。

# keyofって何だ？

[サバイバルTypeScript](https://typescriptbook.jp/reference/type-reuse/keyof-type-operator)によると、**オブジェクト型からプロパティ名を型として返す演算子**と記載されています。

### いや、よくわからん

実際のコードを見てみましょう。

```typescript:例
type Person = {
  name: string,
};
type PersonKey = keyof Person;
// PersonKey = "name" となる
// PersonKey = "age" ← Error

type Book = {
  title: string,
  price: number,
  rating: number,
};
type BookKey = keyof Book;
// BookKey = "title" | "price" | "rating" のユニオン型となる
```

オブジェクトのプロパティ名を型として返す仕様になっています。
プロパティ名以外の値を代入しようとするとエラーとなります。

# typeofとはなんぞや

[サバイバルTypeScript](https://typescriptbook.jp/reference/values-types-variables/typeof-operator)によると、**値の型を調べることができる**と記載されています。

### どう使うんだろう

```typescript:例
typeof true; // boolean
typeof "aaa" // string

type Person = {
    name: string,
    age: number,
}

const person: Person = {
    name: "yamada",
    age: 20,
    birthday: "2000-01-01", // ← Error
}
```

型を調べて条件分岐等に使うこともあれば、オブジェクトに格納できるプロパティを制限する時にも使えそうですね🤔

# keyofとtypeofの合わせ技

keyofは型にしか使えず、変数には使えない。
typeofだと、オブジェクトのキーと値のセットで取得される。

変数かつオブジェクトのプロパティ名をユニオン型として定義したい場合に使います。

```typescript:例
const someObj = {
  hoge: 'HOGE',
  fuga: 'FUGA',
}

let obj: keyof typeof someObj; // obj = 'hoge' | 'fuga'
obj = 'hoge';


const Color = {
  red: "RED",
  green: "GREEN",
  blue: "BLUE",
} as const;

type Color = typeof Color[keyof typeof Color];
// Color = 'RED' | 'GREEN' | 'BLUE'
```

ちなみにas constは型アサーションと呼ばれるものです。

https://typescriptbook.jp/reference/values-types-variables/const-assertion

プロパティがreadonlyになるので、再代入ができなくなります。

# まとめ

型安全難しい。。
【個人開発】評価付きの思い出管理アプリをリリースしてみた

# はじめに
Expoの勉強を兼ねて思い出管理アプリを作成しました。
Expo（ReactNative）は日本語記事がかなり少ないのが難点ですが、Reactの知識があれば新しく勉強することはそこまで多くないです。
最低限の機能でリリースしましたが今後もアップデートを重ねていくので是非インストールして使ってみてください！！🙏

https://play.google.com/store/apps/details?id=com.nojitake.omoidemeisho

# どんなアプリ？
ログイン不要で画像にタイトル・点数・メモを付けて登録することができ、思い出に色を付けて管理することができます！
自分専用の旅行・観光アプリのような感じですね。行った場所に点数とタイトルを付けてアルバム管理するなどの使い方ができます！
<img width="200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/838672/fac2636c-252f-3990-3529-92961250889c.jpeg" />
また登録した内容は共有ボタンを押すことで画面のスクショを他ＳＮＳ等にあげることもできます。
登録した画像一覧は３つのレイアウトから選んで表示することができます。
<img width="200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/838672/dbde0647-619c-fcce-eaee-503db51d03e1.jpeg" /><img width="200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/838672/1d7b2a72-475a-fb19-7a64-e97923cf3cce.jpeg" /><img width="200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/838672/3b4bc744-8c81-982c-1f45-64c73cc1b870.jpeg" />

今はまだこのくらいの機能しかないのですが、これからアップデートを重ねて多機能にしていく予定です。
何卒インストールと感想の方をお願いいたします！！🙏

# Expoってどうなん？
個人的にはExpoは開発がしやすくてかなり好きです。なにより、Reactである程度開発できるのが一番嬉しい点ですね。
なのですが、ExpoもといReactNativeってReactの人気具合に比べて圧倒的に利用者が少ない気がするのですが気のせいでしょうか。。
Reactの知識である程度は書いていけると言っても、やはりExpo独自の仕様はあるのでポチポチググる訳ですが、日本語の記事がかなり少ない。。日本語しか理解できない私はDeeplに頼りきりで生きてました。

ｴｲｺﾞﾍﾞﾝｷｮｳｼﾅｲﾄ…

# 匿名認証について
このアプリはログイン操作が不要なのですが、内部的にはFirebase Authenticationの匿名認証なるものを使用しています。
以下匿名認証についての概要です
> Firebase で認証する一時的な匿名アカウントを、Firebase Authentication で作成して使用できます。一時的な匿名アカウントを使用すると、アプリに登録していないユーザーが、セキュリティ ルールで保護されているデータを使用できるようになります。

https://firebase.google.com/docs/auth/web/anonymous-auth?hl=ja

ドキュメント通りに進めていけば結構簡単に実装出来ました。既にご存じかもしれませんがお勧めです。
私は全く知らなくて、先輩に「ログインページの実装めんどいんすよねぇ～」と言ったら「匿名認証ええで」と教えてもらいそこで初めて知りました。。👶

# 今後の予定
まだまだ追加したい機能はあるので日々アップデートしていく予定です。
またインストールしてみてあったらいいなと思う機能やこりゃないと話にならんでぇ、、って機能がありましたらコメントかアプリのレビューなどでご教授いただけると嬉しいです！

# 最後に
最後まで読んでいただきありがとうございました！
是非アプリをインストールして遊んでやって下さい！！

https://play.google.com/store/apps/details?id=com.nojitake.omoidemeisho
Googleプロジェクト管理：プロダクトバックログ（PBL）

# はじめに

わたしが [Google プロジェクト管理:プロフェッショナル認定証で得られた素晴らしい体験][google]を、要点をまとめ小さく分割して、わかりやすく簡潔に紹介していきます。

興味があれば、ぜひ ***"Google プロジェクト管理:プロフェッショナル認定証"*** を受講してみてください。

[google]: https://qiita.com/mapami/items/317ae776a2268fd54c8f

https://jp.coursera.org/professional-certificates/google-project-management

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/1c9e3622-d11d-e6dd-1bb7-f12b3fef8845.png" width="800">

# プロダクトバックログの特徴

***<font color="MediumVioletRed">『プロダクトバックログは、チームが取り組む物事に関する単一の権威あるソースである』</font>***

プロダクトバックログには、3つの重要な特徴があります。

- プロダクトバックログは生きた人工物であり、***<font color="MediumBlue">いつでもバックログに項目が追加される</font>*** ことを意味する。プロダクトバックログは、プロジェクトのライフサイクル全体を通じて進化し、チームが次に何をすべきかを知るための中心的なガイドとなる。
- プロダクトバックログは、 ***<font color="MediumBlue">プロダクトオーナーが所有し、調整</font>*** します。
- プロダクトバックログは常に機能の ***<font color="MediumBlue">優先順位付けされたリスト</font>*** であることです。そのため、新しい情報や新しい機能があると、それらは重要な順にBacklogに追加されます。リストの一番上にあるものは、非常に具体的でよく定義されたものであり、曖昧なものはリストの一番下に残します。

プロダクトバックログは、製品のガイドであり、ロードマップであることを忘れないでください。これはスクラムの中心的な成果物であり、チームが取り組むべきすべての可能なアイデア、成果物、機能、またはタスクが捕捉される場所です。

# プロダクトバックログ作成のベストプラクティス

バックログは中心的なものなので、プロダクトバックログで作業する際には、いくつかのベストプラクティスと取得すべきデータの断片がある。

- ***<font color="MediumVioletRed">項目説明</font>***
- ***<font color="MediumVioletRed">価値</font>***
- ***<font color="MediumVioletRed">順序</font>***
- ***<font color="MediumVioletRed">見積もり</font>***

これらのベストプラクティスを念頭に置いて、サンプルバックログを構築する方法を説明します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/5d292f9e-b325-dfc7-db57-8b021dd2cc07.png" width="700">

### 項目説明

項目を説明するものです。項目説明を書くときは、プロダクトバックログの項目を追加するときに、詳細が奨励されるように、本当に ***<font color="MediumBlue">明確</font>*** にすることをお勧めします。

例えば、オフィスグリーンの新プロジェクト「Virtual Verde」では、次のような項目説明があります。「Virtual Verdeのクライアントとして、私はニューヨークのアパートで在宅勤務しながら、好きな野菜を栽培する予定です。」

この項目説明には、に ***<font color="MediumBlue">顧客の視点に立った行動や場所など、必要不可欠な詳細</font>*** が含まれています。これによって、開発チームはユーザーのニーズを満たすのに十分な情報を得ることができます。

### 価値

そのアイテムが顧客、チーム、あるいはユーザーにどれだけのビジネス価値をもたらすかを示すものです。どのように価値を示すかは、スクラムチームが一緒に選択すべきものです。私は、ドル記号を使って価値を設定するのが好きです。

| ドル記号  | ビジネス価値  | 
| :--- | :--- | 
|　$  | 低い | 
|　$$$ |高い  | 

### 順序

プロダクトバックログは常に優先順位をつけなければなりません。プロダクトオーナーは、このプロダクトバックログの項目は他の項目と比べてどれくらい重要なのか、と自問します。プロダクトバックログは、優先順位の高いものから低いものへと項目を並べる。このように項目を並べることで、チームはより効率的に活動することができます。

例えば、Virtual Verdeの市場調査チームは、在宅勤務の人たちは、蘭のようなメンテナンスの必要な植物よりも、手入れの簡単な植物を好むということを知りました。そこで、サボテンのようなシンプルで簡単な植物を、蘭よりも優先的に製品化することにしました。そのため、プロダクトバックログには、

1. サボテン
2. 蘭

がリストアップされます。

しかし、例えば、サポートがユーザーから「盆栽が欲しい」というメールを受け取ったとします。蘭の前か後か、どちらにするか？プロダクトオーナーは調査を行い、盆栽よりも蘭を希望するユーザーが多いことから、蘭を先にすることに決定します。

1. サボテン
2. 蘭
3. 盆栽

プロダクトバックログ項目を作成するときの目標は、未知のものに対してあまりストレスを感じないようにしながら、できる限り多くのものを含めることです。例えば、Virtual Verdeのプロダクトオーナーは、サボテンと比べて盆栽の値段がいくらなのかまだ知らないので、ハイエンド市場なのかローエンド市場なのか分からない。そのため、盆栽の説明文にある仮定を記録し、次に進みます。盆栽をもっと詳しく研究するのは、もっと優先順位を上げたときでいいのです。

# まとめ

要約すると、プロダクトバックログは、製品を改善するために何をする必要があるかを並べたリストである。これは、スクラムチームが作業する項目に関する唯一の権威ある情報源です。

プロダクトバックログの洗練化において、項目は分解され、詳細を追加することでさらに定義されます。これらの詳細はさまざまであるが、多くの場合、説明、価値、順序、見積もり、サイズなどの属性が含まれる。

プロダクトゴールは、スクラムチームの長期的な目標であり、プロダクトバックログに含まれる。プロダクトバックログの残りの部分は、プロダクトゴールを達成するためにどのようなタスクがあるのかを定義する。
【Android】WebViewを使ってWebページを表示する方法と端末内のブラウザで開く方法

# はじめに

Androidアプリの開発を行なっていて、利用規約やプライバシーポリシーのページなどをアプリ内で実装するのではなく、外部のWebページとして実装したい場合などはありませんか？

その場合に、どのようにリンクを端末内でひらけば良いのかを２種類の方法を使って紹介します。

この記事はJetpack Composeでの実装を考えている方向けの記事となっていますのでご了承ください。

# WebViewを使う方法

Jetpack Composeで`WebView`を使うには、`AndroidView`を使用します。

`factory`に`::WebView`を渡します。

レイアウトがインフレートされた`update`に指定したコールバックが呼び出されるので、`loadUrl()`を呼び出してURLを開きます。

```kotlin
AndroidView(
    factory = ::WebView,
    update = { webView ->
        webView.webViewClient = WebViewClient()
        webView.loadUrl(url)
    }
)
```

# 端末内のブラウザを使う方法

Jetpack Composeにおいて、外部URLをデフォルトのブラウザを使って開く場合には`UriHandler`を使います。

`UriHandler`のインスタンスは、コンポーザブル内で`LocalUriHandler.current`を使って取得します。

```kotlin
val uriHandler = LocalUriHandler.current
uriHandler.openUri(uiState.url)
```

# まとめ

最初、ブラウザを使ってURLを開く場合に`ACTION_VIEW`のインテントを作成する必要があるのかなと思っていたのですが、ものすごくかんたんに実装できることがわかりAndroidのありがたさをひしひしと感じました。

# 参考にした記事

https://stackoverflow.com/questions/66801838/how-do-i-programmatically-open-an-external-url-on-a-button-click-with-jetpack-co
TCP/IPのプロトコルスタックもっと知っとこう！

未経験からエンジニアになりたい人は、プログラミングから始める人が多いと思いますが、
エンジニアの仕事は、プログラミングだけではありません。そして、プログラミングだけでは、エンジニアになれません。同時にプログラミングが苦手でも、システム構成や開発の流れを理解するとエンジニアに近づきます！
今回はTCP/IPの仕組みについて更に詳しく調べてみましょう！

前回はこちら
https://qiita.com/k1morikawa@github/items/17bffa9080ae1293724b
![インスタスライド_202301052.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23130/d432eafe-6c1e-0566-0342-b6f8047b4578.gif)


# TCP/IPについて
ーTCP/IPの詳細は、業務ではあまり使いません
ーネットワークエンジニアは使います。
ーAWS,Azureで構築する時に使います。

でも知らないと恥ずかしい知識です。

# TCP/IPのプロトコル詳細
TCP/IPは、他のプロトコルと連携しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23130/67a394fd-80f1-3bd5-d98c-4f07e6f17fa2.png)

# プロトコルスタック
１．リンク層
　　物理的媒体の通信制御

２．ネットワーク層
　　データの送信を担当する

３．トランスポート層
　　ネットワークの両端間でのデータの送信を行う

４．アプリケーション層
　　下位層のプロトコルを利用してサービス提供を行う

# 主なアプリケーション
アプリケーション層のサービス
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23130/184ccad5-0844-2d5e-8b52-b0a4da660a8b.png)

# まとめ
ー　TCPIPはプロトコルスタックからなりたっている

ー　アプリケーション層にHTTPとかHTTPSがある

ー　業務ではあまり使いません

ー　でも知ってないと恥ずかしい知識です

# 最後に
未経験の皆さん、若手エンジニアの皆さん、勉強方法について悩みがあればなんでも気軽に質問して下さい！
これからも記事を書いていきますので、モチベーションアップのためフォロー、イイねお願いします。
Java ~配列~

<h2>・配列とは</h2>
　配列とは、値をまとめて管理するオブジェクトのこと。

　配列の種類は`データ型[]`、`ArrayList`、`LinkedList`、`HashMap`の４種類ある。

<h2>・データ型[]</h2>
<h3>・多次元配列の作り方</h3>
　　多次元配列とは、配列の中に配列を作ることである。

　　`データ型[][] 配列名 = new データ型[要素数][]`で作成することができる。

　　`配列名[0] = new データ型[要素数]`で2次元目の配列の個数を入れられる。

![多次元配列図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2850098/69c86168-f67a-51e2-9c39-66ce5d94544e.png)


<h2>・メソッド</h2>
<h3>・fillメソッド</h3>

　　`Arrays.fill(配列名, 入れたい要素)` これを使うとすべての要素を“入れたい要素”にできる。すでにある要素も上書きされる。

<h3>・配列のコピー</h3>
<h4>・Arrays.copyOfを使った場合</h4>

```Java:copyOf
    int[] beCopied = {10, 20, 30};
    //Arrays.copyOf(コピーしたい配列, 長さ[２なら0, 1がコピーされる])
    int[] doingCopy = Arrays.copyOf(beCopied, 2);
    System.out.println(Arrays.toString(doingCopy));
    //-> [10, 20]
```

　　<h4>・System.arraycopyを使った場合</h4>

```Java:arraycopy
    int[] beCopied = {10, 20, 30};
    int[] doingCopy = new int[3] //配列の長さ
    //System.arraycopy(コピーしたい配列, コピーの開始位置, コピー先の配列, コピーする長さ)
    System.arraycopy(beCopied, 0, doingCopy, 0, 3);
```

<h4>・ディープ(deep)コピーとシャロー(shallow)コピー</h4>
<h5>・ディープコピーとは</h5>
　　        <b>ディープコピー</b>とは、完全なコピーを作るコピーのこと。コピーした後、コピー元が配列に変更を加えても、コピー先に影響は受けない。

        <b>シャローコピー</b>とは、見せかけのコピーを作るコピーのこと。コピーした後、コピー元が配列に変更を加えると、コピー先の配列も変更される。

<h4>・copyOfRange</h4>
　<b>copyOfRange</b>メソッドとは、指定した範囲の要素を抜き出して、その要素を集めた配列を作成するメソッドである。

```Java:copyOfRange
    int[] copied = {10, 20, 30, 40, 50};
    //Arrays.copyOfRange(コピー元の配列, 開始位置, 終了位置)
    int[] doCopy = Arrays.copyOfRange(copied, 1, 3);

    System.out.println(Arrays.toString(doCopy));
    //=> {20, 30}
```

<h3>・配列の連結</h3>
<h4>・System.arraycopyメソッド</h4>

```Java:arraycopy
    int[] copiedOne = {10, 20, 30, 40, 50, 60};
    int[] copiedTwo = {70, 80, 90, 100};
    int[] doCopy = new int[copiedOne.length + copiedTwo.length];

    //System.arraycopy(コピー元, コピー開始位置, コピー先, コピー終了位置)
    System.arraycopy(copiedOne, 0, doCopy, copiedOne.length)
    //System.arraycopy(コピー元, コピー開始位置, コピー先, コピー先のコピー開始位置, コピー終了位置)
    System.arraycopy(copiedTwo, 0, doCopy, copiedOne.length, copiedTwo.length);

    System.out.prinln(Arrays.toString(doCopy));
    // => {10, 20, 30, 40, 50, 60, 70, 80, 90, 100}
```

<h3>・並び替え</h3>
<h4>・sort</h4>
　　<b>sort</b>では数字を小さいものから大きいものに並び替える。

```Java:sort
    int[] list = {10, 1, 3, 12, 30};
    Arrays.sort(list);

    System.out.println(Arrays.toString(list));
    => {1, 3, 10, 12, 30}
```

<h3>・deepToStringとは</h3>
　　<b>deepToString</b>とは、多次元配列を文字列で返すメソッド。toStringを使うと数字を参照することができない。

```Java:deepToString
    int[][] list = {{20, 30}, {40, 50}};

   System.out.pritnln(Arrays.deepToString(list));
   //=> [[20, 30], [40, 50]]

```
久しぶりにpython書いたら複数文字列の演算子を使った条件式の書き方わからんくなってた

# 条件式 and,or
Pythonを書く時、論理演算子として**and**や**or**を使って、条件式を書くことがある。(JavaScriptやCでは __&&__ や __||__ で表現する)
有名なもので、[FizzBuzz問題]()の***3の倍数かつ5の倍数***を表現するときに**and**が使われることが例に挙げられる。

# 複数文字列がinで囲まれた大きな文字列に含まれるかどうか
次のような場合を考える
```python:example1.py
if "abc" or "def" in "ghi":
    print("True")
else:
    print("False")

>>> True
```
直感的には、"abc"も"def"も"ghi"には含まれていないため、*False*が返ることが期待されますが、実際には、予想と反する*True*が返ってきます。

これがなぜかというと、pythonでは次のように解釈されているためです。
```python:example2.py
if "abc" or ("def" in "ghi"):
...
```
この場合、左側の条件式"abc"が真として扱われるため、右側の条件式が評価されることなく、if文は*True*となります。

# if文の改善を試みる
**example1.py**の改善を試みます。
```python:example3.py
# パターン1
if ( "abc" or "def" ) in "ghiabc":
    print("True")
else:
    print("False")
>>> True

# パターン2
if ( "abc" or "def" ) in "ghidef":
    print("True")
else:
    print("False")
>>> False
```
**パターン１**は期待通りに結果が返ってきますが、パターン2では期待に反する結果が返ってきます。
このことから、**パターン2**のように書いた場合、左側の条件項（今回の場合"abc"）のみが評価対象になっています。
そのため、評価対象のみを括弧で囲むことは、解決策にはなりません。

結論から言うと、**example1.py**に書いたコードを期待通りに実行する場合は次のように書く必要があります。
```python:example4.py
if "abc" in "ghi" or "def" in "ghi":
    print("True")
else:
    print("False")
>>> False
```
**example4.py**では、各条件に対して評価を行っています。
これが確実なコーディング方法です。

# まとめ
Pythonで複数文字列の演算子を使た条件式を書く場合、直感とは反する結果が返ってくることがある。
内部的にどう処理されているかを把握しておくことで、コーディング時に困惑することが少なくなるかと思います。
POSTDの「分岐予測の簡単な歴史 – Part 1」の「平均1命令あたりのコストの計算式」を理解する

# 概要
POSTDの[分岐予測の簡単な歴史 – Part 1](https://postd.cc/branch-prediction-2/)を読んで、CPUの分岐予測について学習しています。

見出し「予測は成立」配下には、以下のように記載されています。
>全ての分岐が成立すると予測した場合、恐らく70％前後の精度が得られることになります。その場合、分岐の30％に対しては、誤予測のコストが必要になり、平均1命令あたり `(0.8 + 0.7 * 0.2) * 1 + 0.3 * 0.2 * 20 = 0.94 + 1.2. = 2.14` のコストを支払わなければなりません。


最初読んだとき、平均1命令あたりのコストの計算式が理解できませんでした。各数値はそれぞれ何を表しているのか分からなかったのです。

1個ずつ数値が何かを考えることで、式の意味をようやく理解することができました。その覚え書きをQiitaに残します。


# 平均1命令あたりのコストの計算式
`(0.8 + 0.7 * 0.2) * 1 + 0.3 * 0.2 * 20`
まずは左項と右項で分けて考えます。


### 左項
```
  (0.8 + 0.7 * 0.2) * 1
= (0.8 * 1) + (0.7 * 0.2 * 1)
```

* `0.8`：一般的なベンチマークから算出した分岐以外の処理の確率80%
* `0.7`：正しく分岐が予測される確率70%
* `1`：正しく予測された分岐に必要なサイクル数


### 右項
`0.3 * 0.2 * 20`

* `0.3`：誤予測の確率30%
* `0.2`：一般的なベンチマークから算出した分岐処理の確率20%
* `20`：予測しない、または予測を誤った分岐に必要なサイクル数


### まとめ
以下の計算式は3つの項で成り立っていると考えれば、理解できました。

```
  (0.8 + 0.7 * 0.2) * 1 + 0.3 * 0.2 * 20
= 0.8 * 1 + 0.2 * (0.7 * 1 + 0.3 * 20)
= 0.8 * 1 + 0.2 * 0.7 * 1 + 0.2 * 0.3 * 20
```

* 分岐以外の処理に必要なサイクル数: `0.8 * 1`
* 正しく予測された分岐に必要なサイクル数: `0.2 * 0.7 * 1`
* 予測を誤った分岐に必要なサイクル数: `0.2 * 0.3 * 1`
MYSQL

# mysqlの起動
```
$ mysql -u root -p
```

# データベースの確認
```
mysql> SHOW DATABASES;
```

# データベース接続
```
mysql> use 接続したいデータベース名;
```

# テーブル確認
```
mysql > show tables;
```

# テーブルのデータを確認
```
mysql> SELECT * FROM 確認したいテーブル名; 
```

MYSQLを抜ける
```
mysql> quit
```
保護ブランチへのPRマージ条件にpathを限定したCIの成功を指定している場合、そこ以外の変更のときCIが回らなくて条件を満たせない → そんなときはpaths-ignoreを使っていつでも回るCIにすればいい

GitHubのブランチには保護設定をすることができます。
例えば`master`ブランチにマージするためには指定したCIが通っていなければいけない、などの仕組みが作れます。

また、GitHub Actionsによるワークフローでは`on.pull_request.paths`で「特定のディレクトリの変更があった場合のみワークフローを回す」といったことが可能です。

では、次のようなワークフロー`test`を用意して、かつマージの可能条件に`test`が通ったことを指定したらどうなるでしょうか？

```.github/workflows/ci.yaml
name: test
on:
  pull_request:
    paths:
      - "dir/**"
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - run: echo "You have to pass this test before merging."
```

PullRequestがディレクトリ`dir/`配下の変更を含むものであれば、そのPullRequestはマージできます。
しかし、例えば`/README.md`への追記など`dir/`外の変更であればそもそもワークフロー`test`が発火しないのでマージ可能条件を満たしません。

保護を無視して強制マージをする、などのふるまいによってこの問題は解決できますがスマートではありません。
そこで、次のようなワークフローをもう一つ用意することで解決しましょう。

```.github/workflows/ci_ignore.yaml
name: test
on:
  pull_request:
    paths-ignore:
      - "dir/**"
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - run: echo "But you can ignore the test when changes are out of dir/"
```

ワークフローに同じ`test`という名前をつけて`on.pull_request.paths-ignore`に`dir/**`を指定することで、PullRequestがどんな変更であっても必ずワークフロー`test`が実行されるようになります。

`on.pull_request.paths-ignore`は`on.pull_request.paths`と逆の動きをするものです。つまり、そこに指定した箇所**のみ**の変更があった場合はワークフローが**動きません**。
テストが通るように、ignore用のワークフローは必ず成功する内容にしましょう。

これで、指定した箇所の変更ではCIが回ってくれるし、それ以外の変更では自動でsuccessになって保護ブランチへのマージ可能条件を満たしてくれます。

ただしこの方法だと、PullRequesstがpathsに指定した箇所の変更とそれ以外の変更とを同時に含む場合にワークフローが２つとも実行されてしまうので少し格好悪いんですよね......。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1482250/4e9933f7-39d2-8f31-6288-0208d29b1e9b.png)

参考：https://docs.github.com/ja/repositories/configuring-branches-and-merges-in-your-repository/defining-the-mergeability-of-pull-requests/troubleshooting-required-status-checks#handling-skipped-but-required-checks
攻撃の対象にならないために

初めて投稿します。
内容、レイアウト等直しながら、良い記事を作っていきたいです。

さっそく、今日の内容はサーバのICMP応答を無効にする方法です。
疎通ができているか確認するのに便利な「ping」コマンドですが、
ICMPというプロトコルで通信しているんですね。TCP/IPが実装されている場合に使用できます。
TCP/IPで通信を確立する前に、ICMPで機器が物理的およびネットワークに接続できているかを確認できます。
ちょっとした機器と接続するときなんかに手軽に使用できて重宝します。が、
その機器がインターネットに接続している場合、インターネットに接続している誰もがICMP応答を受けることができてしまいます。
接続できてますよーというのがわかるのは自分だけでいいわけです。

自分だけがわかればいいものを公開しているサーバ・・・
これ、他の設定も甘いんじゃないか・・・
ということで、他人に接続できることを知られた場合、その機器は攻撃対象となります。

ICMP応答の無効化、いたって簡単です。
rootユーザーになり、ファイアーウォールが起動していることを確認し、以下のコマンドを入力します。
```
$ firewall-cmd --set-target=DROP --permanent
```
以上です。

pingが通らなくなりました。

オプションの内容はRHELの[公式ページ](https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/8/html/securing_networks/proc_setting-the-default-target-of-policy-objects_assembly_filtering-forwarded-traffic-between-zones)で確認できます。
```
ACCEPT - 支払いを受け付けます。
DROP - 不要なパケットを破棄します。
REJECT - ICMP リプライで不要なパケットを拒否する
CONTINUE (デフォルト) - パケットは、次のポリシーおよびゾーンのルールに従います。
```

当然ですが、ICMP応答を無効にしたから攻撃を受けないわけではないです。
ポートが開いていればTCP/IPのsynパケットはしっかりポートに到達するので、
サーバの設定まで丁寧に行わなければなりません。

・・・検証マシンの設定がうまくいったら記事でまとめたいです。:joy:
rex0220 計算式プラグイン テーブル内小計

kintone のテーブルで、小計を計算してみます。
[計算式プラグイン](https://qiita.com/rex0220/items/ae83c6d5ce50ff7a9a73)、[項目検証プラグイン](https://qiita.com/rex0220/items/be20fd879f5e1bc9e035)、[項目書式プラグイン](https://qiita.com/rex0220/items/87470704fd4187e29406)を使います。

# テーブル内小計

概要行と小計行に挟まれた明細行の金額の小計を計算します。
概要、明細、小計の各行は、マニュアル設定です。
テーブル行が増加すると、計算処理に時間がかかります。
２０行～３０行くらいまでが実用範囲だと思われます。
※[rex0220 計算式プラグイン テーブル処理時間の改善](https://qiita.com/rex0220/items/0add4c5ac2de646af146) で、50行以上も実用範囲になります。

- 詳細画面
![2023-01-26_00h52_30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/cb9b0c3d-d5d8-6b73-6ac4-9119cfe75bec.png)

- 一覧画面
![2023-01-26_10h32_47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/3a402f80-9085-3ae8-3fa7-8332fc5fef27.png)

# 操作例

![2023-01-26_01h01_23.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/f3eff2b3-1f26-19b4-b309-f760a1a89e63.gif)

# 計算式プラグインの設定

概要行と小計行の間の明細行の金額合計を小計行の金額に設定します。
「循環参照を許可」にチェックが必要です、

~~~
// No
ROWNO(テーブル)+1
// 商品
LET(CNO,ROWNO(テーブル),
  SWITCH(分類,
    "小計",LET(PNO,NVL(LASTIF(AND(ROWNO(テーブル)<CNO,分類="小計"),ROWNO(テーブル)),-1),
      FIRSTIF(AND(ROWNO(テーブル)<CNO,ROWNO(テーブル)>PNO,分類="概要"),商品)),
    商品)
)
// 数量
IF(分類="明細",数量,"")
// 単価
IF(分類="明細",単価,"")
// 金額
LET(CNO,ROWNO(テーブル),
  SWITCH(分類,
    "明細",数量*単価,
    "小計",LET(PNO,NVL(LASTIF(AND(ROWNO(テーブル)<CNO,分類="小計"),ROWNO(テーブル)),-1),
      SUMIF(AND(ROWNO(テーブル)<CNO,ROWNO(テーブル)>PNO,分類="明細"),金額)),
    "")
)
~~~


- 金額の計算式の説明
    - LET(CNO,ROWNO(テーブル) ：
      集計関数内では行番号(ROWNO)が変わるため、LET 関数で処理中の行番号を取得しておく。
        - SWITCH(分類, ： 分類ごとに処理を分ける
            - "明細",数量*単価, ：明細行は、金額計算
            - "小計",LET(PNO,NVL(LASTIF(AND(ROWNO(テーブル)\<CNO,分類="小計"),ROWNO(テーブル)),-1), SUMIF(AND(ROWNO(テーブル)\<CNO,ROWNO(テーブル)>PNO,分類="明細"),金額)),
             ※小計行は、前の小計行(PNO)から処理中行(CNO)前までの金額を合計
            - "" :概要行は、金額を空欄


![2023-01-26_01h06_58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/34c1550a-71e2-4738-9735-66af1abd610a.png)

# 項目検証プラグインの設定

概要、小計行の入力不可の指定のみ行っています。

~~~
// 商品の入力不可
分類="小計"
// 数量の入力不可
分類!="明細"
// 単価の入力不可
分類!="明細"
~~~

![2023-01-26_01h13_10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/da685c0c-2501-8875-421b-fdfdf21700a5.png)

# 項目書式プラグインの設定

小計行のみ背景色を指定します。

~~~
// テーブル行の条件
分類="小計"
~~~

![2023-01-26_23h55_57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/f2dbdcc4-c446-64ca-6539-3f2d982388ed.png)
Power Automate for Desktop でCSVを扱う：項目にダブルクォーテーション付きで出力する

業務でPower Automate for desktop でのRPA作成に携わることになり、日々試行錯誤しているので覚え書き。

仕様
1) 某システムから吐き出されたCSVファイル(A)を読み込む
　（UTF-8、項目はダブルクォーテーションで囲まれている）
2) 列を入れ替える、列を加えるなどの列操作
　（前任者がここでExcelを使うRPAを書き、ID欄の0落ちが発生し大事故の過去）
3) 別のシステムに流し込むためにCSVファイル(B)に書き出す
　（UTF-8、項目はダブルクォーテーションで囲む、改行コードLF）
※それぞれフォルダ操作、ファイル名作成などはある。

パッと見、初心者の私でも書けるような単純な仕様ではあるのですがあちこちにトラップがありました。
例えば2)、以前に「0落ち」で大事故を起こしているため、（そして会社という性質上）、まずはExcelを介さずに、安全安心に、CSVとPADのデータテーブルだけで叶えられないかを検討しなければなりませんでした。

今回は上記のうち、3)について。

読み込むCSVはテストとしてこんなものを用意しました。test.csv
項目はダブルクォーテーションで囲まれ、文字コードはUTF-8、改行コードはLFです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427001/1a643676-02ac-d1a6-f511-7f2b2d5e31bf.png)

Excelで単純に開くと見事にゼロ落ちしているのがわかります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427001/0cd2c36e-8f80-5cc6-5902-52c02d423e79.png)

まずは PowerAutomate desktop で単純にCSVを読み込んでデータテーブルに格納し、名前を付けて保存します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427001/09f689b1-54dd-38b3-9f24-a01e59ff981a.png)

「CSVファイルに書き込む」の設定はこんな感じ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427001/985ab2cd-0259-1630-433b-40cdd3fd1ec0.png)

これで保存した「test_after.csv」をテキストエディタで開くと下図のようになっています。
ダブルクォーテーションがない上に、改行コードも「CRLF」になっています。
文字コードはUTF-8で保存ができました（上記で設定したので当たり前ですが…）。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427001/f418ab30-07a4-da1b-8242-567a765cbb4e.png)

あれこれ試行錯誤しましたが、スマートにPADの簡単な機能だけで「項目をダブルクォーテーションで囲む」「改行コードはLF」の両方をかなえるのは難しいと判断しました。

かといって、ここで書き出したCSVを再度サクラエディタで開いてダブルクォーテーションと改行コードを…とするのは、業務改善エンジニアとしてはとりたくない選択肢であります。
（実際のところ、業務ではこのような処理を大量にやるため、あとから一つ一つCSVを開くというのは、RPAの意味がなくなってしまいます。）

結論として、PAD内の機能、PowerShellにコードを書くことで、ダブルクォーテーション問題と改行コードLF問題を解決しました。
しかしながらPowerShellは全く知らない状態からのスタートだったため、2つのことを同時にやりたいと思いつつ、今のところは別々に実装しています。。。

## CSVの項目にダブルクォーテーションをつける（PowerShell）
test_after.csv　⇒ test_wquote.csv
PADのフローにPowerShellを挿入します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427001/c6e1e116-e713-d3e0-bdba-74f16fc9e429.png)
書いたコードは以下の通り。
```
Import-Csv -Path "D:\test_after.csv" -Encoding UTF8 | Export-Csv -Path "D:\test_wquote.csv" -NoTypeInformation -Encoding UTF8
```
test_after.csvを読み込んで、形式を指定して「test_wquote.csv」に書き出しているだけです。
途中、文字化けを起こしたりしましたが、「-Encoding UTF8」をつけることで解決しました。
文字化けが起こる場合は文字コードを確認しましょう。

結果はこちら。ちゃんとダブルクォーテーションがつきました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427001/fc677237-5ca3-9877-208f-7bd31883501f.png)


## CSVの改行コードを「LF」にする（PowerShell）
test_wquote.csv　⇒ test_wquote_lf.csv
PADのフローにPowerShellを挿入します。
書いたコードは以下の通り。

```
$lfText = [System.IO.File]::ReadAllText("D:\test_wquote.csv").Replace("`r`n","`n")
[System.IO.File]::WriteAllText("D:\test_wquote_lf.csv", $lfText)
```
これはCRLFの改行コードをLFに置換（Replace）する方法でした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427001/384eb871-f16f-a82e-ef9e-21b54f6e07b0.png)

うまくいった！と思いきや、UTF-8Nになっちゃってるんですね…
ここはまた今度直したいと思います。

改行コードの変換は以下の記事を参考にしました。ありがとうございました。
https://teratail.com/questions/347291

現在仕事ではGAS、スプレッドシート関数、PowerAutomate desktopを主に触っているので、ほかの部分についても追い追い書いていきたいと思います。
rex0220 計算式プラグイン 複数選択の扱い方

複数選択項目の選択肢を設定する計算式のお問合せがありましたので、まとめておきます。

# 複数選択項目の設定例

複数選択に A、B、Cという選択肢があり、 A、B、C のドロップダウン項目の値が入っている項目と同じ名前の選択肢が自動選択される。

![2023-01-26_00h25_32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/1cfe9652-4b5d-9fa0-b9b3-f94790def59d.png)

操作例
![2023-01-26_00h38_57.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/0c981718-f004-5434-14df-e9f8d590157c.gif)

# 計算式
※複数選択とチェックボックスは、どちらも複数の選択肢を持つため、同じ計算式で値を設定できます。
~~~
// ARRAY 関数に、ARRAY 関数で値を並べる
ARRAY(
  IF(A,ARRAY("A"),ARRAY()),
  IF(B,ARRAY("B"),ARRAY()),
  IF(C,ARRAY("C"),ARRAY())
)

// または、文字列を要素として並べる
ARRAY(
　IF(A,"A",ARRAY()),
　IF(B,"B",ARRAY()),
　IF(C,"C",ARRAY())
)
~~~
![2023-01-26_00h29_34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/5c75d5f8-edbe-f880-d443-6cf5307890d7.png)
2023年1月版 Raspberry Piセットアップ


```
sudo apt update
sudo apt upgrate
sudo apt list –upgradable
sudo apt autoremove

sudo apt install curl

# fnm nodejsバージョン管理
curl -fsSL https://fnm.vercel.app/install | bash
source /home/genya/.bashrc
eval "$(fnm env –use-on-cd)"
fnm install 18.13.0

# 1password https://support.1password.com/install-linux/#other-distributions-or-arm-targz
curl -sSO https://downloads.1password.com/linux/tar/stable/aarch64/1password-latest.tar.gz
tar -xf 1password-latest.tar.gz
 sudo mkdir -p /opt/1Password
 sudo mv 1password-*/* /opt/1Password
sudo /opt/1Password/after-install.sh
1password

# vscode
curl -L https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor | sudo tee /usr/share/keyrings/microsoft-archive-keyring.gpg >/dev/null
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/microsoft-archive-keyring.gpg] https://packages.microsoft.com/repos/vscode stable main" | sudo tee  /etc/apt/sources.list.d/vscode.list
sudo apt update
sudo apt install code

# git 
sudo apt install git -y

# vscode でgithubログイン
# vscodeでlive　shareをするときにgithubアカウントでWeb認証しようとするが
# ブラウザの起動ができないので一度キャンセルをすると認証コードがコピーできるので
# 下記にアクセスして認証コードを貼り付けて認証する
https://github.com/login/device/


```
うまく使えばレスポンスが爆速に Rails 7から導入されたload_asyncについて解説

今回はRails 7から導入された新機能 load_asyncについて解説します！

[私のブログ](https://ftb3nip05e.microcms.io/apis/blogs/dnjqj82-63)にも同じ内容を記載しておりますので、こちらも是非ご参照ください

## load_asyncとは
Rails 7から追加された、「非同期的にクエリ実行するためのメソッド」です。

並列にクエリが実行されるため、うまく使うと **これまで時間がかかっていた処理をかなり短縮できる「可能性」** があります。



## load_asyncの使い方
以下のような場面を想像してみましょう。

mypageを取得するメソッドの中で、「お客様のプロフィール」「お客様の購入履歴」「お客様の獲得ポイント」の３つを取得しています。

``` ruby
def mypage
  @profile = Profile.find_by(user_id: params[:user_id])
  @orders = Order.where(user_id: params[:user_id])
  @points = Point.where(user_id: params[:user_id])
end
```
ここで、通常であればこの処理は上から順に「プロフィールの取得」=>「購入履歴の取得」=>「獲得ポイントの取得」の順番に進んでいきます。

図で表すと以下のような感じです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3120011/fd4d25a6-4031-68d4-03b5-142e3c6d8c39.png)

では、load_asyncを使ってみます。使い方は以下のように各行の末尾にload_asyncをつけるだけです。

``` ruby
def mypage
  @profile = Profile.find_by(user_id: params[:user_id]).load_async
  @orders = Order.where(user_id: params[:user_id]).load_async
  @points = Point.where(user_id: params[:user_id]).load_async
end
```

ここで、処理は「プロフィールの取得」「購入履歴の取得」「獲得ポイントの取得」が **並列に走ります。**

図で表すと以下のような感じです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3120011/2dd8e806-1cb6-4740-46fa-f2dd84f68779.png)

使い方によってはかなりの短縮ができそうですね！

## load_asyncの設定
デフォルトでの並列数は **４つ** です。これ以上増やす場合は、`config.active_record.async_query_executor`の設定が必要です

``` ruby
config.active_record.async_query_executor = 5  # クエリを5つ並列に
```

## load_asyncの注意点
一見「全部これでいいのでは」と思えるほど便利なメソッドですが、意外な落とし穴もあります。

### トランザクションの挙動に注意
トランザクション内ではload_asyncを使っても直列的な動きになることが考えられます。

[参考リンク](https://pawelurbanek.com/rails-load-async)


### データベースのメモリ使用量に注意
並列数をあまりに増やしすぎると、データベースのメモリを過度に使い、逆にパフォーマンスが低下する恐れもあります。
利用する際は、データベースのメモリ使用量に注意し、適度に監視を行いましょう。



### まとめ
1. load_async を末尾につけると, クエリの並列化が行える
2. 並列にできるクエリ数はデフォルトでは4つ
3. データベースのメモリや, トランザクションの挙動に注意


無闇に使わず、ボトルネックに適切に効かせて武器にしましょう🔥
dnsmasq,NSD,Unbound,PowerDNSについて

DNSサーバには主に2つの機能がある。

・名前解決検索要求を受け取り、他のDNSサーバに問い合わせを行う「フルリゾルバ」機能（応答結果をキャッシュしておき、キャッシュがあればそれを返すため「キャッシュサーバ」とも呼ばれる）
・自身の管理するドメインの情報を公開する「権威サーバ」機能（「コンテンツサーバ」とも呼ばれる）

多くのディストリビューションで標準的に使用されるBINDは、フルリゾルバと権威サーバの両方の機能を持つ。
BIND以外にも、以下のような代替となるDNSのソフトウェアがあります。

・dnsmasq
DNSのキャッシュサーバやDHCPサーバなどの機能を持つソフトウェア。
BINDに比べて軽量で設定も容易ですので、簡易的なDNSキャッシュサーバとして利用できる。

・NSD（Name Server Daemon）
NLnet Labsという組織によって開発・保守が行われている権威サーバ。他のDNSサーバに問い合わせを行うフルリゾルバ（キャッシュサーバ）の機能はありません。
BINDに比べてパフォーマンスが良く設定も容易。

・Unbound
NSDと同じくNLnet Labsによって開発・保守が行われているフルリゾルバ（キャッシュサーバ）。
BINDと同様にDNSSEC（※）をサポート。
※公開鍵暗号方式を用いた電子署名により、正当なDNSサーバからのゾーン情報である事を認証し、またゾーン情報が改竄されていないことを保証する技術

・PowerDNS
RDB（リレーショナルデータベース）などをバックエンドデータベースとして使用できるDNSサーバ。RDBの他にLDAPやBINDのゾーンファイル（ドメインの詳細情報が記載されたファイル）をバックエンドに使用できる。
PowerDNSは権威サーバとフルリゾルバの機能を異なるプロセスで処理。
【Unity＆C#】AR開発フレームワークの差異

![immersal.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3118254/ef410f96-03b1-107e-2d50-9e0d488243fa.png)


# はじめに
僕は、都内の某私立<font color="red">文系</font>大学生の１年生です。
UnityとC#でARコンテンツ開発を主として活動しており、サブでWebアプリ開発も行っています。
僕についての紹介はこちらから！
https://qiita.com/RyuseiItoh/items/80cc0f3c419b0d5a5e6b

# 空間を認識するAR
皆さんはAR技術って言われてもピンとこない方が多くいらっしゃると思います。
実際、僕の周りでは20人に1人知っている人がいれば良い方です。

だがしかし、ポケモンGOを知らない人はいない！ポケモンGOはNiantic社がAR技術を用いて作ったまじですごいARゲームだというのに、、、！

Apple社がつい最近VRゴーグルを発表し、VRコンテンツとXRへの認知が急速に拡大すると考えています。そこで今回は少し先の技術 - ARについて覗いてみましょう！！

# ARの開発のプラットフォーム
## (1)Niantic Lightship ARDK
### 概要：
Niantic Lightship ARDKとはNiantic社が開発したAR開発者向けキットを指します。
Unity環境下で使用することができるAR開発プラットフォームとして幅広く知られています。
### 機能：
(1)ARのマルチプレイ化
複数人のユーザーが参加できるようなAR体験を作成することができます！
近くにいるユーザーが同時に共通のオブジェクトにアクセスすることができ、全員で交流することができます。

(2)メッシング
画像やスマートフォンなどのLIDARで読み取った情報から３Dジオメトリを生成することができます！
３Dジオメトリは、画像や機器で読み取った情報から作った３Dモデルのようなものです。

(3)セマンティック セグメンテーション
環境を認識してそれぞれを把握し、領域ごとに区別することができるものです！
空を認識して朝の空を満天の星空にすることもできます！


　　　　　　　　　　〇Niantic社が公開しているARDKの動画です！
<iframe width="560" height="315" src="https://www.youtube.com/embed/zS7z_eYKvNk" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>

## (2)Immersal
### 概要：
スマホのアプリを通して複数の写真を撮り、空間を認識することでサーバー上で画像解析が行われ、開発用のデータを得ることができるものです！
### 機能・使用方法：
自分のスマートフォンでimmersalのアプリをインストールして室内などの写真を中心を向きつつ、ぐるっと部屋を一周して各上下３枚ぐらいづつ写真を撮り、
撮った写真を開発者サイトから解析に出すとAR開発に必要なデータを得ることができます。
サムネの写真も僕が作った点群データです！！

その後開発を終え、スマホなどで現実の部屋と読み取った部屋のデータと照らし合わせ、一致すると開発時に追加したオブジェクトなどが表示されるというわけです！！

　　　　　　　　　〇こちらが都市を実際に読み取って開発した動画です！！
<iframe width="560" height="315" src="https://www.youtube.com/embed/M62Bb3MlPos" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>

## (3)ARFoundation
### 概要：
Unity社がUnityの内部機能として実装しているAR開発のためのフレームワークです！
この機能を使えば簡単にARアプリが制作できます！！

### 機能：
(1)クロスプラットフォーム開発
ARFoundationを使用してアプリを開発すると、iOSで使用されるARkitとAndroidで使用されるARcoreのどちらにも対応しており、それぞれのOSに合わせていくつもアプリを作り直さなくてよいのがとてもすごいところです！！

(2)メッシング
前述の通り空間を認識して、現実空間を捉えることができる機能です！
AndroidのARcoreでは未対応なのが少し難点ですね！

(3)平面認識
平面（壁や床）を認識することができます！
開発時に保存した画像に対し、画像を認識するとオブジェクトを出るなどの機能をつくれば
飛び出る絵本などが作れます！！


　　　　　　　　　〇Unityが出しているARFoundationの紹介動画です！！
<iframe width="560" height="315" src="https://www.youtube.com/embed/ml9qVRdEH4k" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>

# おわりに
皆さんいつも投稿を最後まで見ていただきありがとうございます！

僕は最近Immersalでのアプリ開発を行っているのですが、ARDKを使ったときとは違い
オブジェクトの手前に移った人の抜け感がとてもよいのでお勧めです！！

大企業の事業縮小などでXR関連の部署が解散したりなどする中でも、
XRデベロッパーの需要は高いままです！
皆さんの夢を高く持ち、一緒に頑張りましょう！！
RPGツクールMVのプラグインの存在チェック 

一発ネタです。たとえば「SamplePlugin.js」の存在をチェックしたい場合は……。

```sample.js
var exist_plugin = false;
$plugins.forEach(function(p) {
    if(p.name === "SamplePlugin"){
        exist_plugin = true;
    }
}, this);
````

「main.js」読めば誰でも分かる話ではありますが。
【個人開発】【失敗談】なぜ個人開発は過疎サービスを生み出してしまうのか？【Flutter】

## 誰が書くのか
社内SEに途中でキャリアチェンジした、エンジニア経験２年程のしがない20代後半男性です。

## 何を書くのか
個人開発の振り返りです。派手なタイトルをつけてすみません、特に敵意はありません。

先日Flutterで以下のような「交換日記アプリ」をリリースしました。
https://apps.apple.com/jp/app/exchange-diary/id6444697825

ご覧の通りよくある過疎アプリとなっておりお世辞にも「成功」とは言えない状態です。
そのため、「どうすると良いのか？」を今後のために書いていこうと思います。


## 反省点
### 1.どうしたら人が集まるのか考えておくべき
人が集まってはじめて価値があるコミュニティ系サービスでは、人がいなければ価値が出ません。
ではどうしたら、最初のコミュニティを築けるような熱を生み出せるのか？
お金も人脈も乏しい個人開発者にとっては、難しい課題です。

「知らないどこかの誰かが、有象無象のアプリの中から見つけてくれて、面白いと思い続けてくれる」
基本的にはそんな幻想を抱かない方がいいなと思いました。

### 2.ターゲットとニーズを限定する
ターゲットの明確で限定的な欲求を、確実に解消できるようにしたいものです。
自分のアプリは、「SNS疲れをした人」という仮説が、抽象的すぎるものだったかもしれません。
仮説検証が大事なのでしょうが、個人開発者にとってはやはり実行困難な問題になりやすいです。

存在しないユーザーや、存在しない不満を作り上げないよう気を付けていきたいです。


### 3.機能の優先順位を明確に考えておくべき
いらない機能、意味のない機能、あった方がいい機能は後回しにしましょう。
ただでさえリリースまでにやらなければいけないタスクは多過ぎるのに、時間がもったいないです。
マスト機能に絞り込み、リリースしてからトライ&エラー(ピボット)を重ねるべきでしょう。

## 終わりに
ざっと振り返りましたが、「やってよかった」とは強く思っています。
貧弱な開発者にとっては、まず技術力の向上やリリースまでの一通りの経験が何より糧になりました。
リリースしたことで一定の評価を得ることもできます、分かり易いですしね。

また、驚くべきことに身近な友人や家族に使ってもらい、感動しました。

ただ、”売れるサービス”を作るのは全く別の話で、戦略的でならなければならず、
個人で戦うにはなかなかハードな戦場だと思いました。

この記事が誰かの役に立てれば光栄です！
もし良いなと思ったらハートを押していただけると大変励みになります！

## 宣伝
Flutter大学さんにアプリを紹介してもらったりしました！
共同開発などもやるきっかけになったり、良い刺激をもらっていますので、宣伝させていただきます。
https://flutteruniv.com/
学びを結果に変えるアウトプット大全の感想


# 概要
タイトルの通り本記事は「学びを結果に変えるアウトプット大全」の個人的な感想について記載します。
個人的な感想なのでいじめないでください。

# 読む前
元々私はアウトプットを拒否感を持っていました。
理由は以下です。
- 会社の評価のために強制されることが多かった（勉強会など）
- アウトプットを否定されることが怖かった
- よわよわエンジニアなのでやるべきではないと感じていた
- 自分の考えをアウトプットするかしないかは自分の自由で私が何を考えていようが他人には関係ないと考えていた


しかし、インターネットでたくさんアウトプットしているエンジニアを見たり、
同僚に勧められた「SOFTSKILLS-ソフトウエア開発者の人生マニュアル」を読み、
私のキャリアやエンジニア人生をよりよくするためにはアウトプットが必要だと感じていました。

https://zenn.dev/nagataichiko/articles/403c1e8730fdf6

実際にアウトプットはどのように行えば良いのか参考にするために「学びを結果に変えるアウトプット大全」を読みました。

# 気付き
## アウトプットの効果
私はアウトプットの一番の効果は「人に評価される」ことだと考えていました。
会社の評価制度で「アピールしてくれないと評価できない」「評価しやすいようにアウトプットしてほしい」と言われたことがきっかけでアウトプットを始めたからです。

しかし、アウトプットにはもっとよい効果がありました。
それは「世界を変える」効果です。

アウトプットは「技術記事を書く」以外にも「話す」や「行動する」ことも含まれます。
本を読むなどインプット行為を行なってもアウトプットしなければ何も変わりません。
実際に行動に移すことによってインプットした情報の効能が得られるのです。

## アウトプットがすごいのはわかったけどそれはさておき時間がない
学校や仕事や家事など人はいつもやることがたくさんあって時間に追われています。
アウトプットが良いことなのはわかったけど、時間がない場合、その解決方法には以下があります。

### インプットの時間を減らすこと
インプットとアウトプットの比率は3：7が良いそう。
また、脳への定着の面からもインプットの時間よりもアウトプットの時間を多く取るべきとのこと

### 時間を制限する
15分で記事を書くなど時間を制限することで集中力を高め、生産性を向上させます。

## 脳を活性化するには
- 運動
- 文字を書く
- 抽象化にはアナログ
- 具象化にはデジタル

## 続けること
1日数行の日記でも良い、とにかく続けることが大切
体調についてでも良い。
とにかく続けやすいやり方で継続すること。

# 読んだ後
私は「Qiita」に書こうか「Zenn」に書こうか、「誰かに引用されて馬鹿にされたらどうしよう」などなど悩んで何もしませんでした。
今後は何かしらの方法でアウトプットを継続したいと思います。
また、本を読んだ後の行動のとしてこの記事を作成しました。
- 読書感想文
- Twitterのブックマーク整理
- 設計まわり
- 実装まわり
- Zennスクラップ
Blenderで重複して読み込んだマテリアルを共通のものに

Blenderで　アペンドやインポートで名前が重複したマテリアルのついたオブジェクトを読み込むと
「.001」といった具合に名前がかぶらないようにリネームされてマテリアルが作成されるものの
重複元のマテリアルを使用したい場合に　割り当てを変更するスクリプト
```
import bpy
object = bpy.context.active_object
material_slots = object.material_slots
for slot in material_slots:
    mat_name = slot.material.name
    if mat_name[-4:] == ".001":
        slot.material = bpy.data.materials[mat_name[:-4]]
```
とりあえず動けばいい程度の書き捨て
【Linux】ファイルの重複行を削除する方法

## 重複した行を削除する方法

## `uniq`と`sort`で削除
`uniq`コマンドと`sort`コマンドを使用して重複した行を削除できます。

```:ターミナル
$ sort 対象ファイル | uniq
```

`uniq`コマンドのオプションは以下のとおりです。
|オプション|説明|
|:---:|:---|
|-c, --count|各行の前に重複回数を出力する|
|-u, --unique|重複していない行だけを出力する|
|-d, --repeated|重複した行だけを出力する|
|-D, --all-repeated|重複した行を全て出力する|
|-i, --ignore-case|比較時に大文字と小文字の違いを無視する|
|-w N, --check-chars=N|行の比較を最初のN文字で行う|
|-s N, --skip-chars=N|最初のN文字を比較しない|
|-f N, --skip-fields=N|最初のN個のフィールドを比較しない|
|-z, --zero-terminated|最後にNULL文字を出力する|

## `sort`で削除
`sort`コマンドのみでも削除できます。
```:ターミナル
$ sort -u 対象ファイル
```

また以下のようにすることで対象ファイルを上書きできます。

```:ターミナル
$ sort -u 対象ファイル -o 対象ファイル
```
ubuntu20.04でros2 foxyを始める　


# はじめに
ubuntu20.04LTSにてros2 foxy を導入してみたのでその記録。[ubuntu公式](https://docs.ros.org/en/foxy/Installation/Alternatives/Ubuntu-Development-Setup.html)を参照しています

# 環境
|OS|windows|
|:-:|:-:|
|ubuntu|20.04LTS|

# 実装
### ロケールの設定
基本的に以下を張り付ければokです
```
locale  

sudo apt update && sudo apt install locales
sudo locale-gen en_US en_US.UTF-8
sudo update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8
export LANG=en_US.UTF-8

locale  
```
### ros2 aptリポジトリを追加する
```
sudo apt install software-properties-common
sudo add-apt-repository universe
```

### GPGキーをaptで追加
```
sudo apt update && sudo apt install curl
sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg
```

### リポジトリをソースリストに追加
```
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu $(. /etc/os-release && echo $UBUNTU_CODENAME) main" | sudo tee /etc/apt/sources.list.d/ros2.list > /dev/null
```

### ツールをインストールする

```
sudo apt update && sudo apt install -y \
  libbullet-dev \
  python3-pip \
  python3-pytest-cov \
  ros-dev-tools
```

### ROS2コードを取得する
**mkdir**でワークスペースを作成
**cd**で作成したワークスペースの中に入る
```
mkdir -p ~/ros2_foxy/src
cd ~/ros2_foxy
vcs import --input https://raw.githubusercontent.com/ros2/ros2/foxy/ros2.repos src
```
以下のように出ればok
```
=== src/ros2/tinyxml_vendor (git) ===
Cloning into '.'...
=== src/ros2/tlsf (git) ===
Cloning into '.'...
=== src/ros2/unique_identifier_msgs (git) ===
Cloning into '.'...
=== src/ros2/urdf (git) ===
Cloning into '.'...
=== src/ros2/yaml_cpp_vendor (git) ===
Cloning into '.'...
AAAAAA@BBBBBBB:~/ros2_foxy$
```

### rosdepを用いて依存関係をインストールする
```
sudo apt upgrade
```

```
rosdep update
```

```
sudo rosdep init
rosdep install --from-paths src --ignore-src -y --skip-keys "fastcdr rti-connext-dds-5.3.1 urdfdom_headers"
```

### 動作確認
```
#　時間がかかります
colcon build --symlink-install
```

以下を実行してください
ひとつ目のターミナル **talker**側
```
. ~/ros2_foxy/install/local_setup.bash
ros2 run demo_nodes_cpp talker
```

ふたつ目のターミナル **litener**側
```
. ~/ros2_foxy/install/local_setup.bash
ros2 run demo_nodes_py listener
```
##### 結果

talker側
```
[INFO] [1674657719.183440995] [talker]: Publishing: 'Hello World: 1'
[INFO] [1674657720.183154403] [talker]: Publishing: 'Hello World: 2'
[INFO] [1674657721.183363019] [talker]: Publishing: 'Hello World: 3'
[INFO] [1674657722.183254133] [talker]: Publishing: 'Hello World: 4'
[INFO] [1674657723.183471186] [talker]: Publishing: 'Hello World: 5'
[INFO] [1674657724.183229530] [talker]: Publishing: 'Hello World: 6'
...
```

listener側
```
[INFO] [1674657719.200623682] [listener]: I heard: [Hello World: 1]
[INFO] [1674657720.185435268] [listener]: I heard: [Hello World: 2]
[INFO] [1674657721.185400173] [listener]: I heard: [Hello World: 3]
[INFO] [1674657722.185484660] [listener]: I heard: [Hello World: 4]
[INFO] [1674657723.185766397] [listener]: I heard: [Hello World: 5]
[INFO] [1674657724.185551820] [listener]: I heard: [Hello World: 6]
...
```

### 最後に
この記事ではros2の環境構築について書きました。
別の記事でros2の基本的なことにも触れようと思います。
📖nbdev2をWSLで利用する手順


前記事　[【📖nbdev2入門】Dockerによる環境構築と作業手順 - Qiita](https://qiita.com/lilacs/items/19c9c572a0740c5fc548)

nbdevは、ノートブック駆動開発プラットフォームです。
公式ドキュメント（[nbdev - エンド ツー エンドのウォークスルー](https://nbdev.fast.ai/tutorials/tutorial.html#first-steps)）から以下の手順を抜粋しました。
なお、コマンドで簡単に始められるように、GitHub周りは手順の最後にまとめて実施するようアレンジしてます。

1. 環境のセットアップ
1. プロジェクト作成
1. 開発作業
1. GitHubリポジトリへのプッシュ・設定

# 想定環境
- Windows11 Pro
- WSL2 Ubuntu
- Python 3.9以上　（pipでパッケージ管理）

# １．環境のセットアップ

| **作業**                                         | **コマンド**                                                 |
| ------------------------------------------------ | ------------------------------------------------------------ |
| **nbdevをインストール**                           | `pip install nbdev` |
| **WSL再起動**<br/>（nbdev_*コマンドが見つかるようにするため。）| PowerShellで<br/>`wsl --shutdown`<br/>`wsl` |
| **Quartoをインストール** | `nbdev_install_quarto`     <br>※Python 3.9以上が必要                      |

# ２．プロジェクト作成
以下のコマンドは、リポジトリとして初期化したいフォルダで実行すること。

| **作業**                                         | **コマンド**                                                 |
| ------------------------------------------------ | ------------------------------------------------------------ |
| **nbdevプロジェクトとして初期化**                           | `nbdev_new` |
| **Gitリポジトリとして初期化**                           | `git init` |
| **Git Hookインストール**                     | `nbdev_install_hooks`                                          |
| **セットアップできたか確認**  <br>（Quartoサーバ起動） | `nbdev_preview`<br>http://localhost:****/ へアクセス（ポート番号は起動のたびに変わる）    <br>※自作ライブラリが読み込めなくて失敗するときは「pip install -e .」で編集可能インストールすること |

# ３．開発作業

| **作業**                                             | **コマンド**                                                 |
| ---------------------------------------------------- | ------------------------------------------------------------ |
| **Jupyter Lab起動**                         | `jupyter lab`  |
| **Quartoサーバ起動**  <br>（ドキュメント確認のため） | `nbdev_preview`     <br>※自作ライブラリが読み込めなくて失敗するときは「pip install -e .」で編集可能インストールすること |
| **（Notebookを編集する）**                         |   （Notebookを更新するとQuartoドキュメントがホットリロードされるはず。されないときはQuarto再起動を試すこと。）  |
| **コミット前の確認**  　<br>（テスト、ライブラリビルド） | `nbdev_prepare`                                                |
| **（Git コミット、プッシュ）**                           |  -                                                            |

# ４．GitHubリポジトリへのプッシュ・設定
| **作業**                                         | **コマンド**                                                 |
| ------------------------------------------------ | ------------------------------------------------------------ |
| **GitHubリポジトリへプッシュ** |  |
| **GitHub Pagesの設定**<br>（必要に応じて）       | GitHubプロジェクトの設定ページで設定。  gh_pagesブランチのルートフォルダをドキュメント置き場に使う。 |


<!--
| **ライブラリの出力**                             | `nbdev_export`                                                 |
| **自作ライブラリのインストール** | `nbdev_install`     <br>※Python 3.9以上が必要                      |

-->
p5.jsを用いたhtmlファイルをローカルで直接開いた際のLoading...について

初投稿です．
普段はUnityをいじっているのですが，学校の課題をリメイクしたいなと思いp5.jsを触っていたら表題の件で詰まったのでメモしておきます
# 環境
* Visual Studio Code ver1.74.3
* [p5.js web editor](https://editor.p5js.org/)

# トラブルについて
p5.jsで作成したデザインをウェブサイトの背景に設定し，フォルダからhtmlファイルを直接開こうとすると...
![スクリーンショット 2023-01-25 225844.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3114109/bf8cebd3-1185-c7d0-d146-ca833e3cac38.png)
このように「Loading」の文字が表示され，肝心のデザインが表示されません．
本当はこんな風な背景が表示されるはずなのに...
![Videotogif.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3114109/2230ac9c-288b-f5ce-c582-284a2c318bb0.gif)

# 結論
teratailに同じ質問がありました．
[JavaScript(p5.js)で画像が読み込めない。](https://teratail.com/questions/216753)

htmlファイルを直開きでは見えない仕様のようです．
vscodeでlive serverを使用したときは問題がなかったにもかかわらず，htmlファイルを開いたときには確認できなかったので，なにか問題があるのかと思いましたが，そういうわけでもないようです．live serverを通して確認するのが普通といった感じでしょうか？

問題は問題ではなかったということで，これからはlive serverで確認しながらリメイクを続けていこうと思います．
Azure Web Appsを使ってみてなんか気になったところ

Azure Web AppsでFlaskデプロイしたのですが、その仕組みやらなんやらがわからず混乱しているという記事というかメモです。

### 1なぜコマンドプロンプトやPowerShellでコマンド入力せずに動くのか。
私はVScodeを使ってPythonやらFlaskやらのフレームワークを使ってコードを書いています。そのときに、コマンド入力したり、Pathを入力することで、実行しています。
しかし、AzureWebAppsでは主に
・Azure Portalで設定し、
・Githubと連携し、
・Github Actionsのワークフローが自動設定され、
・デバッグすることで、
なぜか動いているんです。
コマンド入力することでファイルが動くことを当然視していた私にとって、これは非常に奇妙に映るわけです。

設定することで動くPaaSやホスティングサービスの例はあります。
例えば、Heroku。HerokuにはProcfileという「最初にこれを設定して、あれを動かして」といった具合に手続きをHerokuに伝えるファイルがあるようです。

調べてみるとAzureWebAppsにもありました。
https://learn.microsoft.com/ja-jp/azure/app-service/configure-language-python#container-startup-process?appservice=startup

では設定しない私のファイルやコードはなぜ動いているんでしょうか。
~~~Python:run.py
from flask_app import app
if __name__ == __main__
    app.run()
~~~
まさにこのファイルが認識されて動いてました。なぜ？？？よくわかりません。

### 2 Tips Flaskでキー取得にapp.configではos.environ.get使った方がいいかも
私はapp.configではos.environ.getでファイルではなく、変数として読み込むことで動きました。
使う場面ですが、Flaskではセッションを使うにあたって、SECRET_KEYが必要になります。これは人にたやすく見せてはいけないものであり、隠す必要があります。
Flask公式ドキュメントではベストな構成としてOSの環境変数からファイルを探す`app.config.from_envvar ('config.cfg')`などを使えと書いてあります。ただ、PaaSではOSが変わるため、そのままでは動きません。
なので、AzureWebAppsでconfiguration / 構成というメニューがあるため、そこにいき、SECRET_KEYを書きます。
そこで、ファイルから読み込むのではなく、変数を取得する方法を用い、
~~~Python:flask_app.py
app.config[SECRET_KEY] = os.environ.get('SECRET_KEY')
~~~
とするとうまくいきました。
これによってGitのファイル、gitignoreで隠してしまうとファイルがそもそも参照できないという矛盾を克服できるのです。

おそらく初心者ではない人はこんなことせずに解決する方法があると思うので、調べてみてください。私にはわかりません。
Class#getResourceAsStream(String) の引数に指定する値は何？

以下のいずれかです。

* クラスパス直下にある場合は、 `/hoge.txt` のように「スラッシュ ＋ ファイル名」を指定
* クラスのパッケージ名と同じ場所にある場合は、`hoge.txt` のように「ファイル名」を指定

詳しくは [Class#getResourceAsStream(String name) - JavaDoc](https://docs.oracle.com/javase/jp/19/docs/api/java.base/java/lang/Class.html#getResourceAsStream%28java.lang.String%29) を参照し…、分かりにくいので解説します。

# 「スラッシュ ＋ ファイル名」で指定する場合

通常、`resources` からのパスを指定する場合に使います。
![resources 直下に sample.txt を配置](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/205989/5df3cdd4-7d28-e9aa-c4d4-2d3340db25ef.png)
上の図では `resources/samaple.txt` にファイルを配置しています。
これを jar ファイルにコンパイルした場合、クラスパス直下に `sample.txt` が配置されます。
![resources 直下に sample.txt を配置した場合のコンパイル結果](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/205989/a49e4718-5041-e5fa-5bc2-374b5e8ea318.png)
そのため、 `Main.class.getResourceAsStream("/sample.txt")` とすれば、`sample.txt` の `InputStream` を取得できます。

# 「ファイル名」で指定する場合

通常、`resources/<パッケージ名>` の位置にあるファイルを指定する場合に使います。
![パッケージ階層と同じ場所に sample.txt を配置](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/205989/e1c76d93-392a-281f-1083-89a2ecd07f47.png)
上の図では `resources/org/example/samaple.txt` にファイルを配置しています。
これを jar ファイルにコンパイルした場合、`org/example/sample.txt` に配置されます。
![パッケージ階層と同じ場所に sample.txt を配置した場合のコンパイル結果](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/205989/bbeb7b19-1e5c-8cfc-958f-901cdce2a007.png)
そのため、`Main.class.getResourceAsStream("sample.txt")` とすれば、`org/example/sample.txt` の `InputStream` を取得できます。
C# namespaceない し、 using ない けど呼び出せてる。なぜ

## はじめに
C#のコード内に名前空間(namespace)が書いていないクラスがありました。
![VisualStudio_ライブラリ状態.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/568190/7a33adf3-a359-13f4-366d-d4b3e799473c.png)

usingでも指定されていません。
なのに他のクラスから呼び出しが出来ている。
不思議。


![main.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/568190/af4a2509-52a6-333c-d3d3-294ecfa0e2d8.png)


「C# namespace ない」「C# namespace usingない」などで検索してもグローバル名前空間の話や、名前空間を参照できないと思った回答が出ず。
先輩に助けてもらったので記事にします。

## 対象者
この記事は下記のような人を対象にしています。

- 私のようにVisual StudioでC#のコードを久々に見た人
- プログラミング初学者

## 結論
ライブラリとして参照に追加されていると、namespaceがなくても動きます。


## ライブラリ作り方
新規プロジェクトをクラスライブラリとして追加します。
![VisualStudio_ライブラリ追加.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/568190/83d81212-b7b7-39d3-94a6-a471002223d6.jpeg)

コードを書きます。
![VisualStudio_ライブラリ状態.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/568190/ccb7bc0c-9d8d-52c3-9984-a9e443a12d9f.png)


ビルドしてdllを作成します。(ライブラリはexeの代わりにdllを作成します)

## ライブラリをプロジェクトへ追加

ライブラリを追加したいプロジェクトの参照を右クリックして、参照の追加からライブラリのdllを選択します。

![VisualStudio_ライブラリ追加方法1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/568190/a9842049-6820-9c40-0145-0710be31e640.jpeg)

同じソリューション内のプロジェクトであれば、参照マネージャー->プロジェクト->ソリューションから追加することも可能です。

あとはライブラリを追加したプロジェクトでライブラリの内容を呼び出せば完成です。

![main.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/568190/af4a2509-52a6-333c-d3d3-294ecfa0e2d8.png)


## おわりに
ライブラリの導入についてまとめました。
周りにVisualStudioやC#を使える人がいないと、サイトの専門用語も分からず、中々難しく感じています。
おすすめできる書籍も先輩は思い当たらないようですし、実務で学んでいきますが、もう少し初心者目線での記事が増えると楽しいなと思います。
間違いなどがありましたら、ご指摘いただけると助かります。