OmniAICreator/Qiita-1.07M huggingface dataset:
【図解】メール認証とDNS

## 概要

メールの送信元認証を、DNSの観点から学習し、図解してみました。

## 学習内容

**送信元メールアドレスを偽装することは比較的簡単**で、なりすまし・標的型攻撃によく使われます。私のYahooメールにも、偽Amazonから「アカウント停止するぞ」メールが頻繁に来ています。登録情報が不完全だからって、天下のAmazon様が末端ユーザのアカウントを停止するなんて、特にメリットがないと思うんですけどね。

**偽装メール対策として、メールの送信元が正しいかを認証**する仕組みがあります。今回は、以下の3種類の技術について調べてみました。

* **SPF**(Sender Policy Framework)：送信元IPアドレスの認証
* **DKIM**(DomainKeys Identified Mail)：電子署名による認証
* **DMARC**(Domain-based Message Authentication, Reporting, and Conformance)：認証失敗時の動作定義

これらの技術は、**DNSのTXTレコードを使っている**点で共通しています。TXTレコードを使って、決められた文字列をやりとりすることで、送信元の認証や認証失敗時の動作定義をしています。

## 図解①：Alice→Bob

下図が、メール認証とDNSの全体像です。業界スタンダード？の、Alice(example.com)からBob(example.net)にメールを送るシチュエーションですね。図の左上部がAliceが送るメールの情報です。

![メールDNS1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/464218/20bca43e-1573-5e6e-2be3-4e659db2ad10.png)

Aliceからのメールを受け取ったexample.netのメールサーバは、**送信元メールアドレスであるexample.comのDNSサーバに問い合わせ**を行います。

### SPF

SPF認証では、**メール送信元のIPアドレスと、SPFのTXTレコードに記載されているIPアドレスを比較**して検証します。送信元の住所として記載されたものが合っているか、Alice本人に電話して確認するようなイメージですね。

TXTレコードには、送信元として許可されたIPアドレス(FQDNでも可)と、認証結果の処理内容が記載されます。ただし、認証結果の処理内容はゆるい定義でしかなく、最終的には受信側の設定に依存します。

### DKIM

DKIM認証では、**秘密鍵と公開鍵の仕組みを使って送信元を検証**します。メール送信元が秘密鍵を使って電子署名を行い、メール受信者が公開鍵を使って電子署名を検証します。Aliceが特殊な印鑑を押して、Bobがその印影を確認するイメージですね。

TXTレコードには、電子署名の公開鍵が記載されます。また、TXTレコードのホスト名として、[セレクタ名]._domainkeyが使われます。

### DMARC

DMARCは、**認証失敗時の動作を定義する仕組み**です。SPF認証やDKIM認証だけでは、認証失敗したメール(なりすましメール)が受信側でどう処理されたか、送信側は把握できません。DMARCを使うことで、認証失敗時の動作ポリシーを送信側が公開し、受信側の動作をコントロールしたり、受信側からレポートを上げさせたりすることができます。

TXTレコードには、認証失敗時のポリシー(none、reject、quarantineなど)や、レポートの送付先を指定できます。また、TXTレコードのホスト名として、_dmarcが使われます。

### 結果

上図では、SPF認証・DKIM認証ともに問題ないので、DMARCの記載は無視して、**Bobはメールを受信します**。
※DKIM認証の値は一致しませんが、イメージで…

## 図解②：Mallory→Bob

次に、AliceになりすましたMalloryが、Bobにメールを送るシチュエーションで考えてみましょう。

![メールDNS2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/464218/27f119b5-fe35-6fc7-b984-140e3a9e94bd.png)

送信元のMalloryは、**送信元メールアドレスをAliceのものに偽装し、電子署名を付与**して、Bobにメールを送信しました。受信側のBobは、送信元メールアドレスexample.comのDNSサーバに問い合わせて検証を行います。

### SPF

SPF認証では、メールのIPアドレス198.51.100.1と、SPFレコードを比較します。＋で許可された192.0.2.1/32とは合致しないため、~allに該当することになります。~は、不正メールとして処理されるが、配信もされる識別子です。

よって、この時点では、**SPF認証はNGだがメール受信はする**、という状態です。

### DKIM

DKIM認証では、DKIMレコードからAliceの公開鍵を取得し、メールに付与された電子署名と検証します。検証の結果、Aliceの秘密鍵で作成された電子署名ではないことがわかりました。

**DKIM認証はNGですが、DKIMは受信側の動作には干渉しない**ので、メール自体は受信する状態です。

### DMARC

DMARCでは、DMARCレコードの記載に沿って、認証失敗時の受信動作を確認します。Aliceの属するexample.comのDMARCレコードには、認証失敗時は受信しない(p=reject)、と定義されています。また、DMARCレコードに記載されたdmarc@example.comに対して、集計レポート・認証失敗レポートが送信されます。

### 結果

今回はSPF・DKIMともに認証失敗しているので、**受信側のexample.netは、送信側のDMARCレコードの動作定義に従い、このメールを削除**します。よって、Bobがこのメールを目にすることはありません。

## 所感

以上、メール送信元認証の仕組みを、DNSの観点から見てきました。

他のレコードと比較して、TXTレコードは記載の自由度が高く、何に使われているかがわかりにくいものでした。メール送信元認証を通じて、使われ方の一例を知ることができました。

SPF・DKIMでは検知だけを行い、透過or削除の動作定義はDMARCで行う、という点が特徴的だと感じました。ネットワークにおけるIDSとIPSに似ていますが、検知と防御を兼ねるIPSに対して、DMARCは防御専門ですね。

また、記載を間違えれば動作しなかったり、意図しない動作になったりします。~allと-all(チルダとハイフン)とか、紛らわしいです… DNSに限らず、事前の動作検証が大切だと思いました。

実際の運用では、認証失敗したら即削除、みたいなハードな設定は少なそうです。上記の例のようにDMARCの動作をrejectにするのは、結構勇気がいりますね。

https://note.com/anpanda_44075/n/n37a45db22971
ノードオブジェクトからChef-Zeroへのアトリビュート渡し

Chef-Zeroにノードオブジェクトでアトリビュート値を渡す際に試行錯誤があったので備忘として残す

# 環境

AIX: 7300-00-01-2148
Chef-client: 14.15.6

# サンプルChefレポジトリ
```
/chef-repo
├── LICENSE
├── README.md
├── chefignore
├── cookbooks
│   ├── README.md
│   └── example
│       ├── README.md
│       ├── attributes
│       │   └── default.rb
│       ├── metadata.rb
│       └── recipes
│           └── default.rb  # 編集
├── data_bags
│   ├── README.md
│   └── example
│       └── example_item.json
├── environments
│   ├── README.md
│   └── example.json
├── nodes
│   └── node1.json  # ユーザー作成のノードオブジェクト
└── roles
    ├── README.md
    └── example.json
```


ノードオブジェクトとレシピを除き、chef generate repoにて作成した素のchef-repo。

# サンプルレシピ


```ruby:/chef-repo/cookbooks/example/recipes/default.rb
# frozen_string_literal: true

log "Welcome to Chef, #{node['foo']}!" 
```
chef generate repoにて作成したexample cookbookのrecipeを編集


# サンプルノードオブジェクト
```json:/chef-repo/nodes/node1.json
{
  "name": "node1",
  "normal": {
    "foo": "bar"
  },
  "run_list": ["recipe[example::default]"]
}
```
- ディレクトリー
    - cookbooksと同列のnodesとする。
    - 他ディレクトリーの場合、ノードオブジェクトで設定したアトリビュートがnode.normal['foo']などとしてしか参照されなかった。
- ファイル名
    - <ホスト名>.jsonとすると収束後にアップデートされるので分かり易いかと。
- "name": 
    - 必須ではないが、収束後にアップデートさせると"name": "ホスト名"で項目が作成される。
- "normal":
    - ノードオブジェクトで設定できるアトリビュートはノーマルレベルであり、かつそれ以外のレベルは設定できない。他レベルで記載しても"normal":レベルとして使用される。
    - そもそも"normal":を使用しなくともノーマルレベルとして使用される。
- "run_list":
    - 通常の指定と同様に、recipe[]や::defaultは省略可能
    - さらに、-oにてrun_listを指定するなら、ノードオブジェクトにて設定する必要はない。
   
# サンプルノードオブジェクト(最小版)
```json:/chef-repo/nodes/node1.json
{
  "foo": "bar"
}
```
- "normal": { } も省略
- "run_list": が無いので、chef-client実行時には-oにてrun_listを指定する必要がある。




# テスト実行
```bash
$ cd /chef-repo
$ chef-client -z -j nodes/node1.json  # run_listが未設定の場合には -o example などと追加指定
...
Starting Chef Client, version 14.15.6
...
resolving cookbooks for run list: ["example::default"]
Synchronizing Cookbooks:
  - example (1.0.0)
Installing Cookbook Gems:
Compiling Cookbooks...
Converging 1 resources
Recipe: example::default
  * log[Welcome to Chef, bar!] action write
  

Running handlers:
Running handlers complete
Chef Client finished, 1/1 resources updated in 07 seconds
```
- コマンドを実行するディレクトリーを、cookbooksと同じか、cookbooks下とすると、クックブックは自動検出される。
- -oなしでノードオブジェクト内のrun_listに従って実行する場合、<cookbooksと同列のディレクトリー>/nodes/<ホスト名>.jsonに、"automatic":などを含め、結果が記載/アップデートされる。
    - ただ、アップデートを繰り返すと "normal": { "normal": { "normal": { ... と余分な部分が増えていくため、常に-oを用いてアップデートさせない方が良いのかもしれない。増えていくのが仕様なのか障害なのかは不明。
Android/View関連のクラスの挙動を確認する手法例

今回は、Android/TextClockが、
アプリがバックグランドになった際に停止されているかを検証します。

# ソースコードの確認
[TextClock]
https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/widget/TextClock.java

TextClockのソースコードになります。
Androidフレームワークでは、
オープンソースとして公開されているため、
TextClock自体を解析します。

「TextClock#onVisibilityAggregated」で、
「Runnable mTicker」の停止/再開をしているようです。

# API仕様の確認
次は、「TextClock#onVisibilityAggregated」を調べます。
https://developer.android.com/reference/android/widget/TextClock#onVisibilityAggregated(boolean)

```
boolean: このビューとそのすべての祖先が表示され 、このビューのウィンドウも表示される場合は trueView.VISIBLE
```
英文も和訳も意味不明ですが、
「onVisibility」の語感から表示されたらtrueで、非表示でfalseになるように見えます。

# 裏付け確認用のコード作成
onVisibilityAggregatedの挙動を確認するため、
TextClockを継承した、TextClock2クラスを作成します。
[Java]
```
package jp.textclock;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.TextClock;

public class TextClock2 extends TextClock {
    // Viewクラスのコンストラクタは3つでワンセット（たぶん）
    public TextClock2(Context context) {
        super(context);
    }

    public TextClock2(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public TextClock2(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public void onVisibilityAggregated(boolean isVisible) {
        Log.d("onVisibilityAggregated", "isVisible>" + isVisible);
        super.onVisibilityAggregated(isVisible);
    }
}
```
「onVisibilityAggregated」動作でLogcat出力をするようにします。

以下は、実行時のLogcatです。
```
2022-10-17 22:47:46.059 onVisibilityAggregated isVisible>true
2022-10-17 22:47:50.340 onVisibilityAggregated isVisible>false
2022-10-17 22:47:52.990 onVisibilityAggregated isVisible>true
```
[アプリ起動時]
Logcatの1行目に「isVisible>true」が出力されています。

[アプリがバックグラウンドに移行]
Logcatの2行目に「isVisible>false」が出力されています。

[アプリがフォアグラウンドに移行]
Logcatの3行目に「isVisible>true」が出力されています。

```
super.onVisibilityAggregated(isVisible);
```
で、「TextClock#onVisibilityAggregated」が実行されるため、
- バックグラウンドで、「Runnable mTicker」の停止
- フォアグラウンドで、「Runnable mTicker」の再開
が行われていることになります。

# まとめ
調べごとがあれば、Google検索するのが一般的だと思われますが、
ニッチな内容には対応できな場合もあります。
その際に自力で調査する方法として、
一例を紹介させて頂きました。
【git】ローカルにbare repository

# はじめに

これまでGithub や Bitbucket などをremote repository としてgit push していたのですが、まぁ、そういうものが使えないときもあります。ローカルに作業を残しておくために、ローカルにremote repository を作りたい(用語は合っているかな^^;)と思って調べたら、簡単にできました。のでメモ。

# 内容

確認作業は、WSL2 の ubuntu20.04 で行いました。

## bare repository を作る

適当なディレクトリにbare repository を使います。

```
$pwd
localrepo
$ git init --bare remote.git
Initialized empty Git repository in /home/user/localrepo/remote.git/
$ ls remote.git/
HEAD  branches  config  description  hooks  info  objects  refs
```

とすると、remote.git という名前のディレクトリができました。

### push する

何か既存の作業しているlocal repository があればremote をここに書き換えるだけでよいですが、今は、適当なものを作ります。localrepo/remote.git/  とは別の所workdir で以下のようにします。

```
$ git init
Initialized empty Git repository in /home/usr/workdir/.git/
```

ここでとりあえず適当にcommit します。

```bash
$ echo "A" > a.txt
$ git checkout -b work
Switched to a new branch 'work'
$ git add -u a.txt
$ git commit -m "add a.txt"
[work (root-commit) aed953d] add a.txt
 1 file changed, 1 insertion(+)
 create mode 100644 a.txt$ git log
$ git log
commit aed953d4f506ff315c2652f641285bb870dda89a (HEAD -> work)
Author: aiu.eo <aiu@eo>
Date:   Mon Oct 17 22:24:55 2022 +0900

    add a.txt
```

remote repository は登録されていません。

```shell
$ git remote -v
```

先程作成した bare repository へpush します。相対パスで指定して、動きました。

```
$ git push -u ../localrepo/remote.git work
Enumerating objects: 3, done.
Counting objects: 100% (3/3), done.
Writing objects: 100% (3/3), 194 bytes | 194.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To ../localrepo/remote.git
 * [new branch]      work -> work
Branch 'work' set up to track remote branch 'work' from '../localrepo/remote.git'.
```

origin に登録しました。ここでも相対パスで登録できました。作業レポジトリで別のディレクトリにいても、動きました。

```
$ git remote add origin ../localrepo/remote.git
$ git remote -v
origin  ../localrepo/remote.git (fetch)
origin  ../localrepo/remote.git (push)
$ mkdir a
$ cd a/
$ git fetch
From ../localrepo/remote
 * branch            work       -> FETCH_HEAD
```

## 参考

ググって出てきたもの：

https://blog.serverworks.co.jp/tech/2019/08/30/post-73550/
https://hirocorpblog.com/git-clone-bare/

# まとめ

とりあえず、個人の作業用に、push する先としてのrepository は作れた。これで明日も生きていけるかな。

todo: 本家の解説、あれば読みたい。
(2022/10/17)
Streamlit から Databricks に接続してデータを取得するには？


# はじめに

StremlitとDatabricks連携については既に@taka_yayoi さんの記事「[StreamlitからDatabricksでサービングしている機械学習モデルを呼び出す](https://qiita.com/taka_yayoi/items/ce79c29df59a99bf872b)」がありましたが、今回は単純にデータを取得する方法を試してみました。

# 接続方法

今回は[Databricks SQL Connector](https://learn.microsoft.com/ja-jp/azure/databricks/dev-tools/python-sql-connector)を利用しました。pyodbcよりも簡単でライブラリーもpipで取得できます。

# 準備

Databricks環境の以下の情報が必要になります。
- Workspace ホスト名
- HTTP Path名
- Token 

SQLウェアハウスを作成し、「接続の詳細」から**ホスト名**と**HTTP Path**を取得できます。またTokenも同じ画面の右下の「パーソナルアクセストークンを取得」から取得できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2206424/f052b56b-35c7-b5ec-6652-9886f0fcee30.png)

# データ準備
次にデータ取得のためのテーブルを作成します。すでに取得したいデータがある場合はスキップしてください。
Databricksのノートブックもしくは、SQLエディタから以下を実行します。

```sql:
CREATE TABLE IF NOT EXISTS small_table
USING CSV
OPTIONS (path "/databricks-datasets/asa/small/small.csv", header "true", mode "FAILFAST")
```

データエクスプローラでテーブルを確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2206424/9ecf2a34-df37-686d-f8ea-64e5ac45dd1d.png)


# コード作成
今回は２つのファイルを用意します。

```:requirements.txt
databricks-sql-connector
```

`DATABRICKS_SERVER_HOSTNAME`,`DATABRICKS_HTTP_PATH`,`DATABRICKS_TOKEN`は後ほどStreamlitのSecretsに登録します。

```python:app.py
import streamlit as st
from databricks import sql
import pandas as pd
import os

@st.experimental_singleton
def init_connection():
    return sql.connect(
        server_hostname = st.secrets["DATABRICKS_SERVER_HOSTNAME"],
        http_path       = st.secrets["DATABRICKS_HTTP_PATH"],
        access_token    = st.secrets["DATABRICKS_TOKEN"])

conn = init_connection()


@st.experimental_memo(ttl=600)
def run_query(query):
    with conn.cursor() as cur:
        cur.execute(query)
        return cur.fetchall()

# Print results.
st.title("Streamlit & Databricks Demo")
st.subheader("Databricks SQL Connectorを使って、Databricksのデータにアクセスする")

full = run_query("select * from small_table limit 5")
st.table(full)

rows = run_query("select Origin, count(*) as count from small_table group by Origin")
df = pd.DataFrame(rows, columns=["Origin","count"])
st.bar_chart(data=df, x="Origin", y="count", width=0, height=0, use_container_width=True)
```


# Gitリポジトリの作成とコードのプッシュ

Streamlit CloudはGitと連携するため、リポジトリを作成しコードを保存しておきます。
今回作成したリポジトリーはこちらです。クローンしてご利用ください。

https://github.com/maroon-spec/streamlit-sql-demo.git

# Streamlit Appの作成

今回はStreamlit App作成方法は割愛します。他にたくさんの記事がありますのでそちらをご覧ください。

# Secretsの作成

Streamlit Appがデプロイされましたら、**Settings**からSecretsを作成します。今回は最初に準備した以下の３つを記述します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2206424/ffabd7b9-47b8-b570-694a-91758f69a099.png)


# Appの表示

無事にDatabricksからデータを取得して表示できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2206424/4ad97952-cbc5-793c-a643-e0a6c513da6c.png)


# Databricks SQL Connectorについて

従来の[pyodbcドライバー](https://learn.microsoft.com/ja-jp/azure/databricks/dev-tools/pyodbc)に比べて非常にシンプルな設定で利用できます。ただし大量のデータには向いていないのでデータ量が多い場合はpyodbcドライバーを利用した方がおすすめです。

SQL Connectorの詳細はこちらをご覧ください。
https://learn.microsoft.com/ja-jp/azure/databricks/dev-tools/python-sql-connector
Microsoft Edge IEモードの90日制限を解除するツールの作り方

MicrosoftがIE(Internet Explorer)を廃止して数ヶ月が経ちました．かつてWindowsのWebブラウザと言えばIEと言われていた時代が有ったことを思うとICT技術の移り変わりの速さは目を見張るものが有ります．IEが廃止されて困るのはIEでしか動作しない社内システムが正常に動作しなくなることです．社内システムは社外からアクセスされないため優先順位が極めて低くなるということと，長年に渡る運用期間に肥大化したために，手直しに膨大な時間と人的リソースが必要？とされるため誰も手を付けたくない触らぬ神に祟りなしということなのでしょう :scream: :scream_cat: ．本来ならば今年の6月までにEdgeやGoogle Chrome対応化が完了しておくことが理想なのですが，先述の経緯で取り残されているシステムは少なくないでしょう．そこでMicrosoftは救済策を提供しています．以下がその方法です．

https://atmarkit.itmedia.co.jp/ait/articles/2106/16/news026.html

この方法でIEモード(IE互換モード)を用いてMicrosoft EdgeでIE専用サイトを閲覧出来ます．ところがこの方法には致命的な欠点が有ります．何と<font color="RED">90日間</font>しか設定が維持されず，90日が経過すると消えてしまいます．よって再設定しなければなりません．滅多に利用しないシステムならまだしも，定期的に利用するシステムとなれば死活問題です．よって，90日制限なしにIEモードを利用する方法はないものかと色々探っているとレジストリを操作することで，90日制限に悩む必要が無くなるとのこと．しかし，レジストリをマウス操作で編集するのは煩雑な上に，失敗すると最悪PCが起動しなくなります．よって今回は実験環境のVM上でPower Shellを用いてレジストリ操作を行うスクリプトを作成して，期間制限の無いIEモードを実現したいと思います．

# スクリプトの実装
スクリプトはPower Shellで実装しました．実は筆者はかつてPower Shellを業務で利用して散々な思いをしたため，正直な所，Power Shellは嫌いです．一瞬Pythonで実装しようかと思ったのですが，Pythonで実装してしまうと，実行するための環境を用意するのが難しい環境では実行できないため，Windows標準のシェルであるPower Shellで実装することにしました． :dancer: :dancer_tone1: :dancer_tone2: :dancer_tone3: :dancer_tone4: :dancer_tone5: 

```powershell:実装したスクリプト
copy ie_mode_list.xml c:\
reg add "HKCU\SOFTWARE\Policies\Microsoft\Edge" /v InternetExplorerIntegrationLevel /t "REG_DWORD" /d "1" /f
reg add "HKCU\SOFTWARE\Policies\Microsoft\Edge" /v InternetExplorerIntegrationSiteList /t "REG_SZ" /d "c:\ie_mode_list.xml" /f
pause
```

以下のサイトを参考にしてスクリプトを作成しました．大変有益な情報をアップしてくださっている方々に感謝です．

## 参考資料

https://watapipi.com/edge_iemode/#EdgeIE

https://www.pasoble.jp/tips/automatic-ie-mode.html#c1b

https://qiita.com/tukiyo3/items/c09d40715fe643b52a07

# URLリストを作成
IEモードで開くURLのリスト(XML形式)を作成します．上記スクリプトで登場しているファイル名に合わせるならば，`ie_mode_list.xml`です．このリストの作成はMicrosoftの公式サイト(IEモードで開くサイトを管理するツールのドキュメント)が非常に参考になりました．

```xml:IEモードで開くサイトのURLリスト(XML形式)の記載例
<site-list version="221017.0">
    <site url="http://example.com">
        <compat-mode>Default</compat-mode>
        <open-in allow-redirect="true">IE11</open-in>
    </site>
</site-list>
```

## 参考資料

https://learn.microsoft.com/ja-jp/internet-explorer/ie11-deploy-guide/enterprise-mode-schema-version-2-guidance#enterprise-mode-v2-schema-example

# 2022/10/20追記: IEモードが不要になった時のために
IEモードが不要になった時のためのスクリプトを追加しました．

```powershell:レジストリのEdgeキーを削除するスクリプト
reg delete "HKCU\SOFTWARE\Policies\Microsoft\Edge" /f
pause
```

## 参考資料

https://learn.microsoft.com/ja-jp/windows-server/administration/windows-commands/reg-delete#parameters

# 完成したツールを公開
完成したツールをGitHubで公開しました．友人からこのツールを欲しいと言われていたので，GitHubで公開しておけば共有もし易いなという判断です．具体的な使い方のマニュアルもREADMEとして記載しています．MITライセンスですのでIssue(バグ，要望), Pull Requestは大歓迎です．

https://github.com/y-vectorfield/unlimited_ie_mode_tool

# まとめ
社内システムでIEモードで利用する必要が有るシステムが幾つか有り，加えて頻繁に利用するため，90日制限で再登録は煩わしいなと感じていた時にPower Shellで自動化出来ることを知りました．しかし，IEモードはあくまで一時的な弥縫策であるため，1日も早くEdgeかChromeに対応してくれればと願いつつ，暫くはIEモードのお世話になることとします．

# Reference

https://kondeneenen.com/powershell_digitalsignature/

https://www.curict.com/item/d1/d1c4a3e.html

https://qiita.com/KentaKimura/items/d9926cbac860d9bd019b

https://www.javadrive.jp/xml/ini/index5.html
JuliaをJupyter Notebookで利用できるようにした

## 概要
windowsで、JuliaをJupyter Notebookで利用できるようにする方法について書きました。

## Jupyter Notebookをダウンロードする
Jupyter Notebookをインストールする方法は、主に二つあります。

1. Anacondaをダウンロードする
2. Jupyter Notebookのみダウンロードする

今回はAnacondaをダウンロードしJupyter Notebookを使えるようにしていきます。
https://www.anaconda.com/products/distribution

![andaconda-install.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516887/b904ba04-dc76-efa6-349d-502b9154d9c1.png)


## Juliaをダウンロードする
公式ホームページよりJuliaをダウンロードします。私はWindows 64-bit (installer)を選択しました。
https://julialang.org/downloads/

![julia-dawnload.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516887/0b45dcd0-359f-74ad-1394-768578dd0781.png)

## Juliaを起動
ダウンロードが終わったら起動しましょう。ダウンロードできていれば以下のような画面を表示できると思います。

![julia-start.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516887/d35070fe-e078-8eb4-20b4-70cb6bc688f1.png)

## JuliaをJupyter Notebookに接続する
juliaをJupyter Notebookに接続していきます。

JuliaをJupyter Notebookで利用するためには、IJuliaというパッケージが必要となります。
以下の手順でIjuliaをインストールします。

```
julia> ]

(@v1.8) pkg> add IJulia
```

インストールが完了したら、backspaceを押してjuliaモードに戻り、以下を実行します。

```
julia> using IJulia

julia> notebook()
```

すると、ブラウザにJupyter Notebookが立ち上がります。
右上の"new"というタブを押したときに、juliaが表示されていれば成功です。 

![jupyter-notebook.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516887/54b28851-545f-b195-155f-aa926db54196.png)
Landing Zone とは

## 勉強前イメージ

聞いたこともないかも

## 調査

### Landing Zone とは

ランディングゾーンと読み、AWSのベストプラクティスに基づいて作成されたアカウントを展開していく仕組みになります。
あくまで、Landing Zoneはサービスではなく仕組みです。
多数のアカウントのセキュリティなどを一定に保つためのものです。

### Landing Zoneの機能

- 必要な初期設定が完了しているアカウントの作成します
- 管理用の権限を発行、アカウントを管理するための権限を作成します
- SSOによるアカウントのアクセス管理をします
- ネットワークのベースラインを確保します
- AWSのログを一元的に保存します
- ガードレールを設置します

### Landing Zoneの利用方法

- Control Tower を使う

[Control Tower](https://qiita.com/miyuki_samitani/items/210a359f44b602aac1ec) はLanding Zoneを実現するもので簡単にセットアップが出来ます。

- 独自で実装

Organizationsやconfigなどを使って構築します。
カスタマイズが自由ですが構築をする大変さがあります。

## 勉強後イメージ

どっちかというとControl Towerの機能って感じがしてる・・・
合ってるんかな？

## 参考

- [AWS再入門2020 AWS Control Tower編](https://dev.classmethod.jp/articles/re-introduction-2020-control-tower/)
- [AWS Control Towerを活用したランディングゾーンの構築](https://d1.awsstatic.com/Compliance%20V2/JP_Security%20and%20Compliance/AWS%20ControlTower-and-Landingzone-SolutionDays2019_JP.pdf)
- [【お知らせ】AWS Control Towerが東京リージョンで利用可能に](https://www.sunnycloud.jp/column/20210413/)
４０代おっさんPythonを勉強する（名前空間とスコープ編）

## 本記事について

この記事はプログラミング初学者の私が学んでいく中でわからない単語や概要を分かりやすくまとめたものです。
もし不正などありましたらコメントにてお知らせいただければ幸いです。

## 名前空間とスコープ

- 各関数はそれぞれ専用の名前空間を定義される
- メインの領域のグローバルスコープ(大域空間)と関数内のローカルスコープ(局所空間)が分かれている
- 大域空間ではグローバル変数を定義し、局所空間ではローカル変数を定義する
- グローバル変数の値は関数内から参照できる

```python
#  id()関数はPythonが全ての変数を識別するための番号

name = 'としき' # グローバル変数
print('グローバル：',  name, id(name))
def show_name():
    print('内部関数：', name, id(name))

show_name()
print('グローバル：', name, id(name))
```

こちらはエラーが起きる

```python
name = 'としき' # グローバル変数
print('グローバル：',  name, id(name))
def show_name():
    print('内部関数：', name, id(name))
    name = 'あっきー'

show_name()
print('グローバル：', name, id(name))
```

```python
---------------------------------------------------------------------------
UnboundLocalError                         Traceback (most recent call last)
セル1 を c:\Users\toaik\OneDrive\デスクトップ\python\enPiT\kansuu\namaekuukan.ipynb in <cell line: 9>()
      6     print('内部関数：', name, id(name))
      7     name = 'あっきー'
----> 9 show_name()
     10 print('グローバル：', name, id(name))

セル1 を c:\Users\toaik\OneDrive\デスクトップ\python\enPiT\kansuu\namaekuukan.ipynb in show_name()
      5 def show_name():
----> 6     print('内部関数：', name, id(name))
      7     name = 'あっきー'

UnboundLocalError: local variable 'name' referenced before assignment
```

- もし、関数内に同じ変数名を新たに定義すれば、それはローカル変数になる
- ２つの変数は同じ名前になっても、別々のものとされる

```python
name = 'としき' # グローバル変数
print('グローバル：',  name, id(name))
def show_name():
    name = 'あっきー'
    print('内部関数：', name, id(name)) # idが異なる
    
show_name()
print('グローバル：', name, id(name)) # グローバル変数の値は変わらない
```

グローバル： としき 2389997792592
内部関数： あっきー 2389965814640　ここだけがIDが違う
グローバル： としき 2389997792592

- 関数内でもグローバル変数を編集できる(編集はしないほうが良い)

```python
name = 'としき' # グローバル変数
print('グローバル：',  name, id(name))
def show_name():
    global name # グローバル変数だと明示
    name = 'あっきー' # 値を変更
    print('内部関数：', name, id(name)) # 新しいIDになる
    # IDが変わったのは文字列型が変更不能のため
    
show_name()
print('グローバル：', name, id(name)) # グローバル変数の値は変わらない
```

グローバル： としき 2389965814064
内部関数： あっきー 2390001760656
グローバル： あっきー 2390001760656

- もしやるならグローバル領域で代入するほうがよい

```python
name = 'としき' # グローバル変数
print('グローバル：',  name, id(name))
def show_name():
    name = 'あっきー' # 値を変更
    print('内部関数：', name, id(name)) # 新しいIDになる
    return name
    
show_name()
print('グローバル：', name, id(name)) # グローバル変数の値は変わらない

name = show_name()
print('グローバル：', name, id(name))
```

グローバル： としき 2389965781584
内部関数： あっきー 2390001760656
グローバル： としき 2389965781584
内部関数： あっきー 2390001760656
グローバル： あっきー 2390001760656

- 引数で同じ変数名を使ってもグローバル変数を編集できない

```python
name = 'としき' # グローバル変数
print('グローバル：',  name, id(name))
def show_name(name):
    print('内部関数：', name, id(name)) # 古いIDになる
    name = 'あっきー' # 値を変更
    print('内部関数：', name, id(name)) # 新しいIDになる
    
show_name(name)
print('グローバル：', name, id(name)) # グローバル変数の値は変わらない
```

グローバル： としき 2389997633584
内部関数： としき 2389997633584
内部関数： あっきー 2390000480048
グローバル： としき 2389997633584

- プログラムを書くとき、グローバルかローカルか、気を付けないと違う変数の値を変えてしまうから、デバックも難しくなる

## 参考

https://www.kitakyu-u.ac.jp/news/2022/08/003215.html
2022 サマーインターン体験記

# 概要
この記事は、いい生活サマーインターン2022の参加記です。また、インターン参加に至るまでの過程を書いていきます。
これからインターンに参加する人の参考になればと思います。

# 著者のスペック
* atcoder 茶色
* 基本情報
* 趣味での作品開発経験

# いい生活とは
ホームページ　https://www.e-seikatsu.info/

# インターンまでにしたこと
私がインターン参加に至るまでにしたことを書いていきます。
* **2022夏ITエンジニアインターンのスプレッドシートにて参加したいインターンを探す。**
* **pythonプログラミング言語を用いて作品を制作。**
* **自分が今までやってきたことをまとめる（面接でかなり大事）**

といった感じです。

一応10社くらい応募しましたがインターンに受かったのは2社だけでした。
**(お祈りメールが来るとかなりへこみますw）**

# 選考の流れ
**エントリーシート提出→面談→合否の通知**　でした
ほかの企業だとコーディングテストや選考課題などがあるところが多い印象でした。
受かったもう一つの企業は選考課題がありました。

* **面談で聞かれたこと**
    * 学校生活で頑張っていること
    * サマーインターンに参加したい理由
    * 今までに何か作品を作ったことがあるか

主に聞かれたのはこれくらいです。深く聞かれた記憶があります。

# インターンの中身
**1. 事前準備**
インターンを迎える前にオンラインで開発環境を構築しました。
* Gitのinstall
* Vueのinstall
* VPNの設定
* Zoomのinstall
* slackの設定

**2.インターン当日**

* 1日目
    * チームの顔合わせ、開発で使う言語の講義
    * 誰に対してサービスを提供するか（ペルソナの決定）
    * どのような機能を実装するかの決定（要件定義）

* 2~4日目
    * 各々が機能を完成させていく。
    * 開発の合間に社員さんとの座談会（雑談や企業の説明)

* 5日目
    * 作品を完成させたのちに発表(パワポ）
    * チームで振り返り

**3.成果物**
作ったものとしては物件検索Webアプリです。(suumoとかをイメージするといいかも）
機能としては居住形態（アパート、マンション）や家賃などを指定して、プレート形式で条件に合った物件を表示させました。

* 良かった点
  gitを使った開発ができた。
チーム開発のメリットを知ることができた。(問題解決が早い)
  事前に誰に何を提供するかの整理をできた。
    
* 苦労した点
Vueを初めて触ったため、思ったようにコーディングができなかった。（チームメンバーやメンターさんに相談してなんとかなった）
  APIの中身を理解したり、中身の情報をどう整形するかでかなり時間を使った。（不動産のAPIは中身が膨大だったため。）
  オンラインだったため、コミュニケーションが少し難しかった。
  cssが何もわからなかったため、デザイン面で苦労した。(チームメンバーに詳しい人がいたためなんとかなった）

**4.インターンを通じてわかったこと**
今回はIT×不動産という事業形態だったため限定的になるが、エンジニアはプログラミングだけでなく不動産の知識（宅建など?）も必要だと知った。結局、**誰に**サービスを提供するのかがわからないと厳しいものがある。
当然だが、大学での講義だけでしかプログラミングを触れる機会がない人はインターンに受かるのは厳しい。具体的にこれをやっておけばいいということはないが、競技プログラミングが一番手っ取り早いと思う。（1,2年生向け）
コーディングテストについては競技プログラミングに似た問題がよく出ていたので、競技プログラミングをやっておくと自然に対策にもなる。
資格は持っていたほうがよいが、絶対に必要なわけではない。個人的には知識を身に着けるということが大事だと思う。

# まとめ
使った技術
* Vue(フレーム) + Typescript(言語)
* Git(ソースコードの共有)
* Gather(discordみたいなもの)
* slack(コミュニケーションツール)
* Visual Studio Code(開発環境)

やっておいたほうがいいこと
* 何かしらの開発経験を積んでおくこと
* 競技プログラミング(コーディングテストや選考課題対策)

# 終わりに
最後まで読んでいただきありがとうございました。
何か質問があれば聞いてください。
php　emptyで0も空になる


# empty()は0も入る
phpの`empty()`を実行すると0も空になる

```
$ php 221015.php
[0=>グー,1=>チョキ,2=>パー]:0
empty
0
```
簡単なじゃんけんを作って実行

こうならないために
```empty.php
    if($stdin_num === ""){
        echo 'empty'.PHP_EOL;
        return false;
    }

```
でしてみた。もっと簡単な方法探す。
文字列は判定してくれるかも。
# 参考

https://qiita.com/shinkuFencer/items/48718f0c8d203ca513db#%E7%A9%BA%E6%96%87%E5%AD%97%E5%88%A4%E5%AE%9A%E3%81%A8%E3%81%97%E3%81%A6%E3%81%AEempty
VagrantでWebサーバー構築

# 仮想環境にApacheをインストール
Vagrantで仮想環境を立ち上げ、Apacheのインストール
```
$ vagrant up
$ vagrant ssh
[vagrant@localhost ~]$ sudo yum -y install httpd
Installed:
  httpd.x86_64 0:2.4.6-97.el7.centos.5
Complete!
```


# Apacheの起動
Apacheの起動
```
[vagrant@localhost ~]$ sudo systemctl start httpd
[vagrant@localhost ~]$ sudo systemctl status httpd
Active: active (running)
```
システム起動時にApacheの自動起動設定
```
[vagrant@localhost ~]$ sudo systemctl enable httpd
```


# ファイヤウォールの設定
Webサーバーへのアクセスを許可するため、ファイヤウォールの設定を変更
```
[vagrant@localhost ~]$ sudo firewall-cmd --permanent --add-service=http
success

[vagrant@localhost ~]$ sudo firewall-cmd --reload
success
```
``FirewallD is not running``と表示された場合は、ファイヤウォールサービスを先に起動させる必要がある。
```
[vagrant@localhost ~]$ systemctl status firewalld
[vagrant@localhost ~]$ sudo systemctl start firewalld
```


# 仮想環境のネットワーク設定(Vagrantfile)
対象箇所のコメントアウトを解除し、ローカルのIPアドレスを指定
```
Vagrant.configure("2") do |config|

  config.vm.network "private_network", ip: "192.168.56.10"

end
```
仮想マシンの再起動
```
$ vagrant reload
```


# HTMLファイルの作成
DocumentRootに設定されているパスへHTMLファイルを作成する
```
[vagrant@localhost ~]$ cat /etc/httpd/conf/httpd.conf | grep DocumentRoot
# DocumentRoot: The directory out of which you will serve your
DocumentRoot "/var/www/html"
    # access content that does not live under the DocumentRoot.


[vagrant@localhost ~]$ cd /var/www/html
[vagrant@localhost ~]$ sudo touch index.html
[vagrant@localhost ~]$ sudo vi index.html

[vagrant@localhost ~]$ cat index.html
<h1>Hello World</h1>
```


# ローカルIPアドレスでページの確認
今回は``192.168.56.10``を指定したので、ブラウザからこのIPアドレスへアクセス。  
作成したページが表示されていれば成功。
![スクリーンショット 2022-10-17 21.50.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1953754/61d85620-6e36-edb5-9284-7f944685fd55.png)



## 参照
[VagrantとVirtualBoxで仮想環境を構築する③ Webサーバー構築編](https://pointsandlines.jp/env-tool/vagrant-virtualbox-3)
統計検定2級を受けてみた件

# 統計検定2級を受けてみた件
冒頭にもある通り，統計検定2級を受けてみた．

・なぜ受けようと思ったのか
・受験結果
・試験・勉強での注意点とか

などを，今後統計検定を受けようか考えている人，あるいは受ける予定の人が
この記事を見て参考になればいいなと思い，記録に残す．

## なぜ受けようと思ったのか
別に大した理由はない．以上．

というのも寂しいので(実際そうなのだが)，一応どういう考えがあって
試験を受けることを決めたのか，簡単に書く．

私は現在学生であり，研究活動に勤しんでいる．
その際，避けては通れないのが「検定」とか，「有意差」とか，「P値」とかである．

統計検定を受けたあとなのに，こんなに乱暴にまとめていいのか，とは思うが，
研究で扱う「検定」とは，簡単に言えば，
「それって本当に効果があるって言えるの？」「差があるって言えるの？」「偶然じゃないの？」
と言われないために行うものである．

まあ，初めて統計に触れた学生ならこのような理解の人が大半であろう．
別にその理解でも，正直，学部生を卒業することはできると思う．多分…

ただ自分としては，(統計学を専門的に学ぶ課程に所属していないが，)
「なぜ(統計的に)有意な差がある」と言えるのか，とか，「いくつも検定を行わないほうがいいのはなぜか」
など，研究で扱う以上の統計学の知識に対し，興味・関心を持ち，勉強をすることを決めた．

まあ，こんなところである．

## 受験結果
結果的に2回受ける羽目になった．
(つまり1回目は落ち，2回目で合格した)

１回目は52点，2回目は62点である(ギリギリ! 合格点は60点)
まあ，受かればこちらのもの．

2度の受験とその過程の勉強を通じ，これを意識してると良かったんじゃなかろうか，
と思ったことを，次の項に書く．

## 試験での注意点・勉強での注意点とか
### ①勉強の教材
私が利用した教材と，使ってみた感想を記述．

・日本統計学会公式認定 統計検定2級対応 統計学基礎
▶基本的に必要な知識はすべて載っている(当然といえば当然)．ただ，説明がわかりにくい部分もあったので，
それを補うべく「統計WEB 統計学の時間（WEBサイト）」をよく利用した．

・日本統計学会公式認定 統計検定 2級 公式問題集(2018〜2021年)
▶一番初めにこの問題集を手を付けることをおすすめする．そうすることで，
統計検定2級の難易度や，問題で出題される内容がつかめる．
実際，知識0の状態から一番初めにこれに手を付けたため，何を勉強すればよいか分かった．

・日本統計学会公式認定 統計検定 2級 公式問題集(2016〜2017年)
▶正直やらなくてよかった．わざわざAmazonで取り寄せたのだが，
難易度が本番(CBT)に比べ優しく，手応えが無い．
▶2018〜2021年の問題集のみで十分．

・統計WEB 統計学の時間（WEBサイト）
▶極力お金をかけない場合，(１つ目の紹介した参考書を買わずに)このサイト一つで十分勉強できる，
というくらい内容が充実したサイト．
説明も丁寧で，なおかつ結論だけで終わりではなく，証明やコラム要素も絡められており，理解が促された．

### ②実際のCBTテストの注意点 -その一：メモ 編-
一度目の受験で戸惑ったのが，「ラミネート加工されたメモ用紙」と「ペン」が計算用紙として渡された点．
これは統計検定の申し込みサイトにもちゃんと書かれているのだが，一体何のことかわからず当日を迎えた．

ペンのキャップを閉めずに置いておくと，かすれてしまい，うまく書けずに焦りが出た．
また，自分の字が汚くて読めないということもあった（自業自得)．
よくある紙とボールペン，というスタイルではないので，注意すること．

### ③実際のCBTテストの注意点 -その二：時間配分 編-
時間配分が，問題集でやったときと(個人的に)少し変える必要があると感じた．

というのは，問題集は紙なので，どこにどんな問題があるのかがわかり，
うまくタイムコントロールしやすい．

ただCBTの場合，パラパラとめくれるわけではないので，飛ばすかどうかの判断に迷いがあった．

ちなみに2度受けてみて，おそらくどこにどんな問題があるのかはどちらも大体一緒で変わらなかった．
最初にデータの特徴とかを見る(中央値とか，ヒストグラムとか)問題が出てきて，
次に期待値とかを計算する問題が出てきて，
最後の方に検定をする，という流れだった．

この時自分が思ったのは，勉強で利用した問題集と，出てくる問題のジャンルの順番は同じなのだが，
CBTテストの方は，「検定」の問題文の長さが桁違いに多く感じられた．(個人的にここが一番の注意点！！！)

ここから言えることは，最初の方の問題(ヒストグラムとか，期待値の計算とか，確率の計算とか)はかなり早めに解き，
検定のために時間を残すということが大事である．
▶20問解いたあたりから検定が出てくるが，検定のセクションに，90分のうちの半分の45分を当てるくらいが良いと思った．
▶逆に言えば，最初の20問くらいを40分〜45分くらいで解き，半分以上の時間を検定に費やしたいと思った．


### ④勉強のこと
長々と述べたが，結局勉強する流れとしては，問題集でどんな問題が出るのかを把握し，
わからないところを参考書などで確認する，という流れであった．

CBT試験では過去の問題集のものと比べ，検定関連の問題文は多く感じたが，
難易度自体は同じである．

なので，わからないところ・曖昧な理解のところをなくして
試験に臨むことができれば，合格できると思う．
４０代おっさんPythonを勉強する（イテレータandジェネレータ編）

## 本記事について

この記事はプログラミング初学者の私が学んでいく中でわからない単語や概要を分かりやすくまとめたものです。
もし不正などありましたらコメントにてお知らせいただければ幸いです。

## イテレータandジェネレータ編

- 他のプログラミング言語では大体ループを使ってシーケンスデータを処理する

```python
names = ['としき', 'アッキー', '三郎']
i = 0
total = len(names)
while i < total:
    print(names[i])
    i += 1
```

- イテラブルオブジェクトとしてforで処理すると１つずつの要素を取り出せる

```python
names = ['としき', 'アッキー', '三郎']
for n in names:
    print(n)
```

- 基本のイテラブルオブジェクト：文字列、リスト、タプル、辞書、しゅうごうなど

### ジェネレータ

- ジェネレータとは、シーケンスを作成するオブジェクトで、イテレータのソースデータになることが多い
- 今まで使っていたrange(start, end, step)関数はジェネレータの１つ

```python
print(list(range(10))) # start=0, end=10, step=1
print(list(range(10, 15))) # start=10, end=15, step=1
print(list(range(0, 50, 5))) # start=0, end=50, step=5
print(list(range(5, -5, -1))) # start=0, end=50, step=5
```

- ジェネレータは反復処理のために、最後に呼び出されたときを記憶し、次の値を返す
- ジェネレータ関数では値をreturで返す代わりにyieldで返す
- yieldは、関数を一時的に実行停止させることが出来る機能を持つ文
- 一度に一つの値しか生成しないので、メモリの消費量を抑えることが出来る

２つの関数を比べる

```python
def my_range(first=97, last=123, step=1): # returnを使う例
    char = first
    charlist = []
    while char < last:
        charlist.append(chr(char))
        char += step
    return charlist # こちらに全てをためたものが帰っているのでメモリを使う

for c in my_range(): # 一度26バイトのメモリを使う
    print(c)
```

```python
def my_range(first=97, last=123, step=1): # yieldを使う例
    char = first
    while char < last:
        yield chr(char) # こちらで一旦停止して、値を返す
        char += step

for c in my_range(): # 一度1バイトのメモリを使う
    print(c)
```

## 参考

https://www.kitakyu-u.ac.jp/news/2022/08/003215.html
皆の README をかわいくしたい♡

README の見出しのタイトルを「キュン:heart_eyes:」とさせる。
ちょっとだけかわいくする方法をご紹介。

以前に、「[皆の README をイケてる風にしたい](https://qiita.com/ryuma017/items/fcd947ce4f63040c8607)」という記事も書きました。ぜひ併せてご一読ください:sunglasses:。

# 普通に書くと

```markdown:README.md
# Mundane

An example of mundane README
```

![mundane.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2181622/c6d590aa-9b89-0f8c-2aa6-d73c8bbfbd8f.png)

「のっぺり:disappointed:」

ありふれてる。
そもそも markdown がそういうものなのでしょうがないですが、全然かわいくない。

# ちょっとかわいく :heart_eyes:

こうするのだ

```markdown:README.md
<samp>

# Pretty

An example of pretty README ♡

</samp>
```

![pretty.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2181622/fbe88109-7ee7-bb49-faa5-5379a62a4b36.png)

「キュンっ♡」

かわいい。等幅フォントってかわいいですよね。
`samp` タグでサンドイッチするだけです。

# もっとかわいく :heart:

以前書いた[こちら](https://qiita.com/ryuma017/items/fcd947ce4f63040c8607)の記事で紹介した方法とガッチャンコ。

```markdown:README.md
<div align="center">
<samp>

# Pretty

An example of pretty README ♡

</samp>
</div>
```

![pretty-align-center.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2181622/b9817023-034e-7bb4-c155-652f65aacebe.png)

「ギュンっ:star:」

激かわ！これは人の目を引きますね。2度見しちゃいます。
インデントの有無はお好みで。

# どうですか

等幅フォントほどかわいいものってないですよね、これだけでだいぶ雰囲気変わると思います。
僕は GitHub の profile README [[覗きに行くボタン](https://github.com/ryuma017/ryuma017)] でもこの記法使ってます(プログラミングなんもわからんペーペーなので README で差別化を図っていくスタイル)。

たったこれだけの記事です。
最後まで読んでいただきありがとうございました。

# おわりに

**別にかわいくはない。**
Corrosion and corrosion protection, ボッシュ自動車handbook 11版(20)p.340

Corrosion and corrosion protection , ボッシュ自動車handbook 11版(20)

人生で影響を受けた本100冊。
https://qiita.com/kaizen_nagoya/items/16af53acbb147a94172e

に掲載した本のうち、「新人プログラマ応援」企画で「私の推薦書３３冊」として３３冊紹介した。

新人プログラマ応援　私の推薦書３３冊
http://qiita.com/kaizen_nagoya/items/98c62f051dbdb4f8aca2
残りの６７冊から、順に過去の読書感想を引用し、新たな読書感想文を追記する。

 <この項は書きかけです。順次追記します。>


# ボッシュ自動車ハンドブック version 11, 2022

Automotive Handbook  May 2, 2022

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

ボッシュ自動車handbook(英語)11版(0)＜エンジニア夏休み企画>【読書感想文】

https://qiita.com/kaizen_nagoya/items/dfa35aa6f669e5df983e

# Corrosion(腐食) and corrosion protection(防食)
p.340

## Corrosion processes(防食)

### Corrosion protection by means of suitable structural design

Figure 4 Good and bad installation positions for profie sections

![bosch10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51423/091f9a58-4322-2958-fc46-431d086d6272.png)

Figure 5 Design of beads and welts
![bosch11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51423/7d91b551-70fb-c4a6-f7f1-cbe986dca95b.png)

Figure 6 Design related crevices in welds and how they can be avoided
![bosch12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51423/0d5a7bdc-9e2b-1920-57e6-c0ff53fa64d8.png)

Figure 7 Electric instration to avoid contact corrosion
![bosch13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51423/7d06f6a4-fb9a-c562-2c98-e9dfcd878eba.png)

## Types of corrosion(腐食型)
## Corrosion testing(腐食試験)
## Corrosion protection(防食)

# Reference
[1] R.W. Clough, The Finite Element Method in Plane Stress Analysis, Publication, 2nd ASCE Conference on Electronic Computation, 1960
[2] http://www.igfgrothtp2000.de
[3] D. Braess, Finite Elemente, Theorie, Schnelle Loser und Anwendungen in der Elastizitarsthedrie, 5Th Edition, Springer Spectrum, 2013

# 自己参考資料(self reference)

ボッシュ自動車ハンドブック 

https://qiita.com/kaizen_nagoya/items/8e330ce57880f04d71d9
ボッシュ自動車handbook(英語)10版　目次

https://qiita.com/kaizen_nagoya/items/57c799ff544c96efdea9

自動車工学とBosch Vehicle Handbook

https://qiita.com/kaizen_nagoya/items/d13ff6b0e4d7c8907c0d

 ＜この記事は個人の過去の経験に基づく個人の感想です。現在所属する組織、業務とは関係がありません。＞

# 文書履歴(document history)
ver. 0.01 初稿 　20221017
ver. 0.02 図追記 20221018
### 最後までおよみいただきありがとうございました。
いいね　💚、フォローをお願いします。
####  Thank you very much for reading to the last sentence.
Please press the like icon 💚　and follow me for your happy life.
VBAで一次元配列を作成する関数

VBAで一次元配列を作成する方法

基本的には、配列を定義するときには以下のように
一つずつ定義する必要がある。

``` 
Sub test()

Dim str(2) As Variant

    str(0) = "a"
    str(1) = "b"
    str(2) = "c"

End Sub
```
この定義の仕方は少し面倒なので、一次元配列の定義を簡単にする関数を作成。

```
Sub test()

Dim str() As Variant

    str = ArrayDefinition("a", "b", "c")

End Sub

Public Function ArrayDefinition(ParamArray arr()) As Variant
    ArrayDefinition = arr    
End Function
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2405683/ff4e73f7-b3f9-b0cf-7a75-ea628307ca35.png)

一行で3つの関数を定義できている。
変数定義が多い時には定義が簡単になる、と思う。

追記
str = array("a","b","c")で定義できるらしい。知らなかった...
Heat treatment of metallic materials, ボッシュ自動車handbook 11版(19)p.328

Heat treatment of metallic materials , ボッシュ自動車handbook 11版(19)

人生で影響を受けた本100冊。
https://qiita.com/kaizen_nagoya/items/16af53acbb147a94172e

に掲載した本のうち、「新人プログラマ応援」企画で「私の推薦書３３冊」として３３冊紹介した。

新人プログラマ応援　私の推薦書３３冊
http://qiita.com/kaizen_nagoya/items/98c62f051dbdb4f8aca2
残りの６７冊から、順に過去の読書感想を引用し、新たな読書感想文を追記する。

 <この項は書きかけです。順次追記します。>


# ボッシュ自動車ハンドブック version 11, 2022

Automotive Handbook  May 2, 2022

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

ボッシュ自動車handbook(英語)11版(0)＜エンジニア夏休み企画>【読書感想文】

https://qiita.com/kaizen_nagoya/items/dfa35aa6f669e5df983e

# Heat treatment of metallic materials
p.328

## Hardness
## Heat-treatment processes
## Thermochemical treatment


# Reference



# 自己参考資料(self reference)

ボッシュ自動車ハンドブック 

https://qiita.com/kaizen_nagoya/items/8e330ce57880f04d71d9
ボッシュ自動車handbook(英語)10版　目次

https://qiita.com/kaizen_nagoya/items/57c799ff544c96efdea9

自動車工学とBosch Vehicle Handbook

https://qiita.com/kaizen_nagoya/items/d13ff6b0e4d7c8907c0d

 ＜この記事は個人の過去の経験に基づく個人の感想です。現在所属する組織、業務とは関係がありません。＞

# 文書履歴(document history)
ver. 0.01 初稿 　20221017
### 最後までおよみいただきありがとうございました。
いいね　💚、フォローをお願いします。
####  Thank you very much for reading to the last sentence.
Please press the like icon 💚　and follow me for your happy life.
IPAM ってなに？

## 勉強前イメージ

AWSのサイトでちらっと単語だけ見たことあるけど知らない。。。
IPアドレス関係ある？？

## 調査

### IPAM とは

IP Address Management の略で、アイパムと呼ぶ。
日本語ではIPアドレス管理と呼ばれています。

IPAMとはネットワーク内のIPアドレスを一元的に管理することや、その管理のためのソフトウェアのことを指します。
ネットワーク内に存在するDHCPサーバやDNSサーバ等と連携してIPアドレスを収集し
計画的にDHCPサーバでIPアドレスの割当を行うものです。

従来はIPアドレスを計画的に行う際は、エクセルを使って計画し
変更があった際には修正を行うということが多く行われていました。
しかし、作業の漏れが発生したり追跡できなくなったりで使えなくなることがありました。
それを自動的に行うのがIPAMになります。

## 勉強後イメージ

確かにエクセルの表でとかありそう・・・使えなくなるよね。。。。

## 参考

- [IPAM 【IP Address Management】 IPアドレス管理](https://e-words.jp/w/IPAM.html)
【Swift】Alamofireでカスタムレスポンスを作成する

# はじめに
AlamofireでAPIを叩いて`responseDecodable(of: StatusesShow.self)`でデコードされた結果を受け取る。
今までこの方法で使っていました。
この時返ってくる値は`Result<StatusesShow, AFError>`です。

例えばTwitterのAPIを叩いたとしましょう。
[TwitterError](https://qiita.com/SNQ-2001/items/604559ee38227cc134a3)を使いたいと思うとこのように美しくない実装になります。
```swift
AF.request(url, method: .get, headers: headers).responseDecodable(of: StatusesShow.self) { response in
    switch response.result {
    case .success(let data):
        print(data)
    case .failure(_):
        guard let data = response.data, let localRateLimited = String(data: data, encoding: .utf8) else { return }
        do {
            let twitterError = try JSONDecoder().decode(TwitterError.self, from: data)
            print(twitterError)
        } catch {
            print(localRateLimited)
        }
    }
}
```
`Result<StatusesShow, TwitterError>`で返ってきてほしい！！！

カスタムレスポンスを作成して美しいコードにします。

# やりかた
`ResponseSerializer`を使用します。
```swift
import Alamofire
import Foundation

final class TwitterDecodableResponseSerializer<T: Decodable>: ResponseSerializer {
    private lazy var successSerializer = DecodableResponseSerializer<T>(decoder: JSONDecoder())
    private lazy var errorSerializer = DecodableResponseSerializer<TwitterError>(decoder: JSONDecoder())

    public func serialize(request: URLRequest?, response: HTTPURLResponse?, data: Data?, error: Error?) throws -> Result<T, ErrorCode> {

        guard error == nil else { return .failure(.code000) }

        guard let response else { return .failure(.code000) }

        do {
            // 成功
            let result = try successSerializer.serialize(request: request, response: response, data: data, error: nil)
            return .success(result)
        } catch {
            // 失敗
            let result = try errorSerializer.serialize(request: request, response: response, data: data, error: nil)
            return .failure(result.errors[0].code)
        }
    }
}

extension DataRequest {
    @discardableResult func responseTwitterDecodable<T: Decodable>(queue: DispatchQueue = DispatchQueue.global(qos: .userInitiated), of t: T.Type, completionHandler: @escaping (Result<T, ErrorCode>) -> Void) -> Self {
        return response(queue: .main, responseSerializer: TwitterDecodableResponseSerializer<T>()) { response in
            switch response.result {
            case .success(let result):
                // 成功 or 失敗
                completionHandler(result)
            case .failure(_):
                // 想定外のレスポンス
                guard let data = response.data, let localRateLimited = String(data: data, encoding: .utf8) else { return }
                print(localRateLimited)
            }
        }
    }
}
```

# 使い方
はい〜、美しい
```swift
AF.request(url, method: .get, headers: headers).responseTwitterDecodable(of: StatusesShow.self) { response in
    switch response {
    case .success(let data):
        print(type(of: data)) // StatusesShow
    case .failure(let error):
        print(type(of: error)) // TwitterError
    }
}
```

# おわり
めっちゃ綺麗になりました！

# 参考記事
https://stackoverflow.com/questions/64557970/how-to-decode-the-body-of-an-error-in-alamofire-5
Materials, ボッシュ自動車handbook 11版(18)p.258

 Materials, ボッシュ自動車handbook 11版(18)

人生で影響を受けた本100冊。
https://qiita.com/kaizen_nagoya/items/16af53acbb147a94172e

に掲載した本のうち、「新人プログラマ応援」企画で「私の推薦書３３冊」として３３冊紹介した。

新人プログラマ応援　私の推薦書３３冊
http://qiita.com/kaizen_nagoya/items/98c62f051dbdb4f8aca2
残りの６７冊から、順に過去の読書感想を引用し、新たな読書感想文を追記する。

 <この項は書きかけです。順次追記します。>


# ボッシュ自動車ハンドブック version 11, 2022

Automotive Handbook  May 2, 2022

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

ボッシュ自動車handbook(英語)11版(0)＜エンジニア夏休み企画>【読書感想文】

https://qiita.com/kaizen_nagoya/items/dfa35aa6f669e5df983e

#  Materials
p.258

## Material parameters
## Material groups
## Metallic materials
## EN metallurgy standards
## Magnetic materials
## Nonmetallic inorganic materials
## Composite materials
## Plastics


# Reference
[1] 

# 自己参考資料(self reference)

ボッシュ自動車ハンドブック 

https://qiita.com/kaizen_nagoya/items/8e330ce57880f04d71d9
ボッシュ自動車handbook(英語)10版　目次

https://qiita.com/kaizen_nagoya/items/57c799ff544c96efdea9

自動車工学とBosch Vehicle Handbook

https://qiita.com/kaizen_nagoya/items/d13ff6b0e4d7c8907c0d

 ＜この記事は個人の過去の経験に基づく個人の感想です。現在所属する組織、業務とは関係がありません。＞

# 文書履歴(document history)
ver. 0.01 初稿 　20221017


### 最後までおよみいただきありがとうございました。
いいね　💚、フォローをお願いします。
####  Thank you very much for reading to the last sentence.
Please press the like icon 💚　and follow me for your happy life.
LoadError (cannot load such file -- sassc)

<h1>Railsでscssを適用しようとしたらLoadError (cannot load such file -- sassc)</h1>

```ruby:application.html.erb
<%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>
```
<p>上記記載後、ブラウザで</p>
<em>cannot load such file -- sassc</em>
<p>のエラーとなった。</p>

<h3>原因</h3>
<p>gemfile　中の　gem "sassc-rails"　がRails Ver7からはコメントアウトされており、インストール時に適用されないとのこと。</p>
<p>コメントアウト解除後、bundle install により無事解決</p>
php　ubuntuにmbstringを入れる際にエラーになった



# 環境
- ubuntu20.04
- windows surface
- php 7.4

# 拡散モジュール
```ubuntu
sudo apt -y install php7.4-intl php7.4-xmlrpc php7.4-soap php7.4-mbstring
```
拡散モジュールは`php7.4-mbstring`だけでいいかもしれない

https://www.kshare.jp/blog/archives/751.html
AWSのクロスアカウント接続について調べてみた

## 勉強前イメージ

なんだっけ？ぱっと答えられないけど、
違うアカウントのユーザをなんかするみたいなやつだった気がする

## 調査

### AWSのクロスアカウント接続 とは

1つのアカウントで2つ以上のアカウントのリソースを扱えるようにすることです。
2つならマルチアカウント接続とも呼ばれます。

アカウントのログインをし直したらいいだけじゃないって思われるかもしれません。
しかし、環境によっては本番用と開発用で分けたり、他社のAWSアカウントとの連携が必要になるケースがあります。
その際にわざわざ作らなくても元々あるアカウントの許可を行うだけで接続できるようにするのがクロスアカウント接続になります。

### どういう構成になるのか

ユースケースとしては以下のような感じになります。
あるアカウントにはユーザAが存在します。
他にもユーザAは本番環境・開発環境・他社環境への接続ができる必要があります。
それぞれの環境で以下のようにIAMロールを設定します。

- 本番環境
	- 本番ログバケットのread権限をユーザAに割り振る
- 開発環境
	- 開発ログバケットのread権限をユーザAに割り振る
- 他社環境
	- EC2のすべての操作権限をユーザAに割り振る

すると、ユーザAはユーザAのままで [スイッチロール](https://qiita.com/miyuki_samitani/items/d4b9d6c36f07f7163507)を行うだけで
本番環境の本番ログバケットのread権限、開発環境の開発ログバケットのread権限、他社環境のEC2のすべての操作権限を
得ることが出来ます。

![12022-10-17 AWSのクロスアカウント接続について調べてみた - diagrams.net.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/9a4ccabc-291e-1344-8fdf-414bb0150ee2.png)

### スイッチロールとクロスアカウント接続の違い

- クロスアカウント
	- 2つ以上のアカウントのリソースを扱えるようにすること
- スイッチロール
	- 別の権限(ロール)に変更をすること。
	- よく使われるのは、違うアカウントのリソースを扱う際にそのアカウントのロールへ切り替えを行うこと
	- 違うアカントへのログインじゃなくて、あくまで違うアカウントの `ロール` へ切り替えを行うこと

## 勉強後イメージ

スイッチロールはあくまでログインではない。

## 参考

- [AWSのクロスアカウント構築で悩んでいる人必見！AWSエキスパートがセキュリティユースケースを解説します！😎](https://www.ragate.co.jp/blog/articles/9717)
- [AssumeRoleクロスアカウント接続](https://www.skyarch.net/blog/?p=22072)
【Rails】I18n#lで日付のフォーマットを定義しよう

## 環境
Rails 6.0.1
Ruby 2.6.3
PostgreSQL 11.16

## 日付のフォーマットを定義

```config/locales/ja.yml
ja:
  date:
    formats:
      default: "%Y.%m.%d"
      long: "%Y年%m月%d日"
      short: "%m月%d日"
  time:
    formats:
      default: "%Y/%m/%d %H:%M:%S"
      long: "%Y年%m月%d日(%a) %H時%M分%S秒 %z"
      short: "%y/%m/%d %H:%M"
      date_long: "%Y年%m月%d日"
      date_short: "%m月%d日"
      datetime: "%Y.%m.%d %H時%M分"
      only_time: "%H:%M"
```
デフォルトの形は引数の指定なし、それ以外は第2引数を指定するとデフォルト以外のフォーマットに変換できる。

```ruby
I18n.l(Date.today)
#=> "2022.01.01"
I18n.l(Date.today, format: :long)
#=> "2022年01月01日"
```



## 参考

https://railsguides.jp/i18n.html
Ruby + GCP  Vision API で画像の種類(ラベル)を取得する

# 準備

```
gem install google/cloud/vision
```


# コード

```rb

require "google/cloud/vision"

image_path = 'gs://cloud-samples-data/vision/label/setagaya.jpeg'

image_annotator = Google::Cloud::Vision.image_annotator

response = image_annotator.label_detection(
  image:       image_path,
  max_results: 10 # optional, defaults to 10
)

response.responses.each do |res|
  res.label_annotations.each do |label|
    puts label.description
  end
end
```

# 画像

<img width="654" alt="image" src="https://user-images.githubusercontent.com/13635059/196164817-ebc322a4-f0d5-4795-bcc1-960d2cdd107d.png">


# 実行

```
GOOGLE_APPLICATION_CREDENTIALS="/path/to/service-account.json" ruby /path/to/script.rb
```

# 結果

```
Bicycle
Tire
Wheel
Automotive lighting
Infrastructure
Bicycle wheel
Building
Mode of transport
Electricity
Vehicle
```


# 参考

- https://www.farend.co.jp/blog/2021/02/cloud-vision-api/
- https://cloud.google.com/vision/docs/labels?hl=ja#vision_label_detection_gcs-python


# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ


# Twitter

https://twitter.com/YumaInaura
あなたにおすすめのQiita記事

「あなたにおすすめのQiita記事」をレコメンデーションしてくれるサービス「**HottyTech検索**」を個人開発しました！

https://tech.hottydb.com/

↑こちらです。

初回訪問時は単純な人気順だけが表示されますが、興味ある記事をいくつか閲覧すると、「**あなたにおすすめの記事**」という記事の一覧がトップページに表示されるようになっています！

## 主な機能
「HottyTech検索」の主な機能はこちらです。

1. キーワード検索機能（全文検索＋機械学習ランキング）
2. 関連記事レコメンデーション機能（協調フィルタリング）
3. 関連記事レコメンデーション機能（類似記事検索）
4. 「あなたにおすすめの記事」機能

## 技術スタック
「HottyTech検索」で利用している技術スタックは以下の通りです。

| 項目 | 利用技術 |
| --- | --- |
| フロントエンド |  React |
| バックエンド（API） | Spring Boot |
| データベース | HottyDB |
| 検索エンジン | HottyDB |
| 機械学習システム | HottyDB |
| レコメンドエンジン | HottyDB |
| ETLシステム | **なし**（データは全てHottyDBに入ってるのでETLが不要！） |

ご覧のとおり、ほとんどがHottyDBです！！

## HottyDBとは？
https://www.hottydb.com/

[HottyDB](https://www.hottydb.com/)は、検索エンジンとレコメンドエンジンの機能を搭載したRDBMSです。 SQLを用いた通常のデータ操作に加え、文書の全文検索や検索結果の**機械学習**ランキング（ランキング学習）・アイテムレコメンデーションのロジックを全て1つのソフトウェアで担います。 1つのソフトウェアでこれらを実現することで、面倒なデータ伝送システム（ETL）の構築を一切不要にし、利用者は機械学習などの知識がなくてもSQL LIKEな命令だけでこれらを実現することができます。
![HottyDB](https://www.hottydb.com/hottydb-system.svg)

HottyDBについて詳しく解説した記事もありますので、是非参考にしてみてください。

https://qiita.com/toru1055/items/0fe400989373823e9c78
[GIMP]画面がくるっと回転してしまった時、元に戻す方法

# 概要
画像の回転ではなくて、画面（キャンバス）自体がくるっと回転してしまった時、元に戻す方法です。

![スクリーンショット 2022-10-17 19.51.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/8f8226f9-783c-cfbe-72cf-d4c8b07df562.png)

# 本文
Shiftキーを押したままマウスの中ボタンをドラッグするとキャンバスを回転させることができます。

そのままCtrlキーも押すと角度が１５度単位になるので元の角度に戻しやすくなります。
【メモ】DenoでOctokitのRestを使う

一日溶かしたので以降の方はすぐに解決できるように残しておきます

## TL;DR
Restを使いたいだけの場合
```TypeScript
import { Octokit as OctokitCore } from 'https://cdn.skypack.dev/@octokit/core?dts';
import { restEndpointMethods } from 'https://cdn.skypack.dev/@octokit/plugin-rest-endpoint-methods?dts';

export const Octokit = OctokitCore.plugin(restEndpointMethods);
```

## 事象
OctokitをSkypack経由で読み込んで
```TypeScript
import { Octokit } from 'https://cdn.skypack.dev/@octokit/rest?dts';
const octokit = new Octokit();
//    ^? octokit: any
```
とこのようにanyなってしまう事象に遭遇した。
Markdown絵文字表示テスト: 文字キー

[単独絵文字](https://qiita.com/higuma/items/b49981fef25603ff822c) ← [解説](https://qiita.com/higuma/items/e402fc428ecf0cb184d8#文字キー) → [国旗](https://qiita.com/higuma/items/b5d2200313b1d9c54ce4)

----------------------------------------

| シーケンス | 出力 | 名前 | バージョン |
| - | - | - | - |
| 0023 20E3<br>0023 FE0E 20E3<br>0023 FE0F 20E3 | #⃣<br>#︎⃣<br>#️⃣ | keycap: # | E0.6 |
| 002A 20E3<br>002A FE0E 20E3<br>002A FE0F 20E3 | *⃣<br>*︎⃣<br>*️⃣ | keycap: * | E2.0 |
| 0030 20E3<br>0030 FE0E 20E3<br>0030 FE0F 20E3 | 0⃣<br>0︎⃣<br>0️⃣ | keycap: 0 | E0.6 |
| 0031 20E3<br>0031 FE0E 20E3<br>0031 FE0F 20E3 | 1⃣<br>1︎⃣<br>1️⃣ | keycap: 1 | E0.6 |
| 0032 20E3<br>0032 FE0E 20E3<br>0032 FE0F 20E3 | 2⃣<br>2︎⃣<br>2️⃣ | keycap: 2 | E0.6 |
| 0033 20E3<br>0033 FE0E 20E3<br>0033 FE0F 20E3 | 3⃣<br>3︎⃣<br>3️⃣ | keycap: 3 | E0.6 |
| 0034 20E3<br>0034 FE0E 20E3<br>0034 FE0F 20E3 | 4⃣<br>4︎⃣<br>4️⃣ | keycap: 4 | E0.6 |
| 0035 20E3<br>0035 FE0E 20E3<br>0035 FE0F 20E3 | 5⃣<br>5︎⃣<br>5️⃣ | keycap: 5 | E0.6 |
| 0036 20E3<br>0036 FE0E 20E3<br>0036 FE0F 20E3 | 6⃣<br>6︎⃣<br>6️⃣ | keycap: 6 | E0.6 |
| 0037 20E3<br>0037 FE0E 20E3<br>0037 FE0F 20E3 | 7⃣<br>7︎⃣<br>7️⃣ | keycap: 7 | E0.6 |
| 0038 20E3<br>0038 FE0E 20E3<br>0038 FE0F 20E3 | 8⃣<br>8︎⃣<br>8️⃣ | keycap: 8 | E0.6 |
| 0039 20E3<br>0039 FE0E 20E3<br>0039 FE0F 20E3 | 9⃣<br>9︎⃣<br>9️⃣ | keycap: 9 | E0.6 |

----------------------------------------

[単独絵文字](https://qiita.com/higuma/items/b49981fef25603ff822c) ← [解説](https://qiita.com/higuma/items/e402fc428ecf0cb184d8#文字キー) → [国旗](https://qiita.com/higuma/items/b5d2200313b1d9c54ce4)