OmniAICreator/Qiita-1.07M huggingface dataset:
Serverless Frameworkで行うLambdaのコールドスタート対策

# 概要
AWS Lambdaで発生するコールドスタートを軽減させる為の対策を実施します。

以前私が書いた、[Serverless FrameworkでLambdaのコールドスタート対策を行う](https://qiita.com/keitakn/items/d1c524a97dc844cb02cc) の2020年版です。

[Serverless FrameworkでLambdaのコールドスタート対策を行う](https://qiita.com/keitakn/items/d1c524a97dc844cb02cc) は少し前までのベストプラクティスでしたが今後はこの記事の方法が推奨されるようになってくると思われます。

# 対象読者
- [Serverless Framework](https://github.com/serverless/serverless) でAWS Lambdaの開発を行っている方

# Lambdaのコールドスタートについて
[こちら](https://qiita.com/keitakn/items/d1c524a97dc844cb02cc#%E3%82%B3%E3%83%BC%E3%83%AB%E3%83%89%E3%82%B9%E3%82%BF%E3%83%BC%E3%83%88) に書いてある通りです。

コールドスタートとは実行可能なLambdaコンテナが1つもない時にLambdaの実行に時間がかかる現象を指します。

- [AWS Lambda 実行コンテキスト](https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/running-lambda-code.html)
- [コールドスタートとは？！](https://tech.unifa-e.com/entry/2019/12/20/003000?utm_source=feed)

# 今までのコールドスタート対策
今まではすぐに実行可能なLambdaコンテナが消えないように定期的にLambdaを実行してあげるという方法が主流でした。

以前私が書いた、[Serverless FrameworkでLambdaのコールドスタート対策を行う](https://qiita.com/keitakn/items/d1c524a97dc844cb02cc) でもその方法を採用しています。

# これからのコールドスタート対策
2019年の終わり頃、AWS LambdaにProvisioned Concurrencyという設定項目が追加されました。

マネジメントコンソール上だと「プロビジョニングされた同時実行の設定」という部分です。

これを設定しておくと実行可能なLambdaコンテナが常に存在している状態を作る事が出来ます。

（参考）[[速報]コールドスタート対策のLambda定期実行とサヨナラ！！ LambdaにProvisioned Concurrencyの設定が追加されました](https://dev.classmethod.jp/cloud/aws/lambda-support-provisioned-concurrency/)

# [Serverless Framework](https://github.com/serverless/serverless) でのProvisioned Concurrency設定方法

[Serverlessの公式ブログ](https://serverless.com/blog/aws-lambda-provisioned-concurrency/) に書かれている通りです。

`serverless.yml` の `functions` → `provisionedConcurrency` を設定するだけです。
非常に簡単ですね！

```yaml:serverless.yml
functions:
  render:
    handler: dist/server/lambda.render
    events:
      - http:
          path: '/'
          method: get
      - http:
          path: '{proxy+}'
          method: get
      - http:
          path: '/api/{proxy+}'
          method: any
    provisionedConcurrency: 2
```

この設定だと常に2つのコンテナが待機している状態になります。
あと [Serverless Framework](https://github.com/serverless/serverless) のバージョンは最新にしておく事をオススメします。（古いバージョンだと上記の設定に対応していない）

# 注意

## [serverless-plugin-warmup](https://github.com/FidelLimited/serverless-plugin-warmup) から乗り換える際の注意点

[こちらの記事](https://qiita.com/keitakn/items/d1c524a97dc844cb02cc) で紹介されている [serverless-plugin-warmup](https://github.com/FidelLimited/serverless-plugin-warmup) から乗り換えた際にデプロイが完了するまで、Lambdaが正常に起動しなくなりました。

運用中のサービスに適応する場合は注意が必要ですね。

## 料金が高くなる可能性
`provisionedConcurrency` の設定を多くすれば安定した状態になりますがその分料金が高くなります。
運用しながら最適値を見つける必要があります。

# おわりに
provisionedConcurrencyがリリースされた事でよりコールドスタート対策がより簡単になりました。

ただし料金には注意ですね。

ここまで読んで頂きありがとうございます。
【REACT】Componentを学びましょう！part.1 (初心者向け)

# 概要

社内勉強会のため、
Reactの資料を作りました。
自分も、よく知らないので、
一緒に勉強しましょう！！

--------

# 事前準備

https://codesandbox.io/?from-app=1
![fgsafgsaf.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/421654/5655f326-86ac-fd1c-e146-7a4cb890ba46.jpeg)


--------

# Component

Componentは、状態値を利用してUIを表現します。
Component間の一方向にデータを送受信するprops、
Componentの内部で使用されるstateです

![https___qiita-image-store.s3.ap-northeast-1.amazonaws.com_0_421654_d5ff3112-2783-82c9-670e-cf5543ede588.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/421654/a06f77df-882b-ec98-d152-9d33289d753f.jpeg)


--------

# Componentを作成

Componentは、Classと関数形Componentがあります。
まず、関数形Componentの作成から始めます。

```react:MyComponent.js
import React from "react";

const MyComponent = () => {
  return <div> This is new Component. </div>
}
export default MyComponent;
```

```react:MyComponent.js
import React from "react";

function MyComponent() {
  return <div> This is new Component. </div>;
}
export default MyComponent;
```

```react:App.js
import React from "react";
import MyComponent from './MyComponent';

const App = () => {
  return <MyComponent />
}

export default App;
```

結果
![xfgnxbhgx.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/421654/08920a97-001e-fb2c-4bf3-8d89bc841740.jpeg)

--------
Class形Component

```react:MyComponent.js
import React from "react";

class MyComponent extends React.Component {
  render() {
    return <div> This is new Component. </div>;
  }
}
export default MyComponent;
```

--------

# propsを使う！

props(properties)は、
Componentで使用するデータの変更されないデータを扱う際に使用します。
親Componentで子Componentにデータを転送するときに使います。
propsは、変更が不可能です。


```react:MyComponent.js
import React from "react";

const MyComponent = props => {
  return <div> My name is {props.name}.</div>;
};

export default MyComponent;
```

```react:App.js
import React from "react";
import MyComponent from './MyComponent';

const App = () => {
  return <MyComponent name="Tom" />;
};

export default App;
```

結果
![vjgvhj.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/421654/38ed9974-e8ba-ce8c-8c4e-88f4437be306.jpeg)

--------

defaultProps

```react:MyComponent.js
import React from "react";

const MyComponent = props => {
  return <div> My name is {props.name}.</div>;
};

MyComponent.defaultProps = {
  name: "NULL"
};

export default MyComponent;

```

--------

propsTypes

```react:MyComponent.js
import React from "react";
import PropsType from "prop-types";

const MyComponent = ({ name }) => {
  return <div> My name is {name}.</div>;
};

MyComponent.defaultProps = {
  name: "NULL"
};

MyComponent.propsType = {
  name: PropsType.string
};

export default MyComponent;
```

--------
Class形Component

```react:MyComponent.js
import React, { Component } from "react";
import PropsType from "prop-types";

class MyComponent extends Component {
  static defaultProps = {
    name: "NULL"
  };

  static propsType = {
    name: PropsType.string
  };

  render(){
    const {name} = this.props;
    return <div> My name is {name}.</div>;
  }
}

export default MyComponent;
```
gem install ovirt-engine-sdk -v '4.2.4'がインストールできない

gem install ovirt-engine-sdk -v '4.2.4'をbundle install しようとするとエラーが発生する。


<h1>エラー内容</h1>
Building native extensions. This could take a while...
ERROR:  Error installing ovirt-engine-sdk:
        ERROR: Failed to build gem native extension.


 currentdirectory：
/home/vagrant/.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/gems/ovirt-engine-sdk-4.2.4/ext/ovirtsdk4c
/home/vagrant/.rbenv/versions/2.4.0/bin/ruby -r ./siteconf20180522-11143-c35v2a.rb extconf.rb
checking for xml2-config... no
*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of necessary
libraries and/or headers.  Check the mkmf.log file for more details.  You may
need configuration options.

Provided configuration options:
        --with-opt-dir
        --without-opt-dir
        --with-opt-include
        --without-opt-include=${opt-dir}/include
        --with-opt-lib
        --without-opt-lib=${opt-dir}/lib
        --with-make-prog
        --without-make-prog
        --srcdir=.
        --curdir
        --ruby=/home/vagrant/.rbenv/versions/2.4.0/bin/$(RUBY_BASE_NAME)
        --with-libxml2-config
        --without-libxml2-config
        --with-pkg-config
        --without-pkg-config
extconf.rb:29:in `<main>': The "libxml2" package isn't available. (RuntimeError)

To see why this extension failed to compile, please check the mkmf.log which can be found here:

  /home/vagrant/.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/extensions/x86_64-linux/2.4.0-static/ovirt-engine-sdk-4.2.4/mkmf.log

extconf failed, exit code 1


Gem files will remain installed in /home/vagrant/.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/gems/ovirt-engine-sdk-4.2.4 for inspection.
Results logged to /home/vagrant/.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/extensions/x86_64-linux/2.4.0-static/ovirt-engine-sdk-4.2.4/gem_make.out



<h1>解決方法</h1>
①sudo yum --enablerepo=epel,remi,rpmforge install libxml2 libxml2-develをインストール

②sudo yum -y install curl　をインストール
③sudo yum -y install libcurl libcurl-devel　をインストールすると
gem install ovirt-engine-sdk -v '4.2.4'
が通使えるようになり、bundle installをすることができます。
BOMを削除する方法(UTF-8)

業務でファイル操作に関連する処理を実装したのですが、UTF-8(BOM付き)ファイルから
BOMを削除するための方法を学んだので今後のためにまとめてみます。
## そもそもBOMとは？
まず、そもそもBOMとは一体何者なのでしょうか？

BOMとはざっくりいってしまえば
**Unicode系文字コードで作成されたファイルの先頭に付く目印**です。
UTF-8では**0xEF 0xBB 0xBF**の3バイトで表現されます。
BOMは普通メモ帳などでは見ることはできませんが、実際にはファイルの中身の最初に
BOMが付いており、コンピュータ側で読み取る際にもそのように解釈して実行します。
そして、目印として主に2つの役割を持ちます。

1. Unicode系の文字コードで記述されていることを示すためのもの
2. UTF-16、UTF-32においてエンディアンと呼ばれるビットの並び順を指定するためのもの。
並べる順序によって、  
・ ビッグエンディアン(上位バイトから順番に並べる)  
・ リトルエンディアン(下位バイトから順番に並べる)  
の2種類がある

## なぜUTF-8(BOM付き)が存在するのか？

UTF-16、UTF-32のように2バイト以上の文字コードで文字との対応付けを行う際には
エンディアンの並び順を指定するためにBOMが使われます。
しかし、UTF-8のように1バイトの文字コードで対応付けを行っている場合には
エンディアンを指定する必要なんてありません。
では、なぜUTF-8(BOM付き)が存在するのでしょうか？

調べていくと、ExcelがCSVを開く際の仕様に原因があることがわかりました。
ExcelがCSVを開くときにはShift-JISで開こうとするため、BOMなしのUTF-8で
書かれたファイルを読み込もうとすると文字化けしてしまうのです。
これを防ぐためにBOMを付けてCSVを開くときにもUnicode系の文字コードで
読み込むように指定する必要があるのです。

## BOMを削除する方法

では、本題となっているBOMを削除するための方法を説明していきます。
JavaではそもそもUTF-8にBOMが付いている場合を想定していません。
そのため、BOM付きのファイルを読み込む際にはBOMを他の文字と
同様のものとして扱い、BOMを削除しません。
そのため、BOMを削除する場合は別途そのような処理を実装する必要があります。

```Java:Java
    // BOMをUnicodeコード表示したもの
    public static final String BOM = "\uFEFF";

    /**
     * ファイルにBOMが含まれていた場合、
     * BOMなしに変換する。
     *
     * @param s ファイル文字列
     * @return BOMなしのファイル文字列
     *
     */
    private static String removeUTF8BOM(String s) {
        if (s.startsWith(BOM)) {
            // ファイルの先頭より後ろの文字列を読み込む
            s = s.substring(1);
        }
        return s;
    }
```

なお、もう一つの方法としてapacheが提供しているクラスライブラリを使う方法もあります。
詳しい仕様は以下を参照してください。

[BOM付きのファイルを読み込むためのクラス](http://commons.apache.org/proper/commons-io/apidocs/org/apache/commons/io/input/BOMInputStream.html)

## 参考記事

[Javaを使ってBOMを削除するには](https://stackoverflow.com/questions/21891578/removing-bom-characters-using-java)
[UTF-8(BOM付き)の対処方法](https://www.rgagnon.com/javadetails/java-handle-utf8-file-with-bom.html)
data augmentationの1種mixupの簡単実装例

# mixupの概要
（編集予定）

↓参照
https://arxiv.org/pdf/1710.09412.pdf

# 簡単実装例
```python
def mixup(x, y, batch_size, alpha = 0.2):
    l = np.random.beta(alpha, alpha, batch_size)
    x_, y_ = sklearn.utils.shuffle(x, y)
    shape = tuple(-1 if i == 0 else 1 for i in range(len(x.shape)))
    x = l.reshape(shape) * x + (1 - l).reshape(shape) * x_
    shape = tuple(-1 if i == 0 else 1 for i in range(len(y.shape)))
    y = l.reshape(shape) * y + (1 - l).reshape(shape) * y_
    return x, y
```

## コードの解説
### 引数
|引数名|説明（type）|
|:-:|:--|
|x|入力データ（numpy.ndarray）|
|y|出力データ（numpy.ndarray）|
|batch_size|文字通りバッチサイズ（int）|
|alpha|β分布を決定するパラメタ（float）|

`x`と`y`はそれぞれバッチ単位で入力され，また，データセットはエポックが終わるたびにシャッフルされるという想定．

### 関数の中身
`l = np.random.beta(alpha, alpha, batch_size)`
ここでは，ブレンディングの重みを計算する．`l`のshapeは`(batch_size)`になる．

`x_, y_ = sklearn.utils.shuffle(x, y)`
ここでは，`x`と`y`の対応関係を保持したままシャッフルしている．

`shape = tuple(-1 if i == 0 else 1 for i in range(len(x.shape)))`
ここでは，`l`を`x`にブロードキャスト可能にするためのshapeを求めている．
たとえば，`x`のshapeが`(batch_size, width, height, ch)`のようになっていたとして，`l`のshapeが`(batch_size)`である場合，`l * x`をしたときに期待通りの計算結果にならない．また，`x`のshapeのよっては`operands could not be broadcast ...`といったエラーが出る場合がある．

`x = l.reshape(shape) * x + (1 - l).reshape(shape) * x_`
ここでは，`x`をブレンディングしている．

`shape = tuple(-1 if i == 0 else 1 for i in range(len(y.shape)))`
ここでは，`l`を`y`にブロードキャスト可能にするためのshapeを求めている．

`y = l.reshape(shape) * y + (1 - l).reshape(shape) * y_`
ここでは，`y`をブレンディングしている．

### 返り値
|返り値名|説明（type）|
|:-:|:--|
|x|ミックスされた入力データ（numpy.ndarray）|
|y|ミックスされた出力データ（numpy.ndarray）|

## サンプル

単位行列を入力データと見立ててmixupを適用すると以下のようになった．

|α = 0.1|α = 0.2|α = 0.3|
|:-:|:-:|:-:|
|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207140/0eef24d0-612e-1784-8a03-31a5cc11137c.png)|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207140/bb393b78-759e-779c-ffe2-99eac59b0f3e.png)|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207140/b3da931e-fac8-6059-c5e3-5cc40da36383.png)|

|α = 0.4|α = 0.5|α = 0.6|
|:-:|:-:|:-:|
|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207140/37e30698-c6e1-8a3f-72b2-b7d40b94a157.png)|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207140/b42c21d3-a976-2cb5-70ff-7fdcf9fcbcf3.png)|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207140/a69fc377-d8f6-0583-c211-99d64a657af8.png)|

|α = 0.7|α = 0.8|α = 0.9|
|:-:|:-:|:-:|
|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207140/cf2354d1-e1fc-f3eb-90c5-0bb8b50c002d.png)|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207140/f156bf74-c680-1480-7fe9-4bab8f6a0546.png)|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207140/f9780a58-7623-c4ba-873e-ccc7a3e5c2a0.png)|

# Reference
* mixup: BEYOND EMPIRICAL RISK MINIMIZATION (
https://arxiv.org/pdf/1710.09412.pdf)
Javaで文字列を整数・小数に変換(データのキャスト)するメソッドについて

##データ型の変換(データのキャスト)

####文字列等→整数・小数への変換

・整数へ変換するメソッド
Integer.parseInt(変数名);

・小数へ変換するメソッド
Double.parseDouble(変数名);

```
String text = "123"

System.out.println(text);  // 123 (文字列としてのそのまま出力)
System.out.println(Integer.parseInt(text)); // 123 (整数に変換)
System.out.println(Double.parseDouble(text)); // 123.0 (小数に変換)
```
CSSのいろんなposition使い方まとめ

CSSをやっているとたまに、positionがわからなくなります。

これたぶん初心者あるあるなんじゃないかな。
せっかくだから、自分の頭の整理がてら、まとめてみます。

#Positionとは

でもその前に、そもそも position とはなんなのでしょうか。

簡単に言うと要素の「配置・位置」を決めるCSSプロパティのこと。
要素を重ねるときや、要素を特定の位置に配置させる時に使用します。



#Positionの種類一覧

それでは、まずpositionの種類とその簡単な説明。今まで、なんとなく、これか！いや、うまく行かない、じゃあこれか！みたいな感じで使っていた感が否めないので、ここで大体の特徴は掴みたいと思います。


## static

何も指定しなければ、static というのがdefaultになっています。
このstaticというのは、位置の指定ができないもので、position=無効！みたいな感じで覚えておきます。もしpositionを変更したいのであれば、他のプロパティに変更する必要があります。


## relative

要素が通常配置される位置を基準に動かすプロパティ。
relativeは、通常配置されている位置は、確保されたまま要素が動くので、次に要素があっても詰められることがありません。



## absolute

親要素を基準とした中で絶対的な位置を決める。しかし、その場合、親要素は"必ずrelativeかfixed"でなければならない。
absoluteの場合、relativeと違い、通常配置されるはずだった位置は確保されずに動くので次にある要素が詰めてきます。


## fixed

absoluteと似ているが、親要素ではなく、ウィンドウ自体を基準として位置を決める。




#使える要素一覧


##left, right, top, bottomが使用できるのは


- relative
- absolute

またここでマイナスの値を指定することで、要素からはみ出すことができる。

※基本的に、rightとleftを同時に使用する、もしくは、topとbottomを同時に使用することはありません。もし同時に使用してしまった場合は下記の優先順位が適用されますのでご注意を。
right > left
top > bottom


##z-indexが使えるのは

- relative
- absolute
- fixed


#まとめ

positionは、ちゃんと理解できるまでは使うのが難しいです。
またfloatやdisplayなどと重なると、さらにわけわかめになってきますよね。。

でも、とりあえずdiv要素の配置に困ったら、positionで位置を固定することを心がけてみます。

ちなみに、position覚えるためには、こんなWEBSITE（テーマ）を模作してみると良いよ。

http://sage.theroar.nl/

（pinterestでオシャンなHP探してたら、見つけたやつ。）
[ALB][OIDC][LDAP][dex] AWS ALB で LDAP 認証連携に対応する

AWS 上で構築しているアプリを LDAP 認証に対応させようとしたら、今風の(と思われる)方式がなかなかに深かったので覚書です。

背景として以下のような状況があり、AD サーバによる LDAP 認証を追加することを考えます。

- ALB で複数のアプリへ振分
- ALB で SSL 終端
- 社内の既存の AD サーバによる認証を追加 [New]

なお、記事が長くなったので具体的な設定手順やハマりポイントなどの話題を関連記事として切り出しました。

- [AWS ALB の LDAP 認証連携の構築] (https://qiita.com/batatch/items/1577d453944070c19365)

- LDAP シンプルBIND方式と dexidp (予定)

～～

さて、ALB と認証周りについて調べてみると ALB による認証連携の機能があり、LDAP や AD との連携もできそうなことが書かれています。

Application Load Balancer を使用してユーザーを認証する
https://docs.aws.amazon.com/ja_jp/elasticloadbalancing/latest/application/listener-authenticate-users.html

ただ、実際には ALB が対応しているのは Open ID Connect (以下、OIDC) の連携のみで、OIDC に対応した IDプロバイダ(IdP)、もしくは Amazon Cognito と連携するしかなさそうです。

そこで、OIDC <-> LDAP のプロトコル変換する方法がないかと調べたところ、行きついたのが以下の dexidp というツール。

dexidp
https://github.com/dexidp/dex/releases

OIDC のフローを介して、認証処理本体を LDAP や Google 認証など複数選択式にすることができるようです。

ユーザを認証して ID 情報を提供するエンドポイントを OpenID Provider(OP) とか ID Provider(IdP) のように表記し、dexidp はこれにあたります。

ここでは dexidp を用いて以下のような認証環境を構築してみます。
具体的な手順についてはこちらにまとめます。

→[AWS ALB の LDAP 認証連携の構築](https://qiita.com/batatch/items/1577d453944070c19365)

![alb-oidc-component.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/558772/3803007f-3e8f-be62-dfe6-243c84574f4f.png)

ALB による OIDC の認証連携のシーケンスは以下のようになりました。

※あまり図的に説明した情報が見つからなかったので自分で作成することに。。

![alb-oidc-sequence.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/558772/34afde17-f7b6-01b6-3876-45f56132aa5a.png)

OIDC ではクライアントになるアプリ＝ Relying Party(RP) が、IdP から返ってきたアクセストークンを検証したり、属性情報を問い合わせたりするのですが、AWS ALB では ALB がこれを代行してくれます。

RP の振る舞いについては、以下の記事で実験をされていて分かりやすかったです。

OpenID Connect体験
https://qiita.com/sonedasaurus/items/753a65186f1be7185b39

ちなみに、今回初めて OIDC = OpenID Connect というキーワードを知りました。

LDAP 認証連携なんて一般的な方法で簡単に連携できるだろうと考えていたら、時代は先に進んでいました。。汗

個々に ID＋パスワード による認証から、認証は Google や Facebook のようなプロバイダに集約して、アプリ間で属性情報をやりとりする形に向かっています。

OIDC については、下記のサイトで背景などが説明されていて分かりやすいかと思います。

第一回 認証基盤のこれからを支えるOpenID Connect
https://www.ogis-ri.co.jp/otc/hiroba/technical/openid-connect/chap1.html

単なる OAuth 2.0 を認証に使うと、車が通れるほどのどでかいセキュリティー・ホールができる
https://www.sakimura.org/2012/02/1487/


なお、ALB による OIDC 連携では以下のような制約がありました。

- IdP のドメインの正式証明書が必要(オレオレ証明不可)
- IdP は HTTPS 必須
- アプリ側はオレオレ証明可
- ALB の外部用/内部用はいずれも可

今回のように LDAP 連携だと社内利用などのケースが多く、内部ドメインを使ってたりするとハマりポイントかもしれません。

また、IdP(dexidp)に正規の証明書を設定し、社内アプリ用の ALB と別建てする場合はアクセス制限で ALB→ALB な疎通を通しておくのも注意です。
ソフトウェアエンジニアの知識と労働時間

# 概要

まず始めに、ここでは比較的抽象的な表現を使用します。それは、一言に「ソフトウェアエンジニア」とは言っても、「サラリーマンとして」「フリーランスとして」「コーダーとして」「設計者として」など、立場によって在り方（この場合、ほとんどの場合働き方とほぼ同義に使用していると思ってください）が変わります。

私の単なる所感なので、まぁ参考程度に。

# 必要知識
私はソフトウェアエンジニアとして以下の知識があれば、何となくソフトウェアが作成できると思っています。

- コーディングスキル
    - データ型
    - 制御文
    - 関数
    - クラス
- 設計手法（オブジェクト指向やコンポーネント指向 etc.）
- 開発ツールの使い方（ライブラリ含む）
    - IDEの使い方
    - 言語ごとのパッケージ管理ツール
    - バージョン管理ツール（GItなど）
- OS知識（これは開発環境構築の都合上エンジニアの種類を問いません）
- パッケージの理解（DBMSなどはこちら）
- 通信仕様
- 検索エンジンでの調べ方
- 説明書をよく読む
    - （組込みエンジニアの場合はデバイス仕様）
    - （Webエンジニアの場合はクラウド知識）
- （必要であればコンテナ技術）

本来であれば、ソートアルゴリズムとかバイナリデータ処理、文字列処理などが挙がるものですが、近年は標準のライブラリが充実していたり、OSSの利用が当たり前になってきたりしているので、ここで特別に挙げる必要がないと考えています。それらは「検索エンジンでの調べ方」さえ分かっていれば、特段として覚える必要はないと思います。繰り返し調べるのが面倒である場合、スニッピングツールに登録すれば良いだけであると思います。

ここで重視している考えは、「**ツールの使い方**」「**設計手法の理解**」です。超絶コーディングスキルなんて後でついてきます。それよりは、腐りにくい知識をしっかり修める方が大切です。

会社にいると、あまりツールの使い方については重視していないように思います（組込み系は特に）。ここで勘違いしてほしくないのは、ツールにこだわった方が良いということではないということです。**「目的ごとに」「最適なツールを」「必要な機能だけ」使用することが大切**ということです。

# 労働時間

ソフトウェアエンジニアに限りませんが、エンジニアという職業の方は本質的なところで業務時間外で勉強しなければなりません。これは機械／電気エンジニアよりもソフトウェアエンジニアの方がその気質があります。


機械／電気エンジニアは、現実の物／現象を相手にしているので、その知識が腐りにくいです。鉄の質量はいきなり変わらないし、電気の速さが極端に遅くなることはありません。

それに対して、ソフトウェアエンジニアが対象とする技術は「情報」という曖昧なものなので、目にも見えなければ鮮度も悪くなりやすいです。今持っている知識も数年後には使われなくなったりもします。そのため、ソフトウェアエンジニアは常に新しい技術について調べないといけません。「調べないといけない」と言ってますが、それはエンジニアとして大成したければ、という前提です。そうでなければ、調べる必要はありません。これは機械／電気エンジニアでも言えることですが。

「勉強する」ことを「労働」と捉えるのかによって「労働時間」の捉え方は変わります。上記の通り、ソフトウェア開発界隈の流行り廃りのサイクルが早いです。この流れに乗れるか乗れないかで、食っていける領域に乗り続けることが出来ないと私は考えています（これは極論でもありますが）。最近は終身雇用が破綻するとも言われてますし、そうなると最初に切られるのって「勉強しないエンジニア」だと思います。こういうところが一番ソフトウェアエンジニアの業の深さを表しているように思います。
【Visual Studio Code】 Visual Studio Codeのターミナルをnyagosやcmderに変更する

# はじめに

「Visual Studio Code」でターミナル起動、標準で「nyagos」にしたいなと思ったときに調べました。
基本的には、参考の記事を元に作成しています。ありがとうございます。参考になりました。

とまあ、その時のメモです。

# 内容
適応までの流れを以下に記述します。

## 手順
### 1. 「Ctrl + ,」を押してVSCode Settingsを起動する
### 2. settings.jsonを検索
### 3. settings.jsonの編集をクリックし編集画面へ
### 4. jsonファイルが開かれるので以下を追記や編集

```json
{
    "terminal.integrated.shell.windows": "cmd.exe",
    "terminal.integrated.shellArgs.windows": [
        "/k","C:\\Users\\ユーザ名\\nyagosやcmderまでのパス\\nyagos.exe"
    ],
}
```

エスケープする必要があるので、以下を参考にしながら設定指定してください。

```txt
C:\bin\cmder → “C:\\bin\\cmder\\vendor\\init.bat”
```

# 参考
https://mosapride.com/index.php/2019/03/25/post-1277/
コッホ曲線 JavaScript

```
<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title></title>
    <script>
        var ctx;

        function init() {
            var canvas = document.getElementById('main_canvas');
            if (!canvas || !canvas.getContext) {
                return;
            }
            ctx = canvas.getContext('2d');

            var N = 3;
            Koch(0, 260, 150, 0, N);
            Koch(150, 0, 300, 260, N);
            Koch(300, 260, 0, 260, N);
        }

        function Koch(ox, oy, rx, ry, n) {
            var dx = rx - ox;
            var dy = ry - oy;

            var px = ox + dx / 3;
            var py = oy + dy / 3;
            var qx = ox + dx / 3 * 2;
            var qy = oy + dy / 3 * 2;

            var distance = Math.sqrt(dx * dx + dy * dy) / Math.sqrt(3);
            var radian;
            var sx;
            var sy;
            if (dx >= 0) {
                radian = Math.atan(-dy / dx) + Math.PI / 6;
                sx = ox + distance * Math.cos(radian);
                sy = oy - distance * Math.sin(radian);
            } else {
                radian = Math.atan(-dy / dx) - Math.PI / 6;
                sx = rx + distance * Math.cos(radian);
                sy = ry - distance * Math.sin(radian);
            }

            if (n == 0) {
                draw(ox, oy, px, py);
                draw(px, py, sx, sy);
                draw(sx, sy, qx, qy);
                draw(qx, qy, rx, ry);
            } else {
                Koch(ox, oy, px, py, n - 1);
                Koch(px, py, sx, sy, n - 1);
                Koch(sx, sy, qx, qy, n - 1);
                Koch(qx, qy, rx, ry, n - 1);
            }
        }

        function draw(x1, y1, x2, y2) {
            ctx.beginPath();
            ctx.moveTo(x1, y1);
            ctx.lineTo(x2, y2);
            ctx.stroke();
        }
    </script>
</head>

<body onload="init()">
    <canvas id="main_canvas" width="350" height="350" style="background-color:#eeeeee;"></canvas>
</body>

</html>
```
ASP.NET WebForm を この本でやっと理解しました。

# ASP.NET とは
Access や Excel の デスクトップアプリで VBA ばかりをやってきた私には、Webアプリを習得するには、かなり時間がかかりました。いまになって、やっと理解できました。

ASP.NET には、色々な開発方法があります。
Web Form、MVC、Web Page などです。
デスクトップアプリになれている私には、Web Form が理解しやすかったです。

VBA になれていたので、下記の本で ASP.NET Webフォーム を Visual Basic で学習しました。
<a target="_blank"  href="https://www.amazon.co.jp/gp/product/479805805X/ref=as_li_tl?ie=UTF8&camp=247&creative=1211&creativeASIN=479805805X&linkCode=as2&tag=timsoft-22&linkId=457bf3b5ed6813b5fa9a87f63cec909b"><img border="0" src="//ws-fe.amazon-adsystem.com/widgets/q?_encoding=UTF8&MarketPlace=JP&ASIN=479805805X&ServiceVersion=20070822&ID=AsinImage&WS=1&Format=_SL250_&tag=timsoft-22" ></a><img src="//ir-jp.amazon-adsystem.com/e/ir?t=timsoft-22&l=am2&o=9&a=479805805X" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />
学習しながら、必要なことを書き留めていこうと思います。

HTML言語では、テキストボックスや表などのパーツを表示するには、<input type="text">などとタグで記述しなければなりません。
Visual Studio を使って ASP.NET を開発すると、ドラッグするたけでテキストボックスや表などのパーツを配置することができます。

## サーバーコントロール


Webサーバーコントロール
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93227/fc1fa6d6-e3a2-a22c-1864-8236e96fe476.png)

HTMLサーバーコントロール
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93227/4418a08c-5df7-e0db-11a5-cf774762d410.png)

Webサーバーコントロールは、HTMLタグを使って作成した部品です。
例えば、カレンダーコントロールなどは、<TABLE>タグを使って作成した部品です。

HTMLサーバーコントロールは、HTMLタグをドラッグしますので、1つのパーツには、1つのHTMLタグが出来上がります。

Webサーバーコントロールは、HTMLタグを組み合わせた部品が出来上がります。

こんな基本的なことを理解せずに、ASP.NET の本を何冊も読んでいました。
この本でやっと理解できました。
[strong parameters][form_with]投稿にユーザー情報を表示する

#概要
###目的
プロゲート以外の方法（strong parameters）で投稿詳細に投稿主（ユーザー）情報を記載すること。
（ちなみにプロゲートは[こんな感じ](https://qiita.com/akr03xxx/items/6a3f23a53dd887ab26f7)）
###実現したいこと
| 各action           | すること（ポイント） |  
|:-----------------|------------------:|
| new             |              from_withを使って、投稿。 |
| create           |            strong parametersを使用して処理。 |
| show            |              投稿にユーザー情報を引っ張ってくる。 |  

このような流れで進めていきます。


###完成イメージ
<img width="561" alt="スクリーンショット 2020-01-25 15.47.36.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504349/2fcf4217-0597-3b5f-566c-f0096495011f.png">
画像ではユーザー名、アイコン記載しておりますが、
今回は分かりやすく理解してもらうために**ユーザー名**だけの表示します。

#環境
Ruby 2.5.6
Rails 5.2.3

#前提
- userのデーブルがあり、「name」カラムがあること。
- 投稿モデルは今回commentモデルであること。
- deviseを導入していること。（current_userを使用している為）

#strong parametersとは？
一言でいうと
**「Web画面上から内部へ流れてきた値を安全に受け取る仕組み」**のことです。
もう少し噛み砕いて簡単に説明すると、
入力フォームで記述した情報（名前、メールアドレス等）を安全にバックエンドに渡す仕組みのことです。

今回そのストロングパラメーターを使用します。

参考URL
[Rails初学者がつまずきやすい「ストロングパラメータの仕組み」](https://www.transnet.ne.jp/2016/05/18/rails%E5%88%9D%E5%AD%A6%E8%80%85%E3%82%B9%E3%83%88%E3%83%AD%E3%83%B3%E3%82%B0%E3%83%91%E3%83%A9%E3%83%A1%E3%83%BC%E3%82%BF%E3%83%BCcolnr/)
[【Rails入門】params使い方まとめ](https://www.sejuku.net/blog/29763)

#new（form_withを使って投稿）
ここでの目的は**from_withを使って、投稿**出来るようにします。

```erb:comments/new.html.erb
<%= form_with model: @comment, local: true  do |form| %>
 <%= form.text_area :content,class:"new_text" %>
<% end %>

```

このようにform_withを使用して、入力された情報をストロングパラメーターで受け取れるようにします。

#controller(strong parametersを使用して処理)
```ruby:app/controllers/comments_controller.rb
    def new
      @comment = Comment.new
    end

    def create
      @comment = Comment.create params.require(:comment).permit(:content).merge(user_id: current_user.id)

    end

    def show
      @comment = Comment.find(params[:id])
      @user = User.find_by(id: @comment.user_id)
    end
```

###★解説★
ここでのポイントはcreateアクションの時に、
newで入力された特定の情報（今回はcontent）しか
情報は受け取りませんよ〜！っていう設定をしています。

###★ポイント★
#####（１）ログインしているユーザーIDの読み取り

**createアクション**を実行した時に入力されたcontent以外にもその時に
**ログインしているユーザーID**を受け取る設定しています。
current_userはストロングパラメーターでは適用対象外なので、
**mergeメソッド**を使用して受け取れるようにしました。

#####(2)ログインしているユーザーIDの受け取り
**showアクション**を実行した時に、
createアクションで読み取ったユーザーIDを紐付けています。


参考URL
[【Ruby on Rails】ストロングパラメータって何なの？](https://qiita.com/ozackiee/items/f100fd51f4839b3fdca8#3%E3%82%B9%E3%83%88%E3%83%AD%E3%83%B3%E3%82%B0%E3%83%91%E3%83%A9%E3%83%A1%E3%83%BC%E3%82%BF%E3%81%AE%E9%81%A9%E7%94%A8%E5%AF%BE%E8%B1%A1)

#show(投稿にユーザー情報を引っ張る)


```erb:app/views/comments/show.html.erb
<%= @user.name%> #名前を表示
<%=@comment.content%>　#投稿内容を表示
```


これで投稿にユーザー情報を紐付けることが出来ました！

#最後に
まだまだ勉強不足なところがありますので、
アップデートできた知識は追加で記載していきます。

もし、何か修正点とかございましたらコメント等
恐縮ですが、宜しくおねがいします。
IntelliJでGoアプリケーション開発の始め方

[IntelliJ IDEAでGo言語(golang)を始める〜GOPATHの設定など](https://qiita.com/aki-takano/items/7bd8b879572f58b03cdc)
[IntelliJ IDEAでGoを書く](https://note.com/b1a9idps/n/n34de69179a10)
「新サービスを作るときの“3カ条”」が素晴らしかったのでまとめてみた

本記事は「[「ここまで考えて、マネタイズするのが商売」光本×佐藤コンビがモバイルオーダーアプリにガチ指導](https://r25.jp/article/750590431100372964)」の要点をまとめた記事となります。

こちらの記事で紹介されている、
「新サービスを作るときの“3カ条”」

がシンプルでありながら、非常に強力なものだと感じたので、
それらを図を用いて簡単にまとめてみました。

新しいサービスをつくる際の参考となれば幸いです。

## ①「圧倒的な引力を用意しろ」!
![圧倒的な引力を用意しろ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138735/8042ed56-63c5-b95c-123a-7b3a8b0705a2.png)

>世間に浸透していないサービス開始直後だからこそ、利用できる場所の数やサイズに左右されない、絶対的なメリットが必要

引用：（[「ここまで考えて、マネタイズするのが商売」光本×佐藤コンビがモバイルオーダーアプリにガチ指導](https://r25.jp/article/750590431100372964)）

このサービス使わない理由がない、使って当たり前、とユーザーに思わせるような魅力を持つことが大事です。
例えば「アダルト動画サイト」はいろんなところに広告が張り巡らされていてお目当のページに行きつくまでに何回もクリックしますが、みんな見てしまいますよね？
これも「圧倒的な引力（コンテンツ）」があるからこそなんですよね。
「圧倒的な引力」を作り出す方法は2パターンあるかなと思っていて、それは「コンテンツ」と「ユーザー体験」です。
「コンテンツ」は上記の「アダルト動画サイト」がそうですし、後は「ポケモン」、「ドラクエ」といったキャラクターを扱うもの、情報発信としての「記事」、「動画」を扱うものがあるかと思います。
「ユーザー体験」は今までなかったような体験をユーザーに提供することが魅力となり得ます。記事中では「メルカリ」の簡単な出品方法について記載されていました。ユーザーのアクションが圧倒的に減り簡単になる、そもそもユーザーからアクションをせずとも自動でできる、サービスのパフォーマンスが圧倒的に改善しているなどの要素が「引力」となるかと思います。

## ②「八方美人になるな」
![八方美人になるな.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138735/0a7be1bf-f5c5-b16d-5f67-b36df011e46d.png)

>「自分たちの提案に乗ってくれそうな人たち」を探すことが初期顧客を設定するときのセオリー。
~省略~
機能を増やしちゃうのって、ようは「保険」をかけたいだけなんですよね。
全部入れとけば、誰かしらに使ってもらえるだろうっていう

引用：（[「ここまで考えて、マネタイズするのが商売」光本×佐藤コンビがモバイルオーダーアプリにガチ指導](https://r25.jp/article/750590431100372964)）

機能を増やしたり、ターゲートを広くとる前に、まずは自分達に興味を持ってくれている人たちに最大の価値を提供することを考えましょう。そうして、サービスに熱狂してくれる人を増やしていくことで口コミの効果も増えることでしょう。


## ③「誰も犠牲にならないマネタイズを考えろ」
![誰も犠牲にならないマネタイズを考えろ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138735/7c2547fd-932f-07d0-3ff9-3b54bb7bb80b.png)

サービス運営に際して、どこかで誰かが料金を支払い、運営者が利益を得る必要があります。
「損失回避の法則」はご存知でしょうか？
人は損失には敏感に反応します、[今回の記事]((https://r25.jp/article/750590431100372964))の例ですと対象ユーザーが飲食店のユーザーなのでより一層敏感に反応する可能性があります。
サービス全体のどこかで不満が大きくなるよりは、各主体が受けるメリットを最大化しその上で「商売をする」ことが重要でしょう。
Githubの登録覚書

内容：GitHubにユーザー登録、ssh登録する
参考：https://www.sejuku.net/blog/74220
目的：Qiita投稿テスト、備忘録

①Githubにユーザー登録する
設定→メール受信、認証→登録完了メールを受信
(このあと自分のレポジトリを立てるモードに入る、個人レポジトリが現状必要ないのならスルーして良い)

②sshキーを設定する

sshとは何か？
SSH（Secure SHell）はサーバーのセキュリティを確保するためのもの
インターネットを経由してサーバーにログインし、操作できる人を制限できる。
公開鍵と秘密鍵の2つのキーのペアからなる。
ユーザーは秘密鍵を、サーバーは公開鍵を保有する。
ログインを試みると、サーバーは秘密鍵でしか解読できない暗号を渡してくる。ログインする側は秘密鍵を用いて復号した情報にして返す。これが、正解であった時、ログインに成功する。

GitHubとssh
GitHubでは、リモートリポジトリと接続する際に、http,https,git,sshの4種が存在する。
今回sshを扱った理由：仕組みが簡単、セキュリティの確保のため


GitHubにsshキーを登録する by.Mac

❶sshキーの作り方(Unix)

cd ~/.ssh
or(mkdir ~/.ssh)
ls(場所確認)
ssh-keygen -t rsa(-keygen：キーの作成、rsa形式)
ls(id_rsa、id_rsa.pubという2つのファイルが確認できるはず)
pbcopy < ~/.ssh/id_rsa.pub (クリップボードにファイル内の文字列が保存される）


❷GitHubに登録する
メイン画面→アイコン→[setting]→[ssh and GPG keys]
ここで、適当に命名(ex,myMAC)
下のキー入力のところに、command+v

完了！
型の違う値を型変換して別の変数に代入する方法

##文法

####データ型　変数名　＝ (データ型) 代入される側の変数名

※型指定/型キャストをする場合、右辺のデータ型を括弧で括る必要があります。忘れがちなので注意(戒め)。



```
public class Main {
	public static void main(String[] args) {

        double rand = Math.random(); * 100;

        //変数に変数を代入
		int number = (int)rand;

		System.out.println(number);
	}
}

```

##おまけ

###変数定義と同時にMath関数を代入することも可能
その場合は、()でくくる。

```
int game_num = (int)(Math.random() * 10 + 1);
System.out.println("ゲームの本数は" + game_num + "個");
```
オーバーレイのアイコンの取得と表示

TortoiseGitをインストールした際にエクスプローラーなどに表示されるアイコンを取得表示する。
===========

アイコン情報を取得するには、
`SHGetFileInfo`
を使用します。

フラグに
`SHGFI_OVERLAYINDEX`
を追加するよ！

ハンドルを取得出来たら
`DestroyIcon(shfi.hIcon)`
でアイコンは開放しておく。

例）
アイコンのハンドルとインデックス番号を取得する関数

```c++
#include <shellapi.h>

#pragma comment(lib, "Shell32.lib")

HANDLE get_icon_handle(const TCHAR *entry, DWORD *d_no)
{
  SHFILEINFO  shfi;
  HANDLE      handle;

  handle = (HIMAGELIST)::SHGetFileInfo(entry,
                                       FILE_ATTRIBUTE_ARCHIVE,
                                      &shfi,
                                       sizeof( SHFILEINFO ),
                                         SHGFI_SMALLICON
                                       | SHGFI_SYSICONINDEX
                                       | SHGFI_OVERLAYINDEX
                                       | SHGFI_ICON);
  if (handle)
    {
      *d_no = shfi.iIcon;

      ::DestroyIcon(shfi.hIcon);
    }

  return handle;
}
```

アイコンを表示するには、
`ImageList_DrawEx`
を使います。

sub_indexにオーバーレイのインデックス番号が入ります。
オーバーレイされたファイルのアイコンが表示できます。

フラグに指定する、
`INDEXTOOVERLAYMASK(sub_index)`
これが重要！

例）
上で取得したハンドルとアイコンインデックスを使ってアイコンを表示する関数

```c++
void draw_icon(HDC hDC, HANDLE handle, int x, int y, int d_no)
{
  DWORD       index;
  DWORD       sub_index;

  index     =  d_no & 0x00FFFFFF;
  sub_index = (d_no & 0x0F000000) >> 24;

  ImageList_DrawEx(handle,
                   index,
                   hDC,
                   x,
                   y,
                   16,
                   16,
                   CLR_NONE,
                   CLR_NONE,
                   INDEXTOOVERLAYMASK(sub_index) | ILD_NORMAL);
}
flexbox関連でよく使うcssプロパティまとめ

## 参考情報
* coliss: CSS Flexbox の基礎知識と使い方をやさしく解説 [link](https://coliss.com/articles/build-websites/operation/css/css3-flexbox-properties-by-scotch.html)
  * 各プロパティの詳細な説明や概観理解はこちらを参照した方がよいと思います


## 例html
```html
<body>
  <div class="flex-container">
    <div class="flex-item">1</div>
    <div class="flex-item">2</div>
    <div class="flex-item">3</div>
  </div>
</body>
```

## css
```css
.flex-container {
  display: flex; /* 子要素がflexアイテムになる */
  display: inline-flex; /* インライン要素をflexアイテムにしたい場合 */

  /* flexコンテナの主軸の方法を */
  flex-direction: row /* 左から右の水平方向に設定する. default */
  flex-direction: row-reverse /* 右から左の水平方向に設定する */
  flex-direction: column /* 上から下の垂直方法に設定する */
  flex-direction: column-reverse /* 下から上の垂直方向に設定する */

  /* flexコンテナのwrap方法を指定 */
  flex-wrap: nowrap; /* 複数のアイテムを1行に配置する. default */
  flex-wrap: wrap; /* 必要に応じてflexアイテムを左から右、上から下に複数行に配置する */
  flex-wrap: wrap-reverse; /* flexアイテムを左から右、下から上へ複数行に配置する */

  /* flex-directionとflex-wrapをまとめて設定する */
  flex-flow: <flex-direction> || <flex-wrap>;
  flex-flow: row nowrap; /* default */

  /* flexコンテナの主軸に剃ってflexアイテムを1行に配置する */
  justify-content: flex-start; /* モードに従い、flexコンテナの左側に配置される. default */
  justify-content: flex-end; /* モードに従い、flexコンテナの右側に配置される */
  justify-content: center; /* flexコンテナの中央に配置される */
  justify-content: space-between; /* 最初と最後のアイテムは端に、残りは等間隔で配置される */
  justify-content: space-around; /* 等間隔のmarginを持ったアイテムが等間隔に配置される */

  /* flexコンテナのクロス軸に垂直方向で配置する
  align-items: stretch; /* flexアイテムはflexコンテナの高さ（または幅）いっぱいに配置される */
  align-items: flex-start; /* flexアイテムはクロス軸の視点に配置される. 上側とか */
  align-items: flex-end; /* flexアイテムはflexコンテナのクロス軸の終点に配置される. 下側とか */
  align-items: center; /* flexアイテムはflexコンテナのクロス軸の中央に配置される */
  align-items: baseline; /* flexアイテムはベースラインに沿って配置される. ベースラインはggr */
}

.flex-item {
  /* flexアイテムの相対配置順位を指定する */
  order: <integer>

  /* フリーのポジティブなスペースがある場合、 */
  /* flexアイテムが他のflexアイテムと比較してどのくらいの大きさになるかを指定する */
  flex-grow: <number>;
  flex-grow: 0; /* 伸長しない. default */
  
  /* フリーのネガティブなスペースがある場合、 */
  /* flexアイテムが他のflexアイテムと比較してどのくらい縮まるかを指定する */
  flex-shrink: <number>;
  flex-shrink: 0; /* オリジナルのサイズを維持する */
  flex-shrink: 1; /* default */

  /* flexアイテムの最初のメインとなるサイズを指定する */
  flex-basis: auto | <width>;
  flex-basis: 350px; /* デフォルトのサイズを350pxに指定する */
  flex-basis: auto /* default */

  /* flex-grow, flex-shrink, flex-basisを指定するショートハンド */
  /* w3c推奨 */
  flex: none | auto | [ <flex-grow> <flex-shrink>? || <flex-basis> ];
  flex: 0 1 auto; /* default */

  /* 個別のflexアイテムのalign-items値を指定する */
  align-self: auto | flex-start | flex-end | center | baseline | stretch;
  align-self: auto; /* default */
}

```
Xサーバ無し動作のRetroPieゲーム静止画/動画キャプチャをWindowsからとる

デスクワークをしていると、離れたところで動かしているXサーバ無しRetroPieのデモキャストを見て癒やされたくなる瞬間が、私たちにしばしば訪れます。しかし秘技が明かされることはあまりないようです。そこでおっかなびっくりでやってみることにしました。意外と簡単でした。
##前提条件
- Raspberry Pi 4
- Raspbian Buster Lite
- RetroPie 4.5.1 / emulationstation **without X server**
- SSH server
- (クライアント=Windows側) UltraVNC Viewer, **not RealVNC**

以上で問題なく遊べている、また、SSH接続できていること。この記事の以下の作業はSSHで行っています。加えて、動画キャスティングは負荷がかかることもあり、何かのときに備えてSSHはつないでおくのがお勧めです。なお、繰り返しになりますが、動画撮影にクライアントWindowsではUltraVNCを使用します。RealVNCは(今回は)使用していません。

##静止画撮影
[raspi2png](https://github.com/AndrewFromMelbourne/raspi2png)を使用します。VNC不要、SSH接続だけでOKです。

###導入方法
```
$ curl -sL https://raw.githubusercontent.com/AndrewFromMelbourne/raspi2png/master/installer.sh | bash -
```

- 参考: [raspi2png を使って Raspberry Pi のスクリーンショットを撮影する](https://qiita.com/niwasawa/items/a94cf54423d7c75833c1) thanks to @niwasawa san!

###使用方法

エイリアスを設定しておくと便利です。

```
$ tail .bashrc
function funcr2p() {
raspi2png -p $(date -u +%Y%m%d_%H%M%S_%3N).png;
# some nice command(s) accordingly
}
alias r2p=funcr2p
```

```
$ source .bashrc
$ r2p
```
r2pを実行した階層に、(例)20200126_040251_576.pngが保存されます。sambaなどしておくとうまうまですね!
![EPC2xQeVAAYMYTV.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159724/00573010-1cca-696f-327b-aa8a7bf347f4.png)


##動画撮影
###サーバ側
Raspbian BusterではReal VNCがデフォルトで入っていると思いますので、その前提で。

```
$ sudo cat /root/.vnc/config.d/vncserver-x11
```
次の4行が入っていないと思いますので、入れて下さい。

```
Authentication=VncAuth
CaptureTech=raspi
ExperimentalRaspiCapture=1
ServerPreferredEncoding=JPEG
```
- 第1行は、クライアント(Windows)側でUltraVNCを使用する前提で入れます。冒頭に記したように、クライアントでRealVNCは使用しませんので、ご注意ください。
- 第2行は、現時点でexprimental(実験的な)サポートのようです。機能してはいますし、今回のスコープではこれがないと動きませんので、**そういうものと思って**入れてください。
- 第3行は、[公式に推奨設定とありました](https://help.realvnc.com/hc/en-us/articles/360002251297-VNC-Server-Parameter-Reference-)ので、従いました。
- 第4行は、第2行、第3行とのセットでの決め打ちです。公式ドキュメントを参照してください。


次に、vnc server接続のパスワード設定が必要です。

```
$ sudo vncpasswd -service
```
し、[kitabeppu214](https://ameblo.jp/manabu-kitabeppu/entry-12568654448.html)とかしてください。

###クライアント側
- [UltraVNC Viewer](https://www.uvnc.com/downloads/ultravnc.html)を入れてください。Viewer以外は不要です。
- Connectします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159724/376cb78c-49f2-16ed-1f10-053fb81f20da.png)

- パスワードを訊いてきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159724/cfa6b16f-032d-315a-03af-9352d852857a.png)

- 先ほどの、kitabeppu214と入れ、Log Onします。
- RetroPie / emulationstationの画面が、新規ウィンドウに表示されます(あとは、みなさんなら適当にやってできると思います)。
- 動画撮影に、私は、[ロイロゲームレコーダー](https://loilo.tv/jp/product/game_recorder)を[使用しました](https://twitter.com/nekohanahime/status/1221232895953555458)。
- 今回のスコープでは、(クライアント=Windows側で)**音は鳴りません**。

以上です。
Word Cloud の文字を単色にする方法

## 背景
Python の [Word Cloudライブラリ](https://github.com/amueller/word_cloud)では、文字色がランダムに設定されます。
colormapで色テーマを設定することができますが、文字を単色に設定することはできません。

## 方法
まず、文字色を返す関数を定義します。下記のコードでは白色に設定しています。

```
word_color_func = lambda *args, **kwargs: "white"
```
次に、定義した関数を WordCloudクラスの引数（color_func）に渡します。

```
wordcloud = WordCloud(
    color_func = word_color_func,
    background_color = "black",
    width = 1000,
    height = 500,
).generate(text)
```
以上で、Word Cloudの文字色は下図のように変更されます。
WordCloudに渡したテキスト情報は、[Wikipediaの「Machine learning」](https://en.wikipedia.org/wiki/Machine_learning)です。
![wordcloud_example.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329863/b53f4f32-02f5-0d62-a020-7b95f02dcd54.png)

## 補足
RGB形式でも、文字色を設定が可能です。詳細は[こちら](https://github.com/amueller/word_cloud/blob/master/wordcloud/wordcloud.py#L231)に記載されています。

```
color_func=lambda *args, **kwargs: (255,255,255)
```
AWSのSolutionsArchitectAssociateを受験しました

受験しました。暫定で結果は出ました。

**直前に受けた模擬試験の結果**

```
総合スコア: 84%
トピックレベルスコア:
1.0  Design Resilient Architectures: 88%
2.0  Define Performant Architectures: 85%
3.0  Specify Secure Applications and Architectures: 66%
4.0  Design Cost-Optimized Architectures: 100%
5.0  Define Operationally-Excellent Architectures: 100%
```
## 感想
・過去AWSを使っていて、数年離れて、また業務で利用し始めました
・数年前にProまで取得していたが、再度知識確認目的で受けました
・以前受けた時はもっと単純な問題が多い記憶がありました。難易度が上がったように思います

※私自身Udemyとはなんの関係もないですが・・・
個人の主観ですが、過去AWSを触っていて最新の動向を知りたいであったり
今からAWSを覚える際に有料学習動画が一番コスパと時間効率が良いと思います。
https://www.udemy.com/course/aws-associate/
（ほぼ毎週割引セールをやっていて、90%OFFで売りにでてます）

今回受験にあたり、各サービスの最新仕様を確認するため
上記を購入して、1.5倍速などで一気に見ました。

20200127 9:00追記
通ってました
![Screen Shot 2020-01-27 at 8.48.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110457/13fd0f06-72ea-e876-d561-b4ea4f518131.png)
[macOS] コピペする時にスタイルが付いてしまう悩みを解消

## これは何？

少し前にTwitter上でコピペしたらスタイルテキストが付いてて面倒くさいという話題が上がっていたので、アプリケーションをスイッチした時にクリップボードからスタイルテキストを削除するMenu Bar Extraを作ってみました。

なお私は公証を得る権利を持っていないためアプリケーションの頒布は行っておりません。
MITライセンスにて[GitHub](https://github.com/masakih/StyleRemover)に公開しています。

## 使い方
アプリケーションですので起動するだけでOKです。
<img width="211" alt="スクリーンショット 2020-01-26 12.11.52.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2117/a1381bf6-fef1-53a6-dc68-df4884b61273.jpeg">

メニューから有効無効を変更出来ます。アイコンによりひとめで状態確認が出来ます。
<img width="103" alt="スクリーンショット 2020-01-26 12.12.21.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2117/2c7a452a-586e-cd63-f2bf-2fedf3ad6a12.jpeg">　有効のとき。　<img width="103" alt="スクリーンショット 2020-01-26 12.12.28.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2117/508c1aa7-dda8-2c81-4508-3073dbca0613.jpeg">　無効のとき。

### 設定
環境設定からどのアプリケーションに切り替えた時にスタイルテキストを削除するかを変更出来ます。
<img width="551" alt="スクリーンショット 2020-01-26 12.12.35.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2117/bc289c84-1626-4ba0-068a-fc9ce335f611.jpeg">

## 支える技術

おまけです。

### Menu Bar Extra

Menu Bar Extraは`NSStatusBar#statusItem(withLength:)`を使って`NSStatusItem`のインスタンスを取得し`NSMeun`とアイコン（NSButtonのimage）を設定するだけで表示されます。

### Menu Bar Extraの環境設定パネルの表示
アプリケーションに依存しないMenu Bar Extraでは、通常Info.plistで`LSUIElement`をYESにしてバックグラウンドアプリケーションとします。
この場合、環境設定パネルがメインウインドウとならないため、`NSApplication.shared.activate(ignoringOtherApps: true)`を使い強制的にメインウインドウにします。

ちなみにアプリケーションに依存するMenu Bar Extraとは、アプリケーションが起動中にのみに表示され、アプリケーションがバックグラウンドに回っていてもすぐにアクセス出来るようなコマンド群がまとめられたものです。
僕は見たことがありません。

### macOSのクリップボード

macOSのクリップボードにはもちろんコピーした内容が入っているのですが、通常複数の種類のデータが登録されています。
例えばFinderで一般的な画像のファイルをコピーすると、ファイル名、fileURL、ファイルのアイコン、画像をTIFF化したものなどなど様々なものがクリップボードに入れられています。
これらは（内部的には文字列の）キーと値の辞書の形でクリップボードに登録されています。
ペーストを行うアプリケーションはこの中から独自の優先順位を用いて最優先の内容をペーストします。

### クリップボードからのスタイルテキストの除去

`NSPasteboard`は`types`プロパティとして現在登録中のデータのキーが提供されています。
これを文字列にして、その中に特定の文字列があるものを削除しています。
ただし、単純に削除することは出来ないため、一度クリップボードの内容を全て取り出し、クリップボードをクリアしてから、削除対象以外を登録し直すという作業を行っています。

### 最前面のアプリケーションの監視

`NSWorkspace`の`frontmostApplication`がKVOコンパチブルなのでこれを監視すればいいです。

### Combine

今回はKVOおよびTarget-ActionをCombineを用いて処理しています。
Combineはいいですね！

Target-ActionをCombineで処理するために[このようなClass/Struct群](https://github.com/masakih/StyleRemover/blob/master/StyleRemover/Sources/ActionPublisher.swift)を作成しました。

### SwiftUI

SwiftUIはプラットフォームの垣根を越えてUIを作成出来る素晴らしいフレームワークです。 WWDCのビデオを見てすごく興奮しました。

いつ正式リリースされますか？
いまってDeveloper Releaseですよね？
え？あの出来で正式版？　ご冗談でしょ、Appleさん

## おわりに

アイコンが描けない...
xamppでmysqlを使う設定(ポート番号変更~rootパスワード設定まで)

##xampp(7.2.4)でmysqlを使うには

sqlite3ではなく、mysqlを使ってみたい。
と思ったのだが、数々の難問が降りかかってきた。
そのうちの幾つかを記録したい。

###１．xamppのコントロールパネルからmysqlが起動しない。

※イメージはポート番号変更後

####configを右クリックでmy.iniを表示。

![maria_setting1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/494408/c6649cbb-9ea7-fa60-92e4-2f74ec21fc1e.jpeg)

####赤枠のようにポート番号を変更

3306がデフォルトらしいが、このままだと起動できないので「3308」に変更

![xampp_mysql1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/494408/01207a80-428e-9720-0c8a-d3462379ee89.jpeg)

無事にコンパネから、mysqlサービスが起動できた
![maria_setting3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/494408/afab3abe-17e3-d0f8-8c06-23fa27284ee0.jpeg)


###２．コンパネのshellから、mysqlのrootパスワードを設定

コンパネのshellを起動し、
「xamppのインストールディレクトリ\mysql\bin」まで移動。

ディレクトリに移動後
__「mysql -u root -p」を入力後
「Enter password」でエンターキーを押下。(ここは空パスワードでok)__

![mysql_setting_xampp7_2_4_1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/494408/1d7fb26c-94a9-49a9-c5ae-692b2f8f4d02.jpeg)

接続できることが確認できた。

管理者パスワードを設定するために下記コマンドを入力する。
「mysqladmin -u root password」
を入力すると、「New password」が表示されたら、
自分で決めたパスワードを入力する。

![mysql_setting_xampp7_2_4_2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/494408/ae1ecf59-9a47-2dd3-c337-f51546812894.jpeg)

とりあえず、rootパスワードの変更が完了。

※ここから先データベース作成等は、このshell(黒画面)から行うことになる。
Excel VBAで他のブックの特定のセルの値をファイルを開かずに取得する方法

# Application.ExecuteExcel4Macroメソッドを使う
このメソッドは、Microsoft Excel 4.0 マクロ関数を実行するメソッドですが、
引数に取得したいブックの絶対パスとシート名とセルへの参照を指定することで、
**対象のブックをオープンせずに**、その値を取得することができます。
※メモリ上に展開されるだけで、ウィンドウは開かないという事です。

```vb
Dim a As Variant
a = ExecuteExcel4Macro("'C:\tmp\[sample.xls]Sheet1'!R1C2")
```
上記の場合は、 **C:\tmp\sample.xls の Sheet1 の B2セル の値**をブックを開かずに取得しています。
この関数では、セルへの参照は R1C1 形式の文字列として指定する必要があります。

# 相対パスで他のブックへ参照を行いたい場合
自ブックから特定の相対パスにあるブックへの参照を行いたい場合は、
**Scripting.FileSystemObjectオブジェクト**を利用して対象ファイルの絶対パスを取得してExecuteExcel4Macroメソッドに渡します。

例）自ブックと同じフォルダに存在するすべての「.xls」ファイルのSheet1シートのB2セルの値を取得する場合

```vb
' FileSystemObjectを使用して現在のフォルダのFolderオブジェクトを取得
Dim fso As FileSystemObject
Set fso = CreateObject("Scripting.FileSystemObject")
Dim currentFolder As Folder
Set currentFolder = fso.GetFolder("./")

' 自ファイルと同じフォルダにあるブックのSheet1シートのB2セルの値を取得
Dim i As Integer: i = 1
For Each f In currentFolder.Files
    If f.Name Like "*.xls" Then
        Cells(i, 1) = ExecuteExcel4Macro("'" & f.Path "[" & f.Name & "]Sheet1'!R1C2")
        i = i + 1
    End If
Next f
```

# 公式ドキュメント
- Application.ExecuteExcel4Macroメソッド  
https://docs.microsoft.com/ja-jp/office/vba/api/excel.application.executeexcel4macro
- Scripting.FileSystemObjectオブジェクト  
https://docs.microsoft.com/ja-jp/office/vba/language/reference/user-interface-help/filesystemobject-object
[SAP][S/4HANA][Obsolete]パラメータ設定用トランザクションの確認方法(How To Check Transaction Code For Parameter Settings)

こんにちは。

:::note warn
こちらの記事ですが、S/4HANA1809環境で調査して作成したものです。S/4HANA2021環境にて、後述するテーブル：CUS_IMGACHのトランザクションコードが各パラメータ設定の **右クリック>技術情報照会** の画面に表示されるようになっています。よって、以降の記事は2023年現在では多くの導入環境で役に立たない記事になっていることが判明しました…:sob:
なお、これまでカスタマイズを行おうとなった場合は **トランザクション：SPRO > SAP完全版IMG** と操作してIMGツリーにたどり着いていましたが、こちらも **トランザクション：SIMG** を使用することで直接IMGツリーにたどり着けるようになっていることをS/4HANA2021環境にて確認しました。過去の常識がこうやって古い情報となっていくのだな、ということを痛感しています…:sweat_smile:
:::

デモ環境構築や各環境でのパラメータ設定で、

トランザクション：SPRO
→ SAP完全版IMG
→ ツリーをたどって実行

とするの、正直面倒くさいですよね。
今回はSPRO機能のトランザクションコードを確認する方法を3種類紹介します。
そのパラメータ設定の作業時間を減らすために役立てば何よりです。

注意：英語環境での画面ショットとなりますため、適時読み替えてください。

##まず最初に

パラメータ設定のトランザクションのうち、実行ボタンを押すと2種類に処理が分かれますよね。
当方で勝手に名前を付けてみました。

#####表1：パラメータ設定トランザクションの種類(※当方の勝手な分類)

|番号  |内容     |説明 |
|:---:|:-------------:|:-:|
|1|直実行系|専用トランザクションに直接遷移する(下記SM30系以外)|
|2|SM30系|SM30の一覧画面に遷移する|
|3|サブメニュー系|ポップアップ画面が表示され、複数の処理から次の処理を選ぶもの|

表のうち1番は、昔から「O(オー)」始まりのトランザクションであったり、SDの「V」始まりの
トランザクションとしてご存じの方も多いと思います。
2番は、SM30系のトランザクション(パラメータトランザクション)が設定されており一覧画面に直接遷移します。
3番は、組織設定やSDの価格決定表などで、ポップアップ画面にメニューが表示され、
上から順番に処理をしていくことが想定される機能に設定されているものです。
もちろん、これに分類しづらいものもありますので、目安程度に見てください。
それでは確認方法を記載していきます。

また、今回はサンプルとして、**企業構造＞定義＞販売管理＞登録、変更削除：販売組織** ※日本語あってるかな・・・
を使用します。

**※あくまで個人の経験や知識の寄せ集めですので、もっと良いやり方をご存じの方、ぜひ教えてください！**

##トランザクション確認方法1：技術情報照会

###操作方法
１．確認したい機能の行を右クリック→技術情報照会
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326392/c455d527-0ac4-ea94-e4b5-e2ef064ae735.png)

２．更新オブジェクトタブ「割り当て済み対象」の「Transaction」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326392/5e3e7459-a29b-3daa-ba31-c45bedef5242.png)

行が2行あるので、画面の実行ボタンをクリックすると表1-番号3のようにポップアップ画面が表示されるタイプであることがわかります。
実際の画面↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326392/e40d3f0b-a6f9-ba86-0c7c-795da3944232.png)

各行のトランザクションは、SM30とEC04となっています。EC04は「直実行系」でよさそうですが、
「SM30」だけのものはパラメータ値がここではわからないので、一覧画面への直接遷移は難しそうです。

##トランザクション確認方法2：IMGアクティビティの末尾4桁

###操作方法
１．SPROメニューバー＞追加情報＞追加情報＞キー照会＞IMGアクティビティ  ※画面ショット省略
２．一覧に表示されたIMGアクティビティの末尾4桁を確認する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326392/ad23ee47-8029-2031-a557-f2c058c5c8b2.png)

指定されている行のIMGアクティビティが「SIMG」で始まり、末尾4桁が「O」始まりなり、SDなら「V」始まりであれば、それがトランザクションコードである可能性が高いです(今回の「OVX5」はビンゴで、サブメニューのポップアップ画面に遷移します)。
これが4桁トランザクション時代から脈々と受け継がれているコードになると思います。
ただ画面にもありますが、「SIMG」で始まらないIMGアクティビティも多く、後ろ4桁とは異なるトランザクションが設定されているものも多くなり、この方法は使えない場合が増えてきました。

##トランザクション確認方法3：テーブル：CUS_IMGACHで確認する

###操作方法
１．IMGアクティビティの値をコピーする
２．テーブル：**CUS_IMGACH** でIMGアクティビティに設定されているトランザクションコードを検索する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326392/55a69dd7-9d2f-5c37-1489-34a1188f407b.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326392/ab81f8f5-ec27-b31c-4e9e-14d89d40c2fc.png)

この方法、十数年前に受けたSDアカデミーの中で教えてもらいました。
実際に、トランザクションコードの「S_ALR_87007523」を直接実行すると、サブメニューのポップアップ画面に遷移しました。
IMGアクティビティのみがキー項目ですので、「サブメニュー系」の機能の場合、ポップアップ画面に遷移するトランザクションコードが設定されているものと思います。

##最後に
上記の方法で、SPROメニュー系のトランザクション遷移の手間がかなり減ると思います。ぜひ試してみてください。
もっと簡単な方法でばっちり確認できる方法をご存じの方、ぜひ教えてください。

今回は以上です、ありがとうございました。
コンパイル時に確定している辞書は switch〜case が速い

コンパイル時に確定している辞書が必要な場面は割とたくさんある。

で。
どう書くのが速いのか知らなかったので調べてみた。

# 辞書を実現する方法

## switch〜case

愚直に `switch`〜`case` を書く。
`case xxx:return yyy;` を辞書の要素数の数だけ書く。

## std::vector

`std::vector<std::pair<int,int>>` に値を入れて、 `std::find_if` で検索。

## std::map

`std::map<int,int>` に値を入れて、`find` で検索

## std::unordered_map

`std::unordered_map<int,int>` に値を入れて、`find` で検索

## boost::container::flat_map

[頂いたコメント]( https://qiita.com/Nabetani/items/fa978a04b77509f24871#comment-a517f1106af4811577aa ) を受けて、追加。
`boost::container::flat_map<int,int>` に値を入れて `find` で検索

# やる前に予想

|要素数が少ない場合|要素数が多い場合|
|:--:|:--:|
|↑　速い　↑|↑　速い　↑|
|`switch`〜`case`|`switch`〜`case`|
|`vector`|`unordered_map`|
|`unordered_map`|`flat_map`|
|`flat_map`|`map`|
|`map`|`vector` |
|↓　遅い　↓|↓　遅い　↓|

# 実験

## 内容

* 要素数は3, 10, 30, 100, 300 を試した。それ以上だと **コンパイルが** 遅くてつらかったのでやめ。( 3〜300 だと、clang++ で 50秒以上。g++-9 で90秒以上 )
* 「辞書を引く動作を 9万回行う」を 7回行い、処理時間の中央値を抽出。
* 辞書に入れる値は、 key も value も $0 〜 2^{30}-1$ の一様乱数。
* 動作環境は、macOS Catalina / Darwin Kernel Version 19.2.0。
* コンパイラは Apple clang version 11.0.0 (clang-1100.0.33.17) と g++-9 (Homebrew GCC 9.2.0_3) 9.2.0。
* コンパイラオプションは `-std=c++17 -Wall -O2 -march=native`


## 結果のグラフ

y軸が処理時間。対数目盛注意。
x軸は辞書の要素数。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6854/f7dfb83e-cde0-a120-4937-62b9a6c19b88.png)

## 実行結果のまとめ

* `switch`〜`case` が常に最速。特に gcc の場合はめちゃくちゃ速い。
* gcc と clang でだいぶ傾向が異なる。
* clang だと、意外と `unordered_map` が遅い。300要素ぐらいなら `std::map` がよいのか。
* gcc でも意外と `unorderd_map` が遅い。遅いんだけど、要素数が少ないと速い。意外。とはいえきっと、1万要素とかなら  `unorderd_map` が速いんだろうなぁと思う。
* gcc だと、常に `vector` が遅い。 `find_if` がよくなかったかな。
* `flat_map` は `std::map` より速いかと思ったらそうでもない。

# というわけで

というわけで、 `switch`〜`case` を使うのが一番速そう。特に gcc の場合に差が顕著。
アセンブラは見てないんだけど、何してるんだろうね。