OmniAICreator/Qiita-1.07M huggingface dataset:
aws perspectiveを使って構成図を作成してみる

# はじめに

私の所属している会社では環境が複雑なので、手作業での構成図作成はかなりの時間と工数が発生します。
もう発表されてから3ヶ月程経過していますが、
公式ドキュメントとクラスメソッドさんの記事を参考に自分自身もやってみたという記事です。

# やってみる

## 参考手順

[公式ドキュメント]
(https://docs.aws.amazon.com/ja_jp/solutions/latest/aws-perspective/automated-deployment.html)

[classmethod]
(https://dev.classmethod.jp/articles/gettingstart-aws-perspective/)


## Cloudformationを使用してPerspective作成

[AWS Perspectiveのページ](https://aws.amazon.com/jp/solutions/implementations/aws-perspective/)から「AWSコンソールで起動する」をクリックするとAWS Perspectiveを展開するCloudFormationスタック作成画面に進みます。

![https___qiita-image-store.s3.ap-northeast-1.amazonaws.com_0_569912_eca10d56-eba2-31ea-c08e-3889206b7c76.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626780/490c48ae-d78b-8285-298f-ada93a9cbf93.jpeg)

## AWS Perspectiveスタックの作成

「AWSコンソールで起動する」をクリックして、各種パラメータ設定や以下承認のチェックを行い、スタック作成を行います。

パラメータ入力は基本的にデフォルトでOKですが、メールアドレスはメールが届くアドレスを入力してください。

●設定項目の内容についての詳細

| 設定項目 | 設定値 | 説明 |
| --- | --- | --- |
| AdminUserEmailAddress | ご自身のメールアドレス | メールアドレス宛にWebサイトの仮パスワードが送信されます。 |
| AlreadyHaveConfigSetup | Yes or No | 前述した AWS Config の設定が完了していれば Yes。 |
| CreateElasticsearchServiceRole | Yes or No | 前述した IAM ロール「AWSServiceRoleForAmazonElasticsearchService」が存在していれば No。<br>2020/10/02修正 「存在していればYes」となっていましたが正しくは No でした。ご迷惑をおかけしました。 |
| CreateNeptuneReplica | Yes or No | Neptune のレプリカを行うか？ ほとんどの場合は不要だと想います。 |
| NeptuneInstanceClass | インスタンスクラスの選択 | アーキテクチャー図描画に必要なデータを保管する Netptune のサイズ。こだわりがなければデフォルトのまま。 |
| OptOutOfSendingAnonymousUsageMetrics | No | 匿名のメトリクスを AWS Perspective へ送信するかしないか。フィードバックだと思われます。 |


## 初期認証
「Welcome to AWS Perspective」という件名のメールが届きます。
そこには仮のログインパスワードが記載されています。

ネストされたスタックの一つに「aws-perspective-nnnnnnnnnnnn-ap-northeast-1-CloudFrontDistribution-xxxxxxxxxxxxx」というスタックがあり、この出力に CloudFront の URL が表示されます。この URL をクリックします。

ログイン画面が表示されます。メールに記載されている ID とパスワードでログインします。

![2020-09-23_10h24_51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626780/8b157511-b990-b67e-1aaa-6960a89a9d06.png)


ログイン後はすぐに新しいパスワードを求められます。
英数記号を含めたパスワードを入力します。

verification code がメールで届きます。
確認しメールに記載のコードを入力します。

![2020-09-23_10h26_49 (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626780/9d793499-db98-e04b-f6ba-b8e864a257d6.png)

初期設定が終わるとインポートが始まります。インポート完了までに10分程度かかります。(リソース数によって異なります)

![スクリーンショット 2020-12-13 11.56.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626780/faa8ee8a-9a50-7d78-f2af-0b38405518d4.png)

インポート後、左メニューにリソースが表示されました！！！
ここのリソースを選択すると右側キャンバスにアーキテクチャー図が表示されます。

# 所感

最後のここまでやってみての所感を述べます

自動化の中では割と軽快に動いてくれると思いますが、
まだ自分の中では実用の範囲外と感じました。
udemyの手を動かしてAI開発入門：RPAとAI

#udemyの手を動かしてAI開発入門:セクション７
やはり１２月となれば、いろいろと家庭のこともやることが多くなり、学習の時間をとることができない。今日は久しぶりに進んでなかった、手を動かしてAI開発入門:セクション７を実施したい。
***
まず、RPAであるuipathのインストールが教材の通りやってもうまくいかない。
何度かインストールしたことがあり、それも悪さをしたのか。
ならばと、使っていないメールアドレスで新規登録から実施。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282938/393ded39-691d-6059-dc7a-4ad057bddcda.png)
画面上のトライアルの開始をクリック。
なぜかクロームだと上手く動かず、Edgeで開けなおす。
教材だと、次の画面でcomunity editionがダウンロードする画面が開くらしいのだが
そうならずアカウントを申請する画面が開くので、そこでメールアカウントで新規作成し
uipath automation cloudにつながったのち、uipathuipath studioをダウンロードする。
でなんとか、uipathが使えるようになった。
***
###クロームでuipathが動くようにする
どうやらuipsthはそのままではクロームでは動かないとのこと。
uipath　studioのツールから以下を実施。
![SharedScreenshot.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282938/bbc73848-d9b1-b545-d9ab-f2cab12886d0.jpeg)
***
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282938/0c4ed490-b4ca-41f7-2efd-02bf66b38a8c.png)

そうするとクロームの拡張機能の部分にuipathが出てきた。
***
###ブラウザーをそうさするアクティビティの作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282938/00c15ba7-4645-6957-d0ae-fbc9cf6f3124.png)
***
ワトソンの画面をあけて
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282938/4f73cfc9-312e-518e-1b5e-c03044d3fb31.png)
で、uipathのブラウザヲ開くを選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282938/17d1caa7-ce0d-a27a-4433-25f2bfd5df7e.png)
***
次に画面のプルダウンメニューヲ選ぶ場合は、要素の項目を選択を選ぶ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282938/3b1a8856-98a0-dd40-d186-62f797eb5ff6.png)
***
で画面にてきすとを入力する場合はテキストヲ設定を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282938/67d53bd8-2e88-b629-4f84-ba9445b76865.png)
***
最後にくりっくする場合はクリックボタンヲ選択
***
するとひととおり動いた！
と思ったが、なぜか最後のくりっくだけ動かない。
やはり、いろいろと難しい。

***
##次はAIのAPIからuipathから直接呼び出す
これを覚えるとAIの画像認識の結果をどこかのシステムに書き込んだりだきるらしい・・。
***
途中で飛ばした章があったのでもどる。
NanonetsというAIサービスにつなぐ。
で、つくったモデルを表示し統合するをえらぶ。で、シェルで表示した画面が以下。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282938/f23d93e7-55f7-4983-248a-a5935bbb22c2.png)
AWSのcloud9でWordPressの開発環境をようやく作ることができました

先日久しぶりにcloud９でWordPressの開発環境を作ろうとしたら、サーバーのエラーが出てしまい作ることができませんでした。
今回下記のサイトで回答を頂きまして、無事に開発環境を作ることができました。

[cloud9でWordPressのプレビューができない](https://teratail.com/questions/308472#reply-432196)

私は、デフォルトのままAmazon LinuxでEC2インスタンスを作りました。
でも、PHPのバージョンが古いので、アップデートが必要です。

こちらの記事を参考に、PHPのバージョンを7.3に上げました。
[AWS Cloud9（Amazon Linux）にPHP7.3をインストールして開発環境を作る手順書](https://qiita.com/gomiryo/items/28c07d5ee9afd1c325b0)
CSS :not()をレスポンシブ適用時に使ってみた

## はじめに

タイトルについて記事にしました。
この記事で得る内容は以下の通りです。

・ CSSの基礎知識が増える
・ CSS擬似クラス :not()について

以下参考
[CSS の :not() の使いかた](https://qiita.com/noraworld/items/74ab6d7f6ace6e7ec3c4)
[[CSS]否定疑似クラス「:not」の便利な使い方と使う時の注意点](https://coliss.com/articles/build-websites/operation/css/css-not-and-specificity.html)

## CSS :not()とは

CSSの否定擬似クラスで、指定した要素以外にスタイルを適用する

## 例

![スクリーンショット 2020-12-13 10.42.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/772631/a359bee6-dea4-eab5-391f-d481d9c53976.png)

コンテンツを画像の様な並びにしたくて、`FlexBox`で並び順を変えようと試みましたが調整できず
`container-profile-right.responsive`というクラスを新しく作って、普段は`display: none;`で
隠してスマホサイトで表示するイメージです

```haml:index.haml
.container-profile#ABOUT
  .container-profile__right.responsive ← スマホで表示
    %p.top About Me
    .header-line
  .container-profile__left
  .container-profile__right ← :not(.responsive)を当てて
    %p.top About Me ← ここと
    .header-line ← ここを隠す
    %p hoge
    %p.bottom 199X年生まれ 世紀末生まれ
```

```scss:index.scss
@media screen and (max-width: 768px) {
// 中略
  .container-profile {
    padding: 2rem;
    display: flex;
    flex-direction: column;
    &__right.responsive {
      display: block;
      p.top {
        font-size: 3rem;
      }
      .header-line {
        width: 20%;
        margin: 2rem auto 3rem;
      }
    }
    &__right:not(.responsive) { // &__rightの.responsiveを除きスタイルを適用する
      text-align: center;
      font-size: 2rem;
      padding: 3rem 0;
      line-height: 55px;
      p.bottom {
        padding-bottom: 2rem;
      }
      p.top,
      .header-line {
        display: none;
      }
    }
  }
}
```

クラス名を変えるなりすれば簡単でしょうが、`:not()`をあえて使ってみました
Transformer:  Scaled Dot-Product Attentionメモ

#1 Scaled Dot-Product Attention

Scaled Dot-Production AttentionのAttention関数は、Query、Key、Valueを入力とする以下の関数である。
![sdpa form.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102001/0530d5cd-8020-74ea-308b-7558e7178de2.png)

図で示すと以下のようになる。
![sdpa fig.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102001/f80d574c-300a-1185-dacc-25bbf1ccbd7a.png)

#2 コード

Tensorflowチュートリアルに記載のあるScaled Dot-Product Attentionメソッドの実装は以下。

```
import tensorflow as tf

#############################################
#
# Scaled Dot Product Attention
#   Attention(Q, K, V) = softmax( Q*K.T / sqrt(d)) * V
#
def scaled_dot_product_attention(q, k, v):
 	# Q * K.T
	matmul_qk = tf.matmul(q, k, transpose_b=True)

	# Q*K.T / sqrt(d)
	dk = tf.cast(tf.shape(k)[-1], tf.float32)
	scaled_attention_logits = matmul_qk / tf.math.sqrt(dk)

	# softmax( Q*K.T / sqrt(d) )
	attention_weights = tf.nn.softmax(scaled_attention_logits, axis=-1)

	# softmax( Q*K.T / sqrt(d) ) * V
	output = tf.matmul(attention_weights, v)

	return output, attention_weights

```

QとKの転置の内積を計算

```
matmul_qk = tf.matmul(q, k, transpose_b=True)
```
QとKの転置の内積をルートdkで割る

```
scaled_attention_logits = matmul_qk / tf.math.sqrt(dk)
```
softmaxを計算

```
attention_weights = tf.nn.softmax(scaled_attention_logits, axis=-1)
```
softmaxの結果とVの内積を計算

```
output = tf.matmul(attention_weights, v)
```

図中のMask(opt.)はオプションのため省略している。


##2.2 テストコード

K, V, Qの値を指定して、scaled_dot_product_attentionメソッドを呼び出すコード。

```
#############################################
#
# Test "Scaled Dot Product Attention" method
#
k = tf.constant([[10, 0, 0],
				 [ 0,10, 0],
				 [ 0, 0,10],
				 [ 0, 0,10]], dtype=tf.float32)

v = tf.constant([[    1, 0],
				 [   10, 0],
				 [  100, 5],
				 [ 1000, 6]], dtype=tf.float32)

q = tf.constant([[0, 10, 0]], dtype=tf.float32)

print('---input---')
print(k)
print(v)
print(q)

result, attention_w = scaled_dot_product_attention(q,k,v)

print('---result---')
print(attention_w)
print(result)
```

k、v、qを入力して、scaled_dot_product_attentionメソッドを呼び出し、出力結果(result)を表示する。

#3 実行
テストコードを実行すると以下のような結果となる。
![attention result.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102001/fb43c2dd-5c96-e7d5-8241-6c1ee780073b.png)
(1.00000e+01 9.276602e-25)が出力結果である。

#4 環境

||Version|
|:---|:---|
|Python|3.7.4|
|Tensorflow|2.3.1|

#5 参考

||URL|
|:---|:---|
|Transformer論文|https://arxiv.org/abs/1706.03762|
|Tensorflowチュートリアル|https://www.tensorflow.org/tutorials/text/transformer|
Windows Server に初期設定しておくとよいこと

## はじめに

Windows Server を構築した際にとりあえず設定しておくことです。


## パフォーマンス優先の設定にする

### 手順

1. 「ファイル名を指定して実行」で「sysdm.cpl」と入力して「OK」をクリックする。
2. 「システムプロパティ」画面の「詳細」タブを選択する。
3. 「詳細」タブの「パフォーマンス」の「設定」をクリックする。
4. 「視覚効果」タブの「パフォーマンスを優先する」を選択する。
5. 「詳細設定」タブの「次を最適なパフォーマンスに調整」の「バックグランドサービス」を選択する。「OK」ボタンをクリックする。


## ＰＣの用途が分かる壁紙に変更する

### 目的

「本番AP01」「検証DB01」のような壁紙を設定して現在作業しているＰＣを明確にするで、検証機で作業しているつもりが本番機で作業していたといったリスクを減らします。
ポリシーを使用することで、全てのユーザーに対してデフォルトの壁紙として設定することができます。

### 手順

1. PCの用途やサーバー名を示す壁紙用の画像ファイルを作成する。（ex. 本番AP01、サーバー名 など）
2. 壁紙を設定するＰＣの共通フォルダに画像ファイルを保存する。（ex. C:\Users\Public\Pictures\wallpaler.png）
以下は、意外と考慮漏れになる致命的な実装です。
3. 「ファイル名を指定して実行」で「gpedit.msc」と入力して「OK」をクリックする。
4. 「ローカル コンピューター ポリシー」で 「ユーザーの構成」→「管理用テンプレート」→「デスクトップ」の順に展開し、「アクティブ デスクトップ」をクリックする。
5. 「アクティブ デスクトップの壁紙」をダブルクリックする。
6. 「設定」タブ」「有効」をクリックし、使用するデスクトップの壁紙へのパスを入力し、「OK」をクリックする。


## サインアウト.bat をデスクトップに用意する

### 目的

デスクトップに「サインアウト.bat」を用意して、サインアウトの操作を簡単にすることで、誤操作によるシャットダウンと未サインアウトによるメモリの浪費を防ぎます。
パブリックユーザのデスクトップに「サインアウト.bat」を格納することで、全てのユーザーにデスクトップに「サインアウト.bat」を配置することできます。

### 手順

1. 後述の「サインアウト.bat」を用意する。
2. 「C:\Users\Public\Desktop」に「サインアウト.bat」を格納する。

```bat:サインアウト.bat
logoff
```


## おわりに

ちょっとしたことで、効果があるものは積極的に設定しておきたいですね。
他にあればぜひコメントください。
ABC183C - Kotlinで順列を生成するスニペットと動作解説

# 要約
C++ や Python で順列の前列挙をしたい場合は next_permutation を使うと便利ですが、Kotlin にはそれがありません。
本記事では、Kotlin で順列を生成するコードスニペットの紹介と、動作解説をします。
Kotlinの基本的な文法は分かるけど、再帰を自分で１から書くのは難しいと感じるAtCoder緑前後までの競プロer (私です) を対象としています。


## 例題
[ABC183 C - Travel](https://atcoder.jp/contests/abc183/tasks/abc183_c)
入力：N(2~8)頂点と、各頂点間の距離、正整数K
出力：頂点1で始まり頂点1で終わる各頂点をちょうど1度ずつ訪問するパスのうち、長さがKとなるパスの数

## 回答方針
1. パスの頂点1以外の頂点の並び順を全通り生成（制約が`N<=8`なので`8!=40320`通りを全列挙しても問題ない）
1. それぞれのパスの長さがKかチェックする

2については、順列の列挙ができればあとは足し算を行うのみなので、本記事では割愛します。

## 順列生成
C++ や Python で順列の前列挙をしたい場合は next_permutation を使うと便利ですが、Kotlin にはそれがありません。
例えば`[1, 2, 3]`という要素を持つリストから、`[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]`という順列のセットを生成するにはどうすれば良いでしょうか。
Kotlin では、下記のコードにより、任意のリストから順列を生成できます。

```kotlin:Permutation.Kt
fun <T> generatePermutations(source: List<T>): Set<List<T>> {
    val permutations = mutableSetOf<List<T>>()
    fun permutation(source: List<T>, perm: List<T>) {
        if (source.size <= 1) {
            permutations += perm + source
        } else {
            repeat(source.size) {
                permutation(source.take(it) + source.drop(it + 1), perm + source[it])
            }
        }
    }
    permutation(source, emptyList())
    return permutations
}
```

以下、簡単に動作の解説をします。

- permutation() は再起関数になっています。
- permutation() の引数 source は残りの順列化する要素のリスト、perm は現在までに確定している順列を保持しておく変数です。
- 1回の permutation() が果たす役割は、「sourceから1要素を選んでpermの末尾に追加 (とsourceから削除) し次の再帰に突入」をsourceの全要素に対して行うこと、となります。
- sourceの要素が1要素になると、それを末尾につなげて一つの順列が完成するので、返却用のmutableSetに登録します。
- 初期状態は、generatePermutationsに渡されたsourceで、構築途中の順列はないので空のリストを渡して、順列を作成します。

自分の提出
[提出 #18704381 - AtCoder Beginner Contest 183](https://atcoder.jp/contests/abc183/submissions/18704381)

本記事は以上になります。
間違いや改善点などありましたらご指摘よろしくお願いします。
正規表現早見ページ(JavaScript)の紹介

　正規表現はそれほど頻繁に使う機会はありませんが、使ってみれば非常に便利なものです。しかし、たまに使う程度では使用方法を思い出すだけでも大変で、敬遠しがちになってしまいます。そこで、できるだけ狭いスペースで、多くの情報が即座に手軽に引き出せるように、**正規表現早見ページ**を作ってみました。

http://tsubolabo.on.coocan.jp/html/RegExpQR01.html

　**画面１**はページ内の一部を示しています。できるだけ広い領域を詳しく分かり易く記述し、目的の項目に手間をかけずにジャンプできるように配慮しています。

**画面１**
![Qiita_post02_01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/932484/f2a52975-3bad-1eef-c6cd-ed92d49fb182.jpeg)


　また、右上の「使ってみる」ボタンをクリックすると、**画面２**のような小窓が表示されます。上の欄に入力された原稿と正規表現を使って検索が実行され、どの文字がどのようにヒットするのかが、下の欄で一目で分かるようになっています。

**画面２**
![Qiita_post02_02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/932484/110f6318-ef25-8874-e659-f3b1b635dd64.jpeg)

　ブラウザによっては一部に非対応の項目があるため、「非対応ブラウザ」の名前を明記してあります。しかし、ここに書いている「Edge」は旧legacy版のことを指しています。この春に強制アップデートされたchrome版のことではありません。新しいEdgeでは非対応項目がChrome並みに少なくなっていると思われますが、まだ詳細なチェックはできておりません。
pythonで数値テキストからwavファイル生成

# 1. はじめに
テキスト出力した44kSa/s 音声データをwavファイルにするpythonスクリプトです．

# 2. 概要
numpyとwaveモジュールを使います．
テキストの数値データをnumpyのloadtxtで読み込み，waveのWave_writeでファイル出力します．
途中，DCオフセット除去や正規化とクリッピング処理をし，符号付き16bit整数にしています．

# 3. スクリプト
正規化は最大値で行っています．RMSで行った方が音量は大きくなりますが，クリッピングで歪むのを避けるためです．実行時に引数を使っているのでimport sysしています．

<details><summary>txt2wav44k.py</summary><div>

```python
import wave
import numpy as np
import sys

#usage:
#python3 txt2wav44k.py dat01.txt

aryArg = sys.argv
if len(aryArg) > 1:
	fnamel = aryArg[1]
else:
	fnamel ='dat00.txt'

fnames= fnamel[0:-3]+'wav'
fs=44100

strmOrg=np.loadtxt(fnamel)
N=len(strmOrg)
timlen=N/fs #sec

factScl = 0.90
strmOrg = strmOrg - np.mean(strmOrg)
myRms = np.sqrt(np.mean(strmOrg*strmOrg))
myMax = np.max(np.abs(strmOrg))


#streamNrm = strmOrg / myRms * factScl
streamNrm = strmOrg / myMax * factScl

streamPeakSup = np.where( streamNrm < 1.0 , streamNrm , 1.0)
streamPeakSup = np.where( streamPeakSup > -1.0 , streamPeakSup , -1.0)
streamOut = streamPeakSup

scaleFixedPoint = 32767
stream= np.int16(streamOut * scaleFixedPoint)

objw = wave.Wave_write(fnames)
objw.setnchannels(1)
objw.setsampwidth(2)
objw.setframerate(fs)
objw.writeframes(stream)
objw.close()

#from playsound import playsound
#playsound(fnames)

```
MathJax早見ページの紹介

　MathJaxを使えば、Web上で綺麗な数式を表示できて便利ですが、たまに利用するだけでは記法を思い出すのに苦労します。そこで、できるだけ狭いスペースで、多くの情報が即座に手軽に引き出せるように、**MathJax早見ページ**を作ってみました。

http://tsubolabo.on.coocan.jp/html/MathJaxQR01.html

　TeX文字を多量に詰め込んでいるため、ページの立ち上がりにはやや時間を要しますが、立ち上がってしまえば、あとはサクサクと反応すると思います。

　**画面１**に示すように、目的のTeX文字の上を左クリックすれば、その文字がハイライト表示され、左下に小窓が現れてTeX記法が直ちに表示されます。右クリックによるMathJax特有の表示方法よりも操作ステップ数が少なく迅速です。

**画面１**
![Qiita_post01_01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/932484/6f0ca599-6487-a350-a88d-6e54b6b92fd7.jpeg)

　また、右上の「使ってみる」ボタンをクリックすると、左上に**画面２**のような小窓が現れ、上の欄に自由に入力したTeX記法が、TeX文字に変換されて下の欄に表示されます。

**画面２**
![Qiita_post01_02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/932484/8578175b-b8d2-3f66-249f-978c7eefc39b.jpeg)

　なお、現在、MathJaxの最新バージョンはV3ですが、このページはまだV2で動作しています。しかし、「導入」や「突出部無視」・「追加変換」を除けば、基本動作は殆ど変わりません。このベージに最新バージョンをまだ適用していないのは、V2で使用できた裏技の一部がV3では使用できなくなったため、対話形式の動作の一部を移植しにくい状況にあるためです。そのうちに移植するつもりです。
【Mac】自分の好きなキーボードを使うために接続中のみ内蔵キーボードを無効化する方法

[生産性向上のための環境整備2020 - 03 【PR】 Lenovo Advent Calendar 2020](https://qiita.com/advent-calendar/2020/lenovo_env_03)の12/13の記事です。

## 好きなキーボードを使いたい！！
これが本記事のテーマです。
リモートワークが増える昨今、オフィスなら気にならなかったのですが、

- 家の作業スペースが狭い！！
- キーボードをMacの外に置く余裕が無い！！

**狭い環境の中**で自分の好きなキーボードを使うための**「生産性を向上する話」**をしていきたいと思います。

## 現環境の共有

外付けキーボードをこのように置いているとトラックパッドが使えなくて**マウス**が必要になります。**当然マウスをおくスペースも無い**のです。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328771/2db51bc9-d21d-6059-1499-65d93d478d2d.png" width=350 />


キーボードの上にキーボードを置きたい！！しかし下のキーボードが反応して作業にならない。当然ですよね。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328771/e54ccebb-8488-4847-a077-0f5cb1250cb0.png" width=350 />

## やりたい事

外付けキーボードが接続されている時は**内蔵キーボードを無効化**したい！！！

[Karabiner-Elements](https://karabiner-elements.pqrs.org/)というフリーウェアを使用させてもらって解決しました。


## インストール方法

[公式サイト](https://karabiner-elements.pqrs.org/)からインストーラをダウンロード。

僕の環境がmacOS Catalina 10.15.17なので執筆時点で最新のv13.1.0を使用します。
 <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328771/4f0f22b2-8592-82e6-a519-1a65c983a8cf.png" width=550 />




## パーミッションの設定

インストールが完了したら、パーミッションの設定をいます。

`システム環境設定 > セキュリティとプライバシー > プライバシー > 入力監視`から以下2点にチェックを入れます。


- karabiner_grabber
- karabiner_observer

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328771/305fd6df-f4b5-2caf-bd74-446a753afc5d.png" width=550 />


**※初回インストール時にはkarabiner_observerしか存在しない場合があります。その際は再度インストーラーから再インストールを実行することでkarabiner_grabberが登場しました。**


## Karabiner-Elements起動

Karabiner-Elements初回起動時、ドライバーのアラートが表示されました。指示に従っていきます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328771/d9807640-4957-f5dc-4003-1b69e4e4ae09.png" width=550 />



以下を許可。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328771/7d578169-e4a4-b726-2a5c-236d4f16f716.png" width=550 />


許可をするとキーボード設定アシスタントから外付けキーボードの認識作業が入ります。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328771/6fc32455-c4d9-ce79-0df7-c1cfa7fd6d7a.png" width=550 />


指示にしたがって外付けキーボードを認識させます。




## 内蔵キーボードの無効化成功

Karabiner-Elementsを起動します(Karabiner-Elements.appを実行)。

`Devices > Advanced`から、下のキャプチャのように無効化したいキーボードを選びます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328771/85f50cb6-25cf-df8c-76ca-f03afa5eccab.png" width=550 />


外付けキーボードが接続されていない時のみ、内蔵キーボードが無効化するようになりました。

これで**狭い空間**で**好きなキーボード**を使うことが出来るようになりました！！超快適。

## 最後に

2020年アドベントカレンダーもそろそろ後半戦。他にもアドベントカレンダーを書いていますので、こちらもどうぞ。

- [【Unity】新規ゲームのUI開発で気をつけた39のTips前編 - Qiita](https://qiita.com/ohbashunsuke/items/0570234362e2e45c0011)
- [【Unity】シーン、Prefab内に含む任意の文字列を検索するSearchStringInAssetsを作りました - Qiita](https://qiita.com/ohbashunsuke/items/0ba8ab2d3253f5617a0e)


明日は[TomoyukiSugiyama](https://qiita.com/TomoyukiSugiyama)さんの番です。
G’sアカデミーへの入学を検討している人に現役生から伝えたい3つのこと



# はじめに
こちらは　[G's Academyアドベントカレンダー2020](https://qiita.com/advent-calendar/2020/gsacademy)　の13日目の記事です。

今回がQiita初投稿です。
今まで見るだけだったのですが、せっかくの機会なので書いてみようと思い、簡単ではありますが、今回投稿しました。

これからG'sアカデミーを検討しようと思っている人に向けて、少しでも参考になればと思います。
※2020年12月現在の内容です。


#書いている人
普段はサラリーマンしている、G’sアカデミーDEV18期現役生です。
G's入学前に、HTML、CSS、JavaScriptを勉強していましたので、全くの初心者ではありません。

#誰に向けた内容か？
これからG'sアカデミーのDEVコースを検討しようとしている人、検討している人。


#伝えたい3つのこと

この2ヶ月間通ってみて思った、個人の率直な感想です。
特に、この3つが強く感じたことになります。

###その１：プログラミングを教わりたいと思う人には不向き
過去にプログラミングスクールに通ったことはないので、他を知っているわけではないですが、
G'sアカデミーでは、1〜10まで丁寧に教えてもらうスタイルではありません。

1〜3ぐらいを授業で教わって、4〜10まではトライアンドエラーを自分で行うって感じでしょうか。
そのため、全部教えてもらわないと自分はできないという人には合わないと思います。

サポート体制がないのか？というとそうではなく、
講師以外に、過去の卒業生がチューターとして参加し、サポートをしていただけます。
わからないことがあれば、親身になって説明してもらえますし、チューターもわからないことは一生懸命調べてくれます。

そのため、

* 自走できる人
* 自己発信できる人
* トライアンドエラーできる人
* 自ら質問することに躊躇いがない人

といったところが必要かなと思います。



###その２：課題の提出が（ほぼ）毎週あり、ハードである。
授業で習った内容を踏まえて、翌週の授業までに課題作成があります。
ランディングページやじゃんけんアプリの作成、APIの利用などです。

授業　→　課題作成　→　課題提出　→　チューターからのFB

が1週間の流れです。

DEVコースは、社会人が多いので、課題に時間が取れないという人もいます。
事前に報告すれば遅れて提出することができますが、課題に対するチューターからのFBはもらえません。

たとえば、社会人の方で、課題に取り組む時間を1日3時間確保できるとしたら、3時間×5日で約15時間でしょうか。
仕事が忙しく、通勤にも時間がかかる人で、なんとか1日1時間を確保できたとしたら、1時間×5日で5時間ぐらいしかありません。
これぐらいの時間の中で、課題を毎週こなす必要があります。

そして、この課題の提出は、後期授業に参加するための一つの要素になりますので、避けては通れないものになります。

G'sアカデミーで初めてプログラミングやりますという人であれば、

そもそもなぜそれが動くのか？
なぜ動かないのか？
やりたいことを実現するためにはどうすればいいのか？
どのように調べればいいのか？

と詰まる要素がたくさんあります。それだけで時間が過ぎ去っていくこともあります。

この課題提出が、初心者には非常にハードだと思います。

###その３：オンライン参加のみだとG'sの良さが半減

こんなご時世なので、オフライン、オンラインのどちらかで授業を受けることができます。
授業に参加できなかったとしても、授業を録画したものを後から見ることは可能です。

授業の観点だけであれば問題はないのですが、G'sのメリットは、ただプログラミングを勉強するだけでなく、仲間に出会うという面もあります。

20代〜50代の色々な経験・キャリアを持つ人たちが集まります。

オフラインであれば、授業前や授業中、授業後に同期とコミュニケーションを取ることができますが、オンラインだとそれが難しい印象です。

もちろん、オンラインで参加すると移動時間をカットできるので、その時間を別のことに充てることができます。
また、家庭の事情などでオンラインの参加になることもあると思います。

オンライン参加を否定するものではありません。

ただ、せっかく出会うことができた同期と、もしかしたらこの先、仕事のパートナーになるかもしれない人たちとコミュニケーションが取りやすいのはオフラインのメリットだと思います。
オフラインでコミュニケーションを取ったからこそ、オンラインでのコミュニケーションが活きると思います。

そのため、オンラインだけの参加となるとG'sの良さが半減すると思います。
ですので、何度かはオフライン参加できると良いと思います。

#最後に

今回は3つに絞って書いてみました。
なお、最初に述べたように、あくまで個人の感想です。
他の同期の人たちや、卒業生の人たちと意見が違うこともあると思います。
他の方も、発信しているので、色々な意見に触れていただければと思います。

本記事がG'sを検討している人にとって、少しでも参考になれば幸いです。
UbuntuにてIntellijへPlantUMLインストール

# 環境
| OS | Version |
|:-:|:-:|
| Ubuntu  | 20.04 LTS  |

# Plugin 
Intellijにて、PluginsのMarketplaceからPlantUML-integrationをインストール

## 公式
https://plugins.jetbrains.com/plugin/7017-plantuml-integration

# シーケンス図、アクティビティ図以外も作りたい場合、Graphvizをインストール
## Graphvizをインストール

```sh
apt install -y --no-install-recommends graphviz graphviz-dev
```

## Intellij->OtherSettings->Graphviz dot executableに「/usr/bin/dot」を設定

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87538/eb2cd292-22ee-4d54-e155-8a07efd0a2e9.png)

### 動作例（ステート図）
```plaintext
@startuml

[*] --> State1
State1 --> [*]
State1 : this is a string
State1 : this is another string

State1 -> State2
State2 --> [*]

@enduml
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87538/e9c9d6dd-c255-272f-adb2-c3493a03027f.png)
PAY.JPのAPIを用いたクレジット決済機能を実装（環境変数編）

##環境変数をシェルに設定
開発環境における鍵情報はシェルに保存し、環境変数として呼び出すようにします。

```ruby:ターミナル
# iを押してインサートモードに移行し、下記を追記する。既存の記述は消去しない。
export PAYJP_SECRET_KEY='sk_test_************'
export PAYJP_PUBLIC_KEY='pk_test_************'
# 編集が終わったらescキーを押してから:wqと入力して保存して終了
```
記述ができたら、以下のコマンドを実行して設定を反映させます

```ruby:ターミナル
# 編集した.zshrcを読み込み直して、追加した環境変数を使えるようにする
% source ~/.zshrc
```
確認のため、rails cを行います。

```ruby:ターミナル
[1]pry(main)> ENV["PAYJP_SECRET_KEY"]
=>"sk_test_************"

[2]pry(main)> ENV["PAYJP_PUBLIC_KEY"]
=>"pk_test_************"
```

##サーバーサイドで環境変数を読み込めるようにする

```ruby:app/controllers/orders_controller.rb
#省略
def pay_item
   Payjp.api_key = ENV["PAYJP_SECRET_KEY"]
   Payjp::Charge.create(
     amount: order_params[:price],
     card: order_params[:token],
     currency:'jpy'
   )
end
```
##JavaScriptで環境変数を呼び込みます

```ruby:ターミナル
% touch config/initializers/webpacker.rb
```
```ruby:config/initializers/webpacker.rb
Webpacker::Compiler.env["PAYJP_PUBLIC_KEY"] = ENV["PAYJP_PUBLIC_KEY"]
```
```js:app/javascript/card.js
const pay = () => {
 Payjp.setPublicKey(process.env.PAYJP_PUBLIC_KEY);
  // 省略
```
##本番環境に環境変数を設定する

```ruby:ターミナル
% heroku config:set PAYJP_SECRET_KEY='sk_test_*************'
```
```ruby:ターミナル
% heroku config:set PAYJP_PUBLIC_KEY='pk_test_*************'
```
##Herokuへプッシュ

```ruby:ターミナル
% git push heroku master
```
※環境変数が更新されない場合の対処法
###ファイルの変更履歴が存在する場合の対処法
ファイルの変更履歴が存在する場合、つまり、Herokuにプッシュしたときから少しでもファイルに差分が存在する場合を考えます。この場合は通常通りコミットして、そのコミットをHerokuにプッシュすれば問題ありません。

###コミットを行う

```ruby:ターミナル
% git add .
% git commit -m "後から見てわかりやすいコミット名"
```
```ruby:ターミナル
% git push heroku master
```
※ファイルの変更履歴が存在しない場合の対処法
続いて、ファイルの変更履歴が存在しない場合、つまり、特に変更するファイルもないがHerokuに設定した環境変数だけ本番環境に反映させたい場合
Herokuの仕様上、最新のコミット履歴が存在しない状態でgit push heroku masterコマンドを実行しても下記のように「Everything up-to-date（すでに最新の状態に更新されています）」と表示されます。

###空のコミットを生成
```ruby:ターミナル
% git commit --allow-empty -m "空のcommit" 
GitHub Desktopで空のコミット履歴が確認できれば成功です。
新しくコミットを生成することができたので、これで問題なくHerokuへプッシュすることができます。
```
###git push heroku masterを実行
```ruby:ターミナル
% git push heroku master
```
以上備忘録でした。
【Xcode】Info.plistのValue欄が狭い問題 (解決)

Xcode Version 12.2
いつの間にか、Info.plistのValue欄が狭くなっていました。
![スクリーンショット 2020-12-13 10.19.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/948735/2459fe92-5eb5-645d-b105-33d133db0eae.png)

普通はラベル横の｜から広げられるものですが、なぜかポインタが広げるものに変わらず。
Keyの幅は問題なく変えられるので、操作自体に問題があるわけではなさそうです。

各項目のValue値をダブルクリックすれば編集できるので、全く使えなくなったわけではないけれど、長い文などが読めず、非常に使いずらい状態になっていました。

Info.plistのタブを閉じたり、Xcodeを再起動させても変わらず。。。。
悪戦苦闘していたところ、自己解決しましたので、備忘録として、また同じ悩みを持つ方がいましたら参考までに。

Info.plistを右クリック > 「Open in New Window」で新しくInfo.plistを開くことで解決しました。
![スクリーンショット 2020-12-13 10.31.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/948735/fd74a187-4242-1adb-d79b-d2b71a78e75d.png)
Info.plistの表示が一旦リセットされたのではないかと思います:thinking:
[Swift] 可変長引数

#可変長引数とは
任意の個数の値を受けとつ事ができる引数です。
関数を呼び出す側に配列であることを意識させないというメリットがあります。
#使い方
引数の定義の後に...をつけます。
`func 関数名（引数： 型...）{}`
#書いてみた
printという関数で引数を可変長引数にしています。
引数にa,b,cの３つを入れ、`for in`の式で引数の数だけprintされるようになっています。
また、`print("first: \(strings[0])")`のように関数内で配列として取り出すこともできます。

```swift
func print(strings: String...) {
    if strings.count == 0 {
        return
    }
    print("first: \(strings[0])")  //first: a
    
    for string in strings {
        print("element: \(string)")
    }
}
print(strings: "a","b","c")  //element: a element: b element: c
```
#参考文献
石川洋資・西川勇世、『[増補改訂第３版] Swift実践入門　直感的な文法と安全性を兼ね備えた言語』、技術評論社、２０２０年４月２８日、４５３ページ
docker-composeを実行しようとしたら、エラー「Cannot locate specified Dockerfile: Dockerfile」

# 前提

- PyCharmでプロジェクトディレクトリに、
DockerFile
docker-compose.yml
を置いて、docker-composeを実行しようとした。

# 発生した問題
- 下記エラーが発生。

```
Building app
[19832] Failed to execute script docker-compose
Traceback (most recent call last):
  File "compose\cli\main.py", line 67, in main
  File "compose\cli\main.py", line 126, in perform_command
  File "compose\cli\main.py", line 864, in run
  File "compose\cli\main.py", line 1316, in run_one_off_container
  File "compose\project.py", line 615, in up
  File "compose\service.py", line 362, in ensure_image_exists
  File "compose\service.py", line 1147, in build
compose.service.BuildError: (<Service: app>, {'message': 'Cannot locate specified Dockerfile: Dockerfile'})

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "docker-compose", line 3, in <module>
  File "compose\cli\main.py", line 78, in main
TypeError: can only concatenate str (not "dict") to str
```

# 対応策
・ファイル名を
DockerFile⇒Dockerfile
に直したら直った。
Gitで特定のブランチへの直pushを禁止する

## Gitでmasterブランチに直pushを防ぐ

ローカルにていろいろファイルを作成して直pushを防止する

## Git hooksとは

- Gitでcommit、push、receiveなどのイベントの前後に実行するスクリプト。
- Gitフックは組み込み機能で、ダウンロードの必要がない。
- ローカルで実行される。

https://githooks.com/

## 使ってみる

.git/hooksフォルダにスクリプトファイルを入れていくことで機能してくれるそう。
今回はpush時にスクリプトを走らせたいので`https://www.git-scm.com/docs/githooks#_pre_push`を見ていく。

### pre-pushファイルを作成

```bash
# プロジェクトのルートでpre-pushを作成しスクリプトを記述する
vim .git/hooks/pre-push

# 実行権限「x」をつける
$ chmod +x pre-push
```

### pre-pushの中身作成

こちらを参考にさせていただき、pre-pushの中身を作成
https://qiita.com/sensuikan1973/items/e6ab84403338a874b3aa

```text
#!/bin/bash

# pushを禁止するブランチ
readonly MASTER='master'

while read local_ref local_sha1 remote_ref remote_sha1
do
  if [[ "${remote_ref##refs/heads/}" = $MASTER ]]; then
    echo -e "push禁止"
    exit 1
  fi
done
```

これで指定したブランチはローカルから直pushできないようになる

## 参考
https://qiita.com/sensuikan1973/items/e6ab84403338a874b3aa
PAY.JPのAPIを用いたクレジット決済機能を実装（導入編②）

JavaScriptに以下の記述を行います。

```javascript:app/javascript/card.js
const pay = () => {
  Payjp.setPublicKey("PAY.JPテスト公開鍵");
  const form = document.getElementById("charge-form");
  form.addEventListener("submit", (e) => {
    e.preventDefault();

    const formResult = document.getElementById("charge-form");
    const formData = new FormData(formResult);

    const card = {
      number: formData.get("order[number]"),
      cvc: formData.get("order[cvc]"),
      exp_month: formData.get("order[exp_month]"),
      exp_year: `20${formData.get("order[exp_year]")}`,
    };

    Payjp.createToken(card, (status, response) => {
      if (status == 200) {
        const token = response.id;
        const renderDom = document.getElementById("charge-form");
        const tokenObj = `<input value=${token} name='token' type="hidden"> `;
        renderDom.insertAdjacentHTML("beforeend", tokenObj);
      }

      document.getElementById("order_number").removeAttribute("name");
      document.getElementById("order_cvc").removeAttribute("name");
      document.getElementById("order_exp_month").removeAttribute("name");
      document.getElementById("order_exp_year").removeAttribute("name");

      document.getElementById("charge-form").submit();
    });
  });
};

window.addEventListener("load", pay);

```
ここで注意なのがgetElementById後のIDの記述です。
実際にブラウザの検証ツールを使い、ID名をよく確認することです。

##Orderモデルにトークンの値を追加する
tokenの値もOrderモデルで取り扱えるようにします。

```ruby:app/models/order.rb
class Order < ApplicationRecord
  attr_accessor :token
  validates :price, presence: true
  validates :token, presence: true
end
```

##コントローラ編集

```ruby:app/controllers/orders_controller.rb
class OrdersController < ApplicationController

  def index
    @order = Order.new
  end

  def create
    @order = Order.new(order_params)
    if @order.valid?
      pay_item
      @order.save
      return redirect_to root_path
    else
      render 'index'
    end
  end

  private

  def order_params
    params.require(:order).permit(:price).merge(token: params[:token])
  end

  def pay_item
    Payjp.api_key = "自身のPAY.JPテスト秘密鍵" 
    Payjp::Charge.create(
      amount: order_params[:price],  # 商品の値段
      card: order_params[:token],    # カードトークン
      currency: 'jpy'                 # 通貨の種類（日本円）
    )
  end
end
```

以上備忘録でした。
脱Excel Elastic Stack（docker-compose）でcsvログを分析・可視化 - Elasticsearchのデータ重複エラー対処方法

## はじめに
どうも！生産技術部で製品の検査工程を担当しているエンジニアです。Elasticsearchにデータを取り込む際にデータ重複のエラーが出ることがあります。その対処方法が公式ブログに記載されていましたので紹介します。

[脱Excel Elastic Stack（docker-compose）でcsvログを分析・可視化 - Elastic Stackとは](https://qiita.com/TomoyukiSugiyama/items/619ab258ba230dfcf0a0)の続きになります。

## 対象読者
この記事では、Elastic Stackをそもそも知らない方、これから試そうと思っている方を対象としています。

## この記事の内容
[公式ブログ「Elasticsearchでのイベントベースのデータ重複を効果的に防止」](https://www.elastic.co/jp/blog/efficient-duplicate-prevention-for-event-based-data-in-elasticsearch)の内容を実践したものです。

## Filterの設定
FilterでユニークなドキュメントIDを生成します。IDはメッセージフィールドをMD5でハッシュ化し、タイムスタンプフィールドを１６進数に変換したものをprefixフィールドにセットしておき、これらをOutput時に連結すれば完了です。

注意すべきは、ブログのままだと`Invalid FieldReference:'@metadata[prefix]'`とエラーが出るため、以下のように変更しています。


```config:logstash/pipeline/filter/filebeat_filter.cfg
  fingerprint {
    source => "message"
    target => "[@metadata][fingerprint]"
    method => "MD5"
    key => "test"
  }

  # ruby { code => "event.set('@metadata[prefix]', event.get('@timestamp').to_i.to_s(16))" }
  ruby { code => 'event.set("[@metadata][prefix]", event.get("@timestamp").to_i.to_s(16))' }
```

## Outputの設定
先述の通りに、document_idに連結して設定します。

```config:logstash/pipeline/output/filebeat_out.cfg
output {
  elasticsearch {
    hosts    => [ 'elasticsearch' ]
    index    => "%{[@metadata][beat]}-csv-%{+YYYY.MM.dd}"
    document_id => "%{[@metadata][prefix]}%{[@metadata][fingerprint]}"
  }
}
```
## 最後に
単純ですが、幅広いシチュエーションで適応できるので、重宝すると思います。
MicronautでのCORS制御

# 結論

application.ymlに設定を追加する。

```yaml
micronaut:
    server:
        cors:
            enabled: true
```

# 参考資料

[MDN web docs -  オリジン間リソース共有 (CORS)](https://developer.mozilla.org/ja/docs/Web/HTTP/CORS)
[Stack overflow - CORS in Mirconaut Microservice](https://stackoverflow.com/questions/58559242/cors-in-mirconaut-microservice)
Goでテキストファイルを使用したIPC(プロセス間通信)をやってみた

<h1>テキストファイルを用いたIPC</h1>
異なるプロセス(ソフト)間でデータの共有・連携をする際にIPC(プロセス間通信)を使用する。
GoでIPCをやろうと思ってみたら、なかなか簡単な方法が見つからなかったので
ファイルの読み書きを使用したシンプルなIPCを実験してみた。

<h1>テキストファイルIPCのメリット</h1>
仕組みがシンプル(テキストファイルの読み取り、書き出しだけで出来る)
全く異なる言語で作成したソフト間でも確実にデータ連携が可能。

<h1>実験内容</h1>
ソフトウェア上で入力した文字列を、もう一方のソフトで表示させる。
C#(WPF)で文字列を入力・送信するソフトを作成し、送信すると入力文字列がテキストファイルに書き込まれる。
Goで入力された文字列をPrintするCLIを作成する。テキストファイルを読み取り、中身が変わったらCLI上にPrintする。
WPFには最終更新日時を表示させておく。Goが文字列をPrintしたら、テキストファイルにその際の日時を書きだす。
文字列・更新日時の読み取り間隔は5秒間
C:\Users\Public\DocumentにData.txt(文字列連携用テキスト)とLastUpdate.txt(更新日時連携用テキスト)を入れて使う。
![IPCイメージ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/595683/db536e30-a5de-eccd-dbfe-be53dc1c8c5d.png)

<h1>動作環境</h1>
OS:Windows 10
WPFアプリケーション：.Net Core 3.1 (C#で作成)
GO:version 1.15.5

<h1>テキストファイルIPCのソースコード</h1>
```Go
package main
 
import (
	"time"
	"fmt"
	"io/ioutil"
)

func Receive(ch1 chan string){
	for{
		data, _:=ioutil.ReadFile("C:\\Users\\Public\\Documents\\Data.txt")
		ch1<-string(data)
		time.Sleep(5*time.Second)
	}
}

func Date(ch2 chan string){
	for{
		now:=time.Now().Format("2006-01-02 15:04:05")
		ch2<-now
		time.Sleep(5*time.Second)
	}
}

func main(){
    ch1:=make(chan string)
    ch2:=make(chan string)
    go Receive(ch1)
	go Date(ch2)
	var prevdata string=""
    for{
		msg1:=<-ch1
		msg2:=<-ch2
		if prevdata != msg1{
			fmt.Println(msg1)
			_=ioutil.WriteFile("C:\\Users\\Public\\Documents\\LastUpdate.txt",[]byte(msg2),0644)
			prevdata = msg1
		}
	}
}
```
io/ioutilを使用してテキストファイルの読み取り/書き出しを実行。
Receiverゴルーチンでテキストファイルを読み取り、ch1に読み取った値を入れてます。
Dateゴルーチンで日時を取得し、ch2を経由してテキストファイルに書き出します。
(並列処理ではなく)2つのプロセスをわかりやすく分けるため、今回はゴルーチンにしました。
time.Sleepで5秒間隔に読み取り・書き出しを行っています。
更新がない場合にPrintしないよう、prevdata変数を判定に使用してます。

![Tx_main.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/595683/e76a719c-bcb9-ec03-db92-52eb64c44a5f.png)
WPFアプリケーションはこのような感じ。
GoのCLIと異なるのはTextBoxがあるくらいで、処理はほとんど同じ。

<h1>結果</h1>
![Rx_main.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/595683/1bce6201-6a55-3e80-2365-153f9f548cf4.png)
「吾輩は猫である」と表示されてるときに「名前はまだない」と入力したら
![IPC.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/595683/25f55b88-a47b-ff81-aedd-9d4d05bef793.png)
Go側にちゃんと「名前はまだない」が表示された。

<h1>最後に</h1>
WPFとGolangでデータ連携が出来たということは、デスクトップ上のクライアントからWebアプリに容易にデータ送信できるかもしれない。
全く異なるプログラミング言語やプラットフォーム同士の連携も、テキストファイルなら簡単に出来るのかも。

<h1>引用・参考文献</h1>
https://www.udemy.com/share/101XCSAEMZdFZXTHQG/
ゴルーチンとioutilの使用方法は、酒井潤先生のこちらのUdemy講座を参考にしました。

https://icooon-mono.com/ (WPFアプリアイコン)
https://www.silhouette-illust.com/ (テキストファイル・CLIアイコン)
イラストにアイコンを使用させていただきました。

https://qiita.com/navel3/items/cec4a8875faa8644d8db
navel3さん記事　ソケットを利用したIPCパッケージを作成しています。
初めてのサクラエディタマクロ（JScript版導入編）

この記事は『[ゆるっと Advent Calendar 2020](https://qiita.com/advent-calendar/2020/yurutto)』の24日目の記事です。

## COBOL業界でよく見かけるサクラエディタ

現在生保関係の業務にいるが、金融と同じでこちらでもCOBOLはうじゃうじゃといてる。<br>
今春から転勤となり、2社目の生保業界だが、どちらの業務でも存在していたのが「サクラエディタ」。

いつかはオープン系に…！と思っているが、まぁまだまだ動ける様子でもなさそうだし、せっかくの機会なのでサクラエディタのマクロについて勉強してみた。

## [サクラエディタ](https://sakura-editor.github.io/)

国産のOSSのテキストエディタ。
リポジトリは[GitHub](https://github.com/sakura-editor/sakura)にあり、結構活発に開発されている。

高機能で軽く、マクロも使えてしかも無料。AtomやVSCodeを開くまでもないけどメモ帳はちょっと…といったといったシチュエーションには多分うってつけ。個人的には結構好き。

おそらくCOBOL業界でよく見かけるエディタ。

## ここでお話すること

* マクロで使う言語
	* WSH（Windows Script Host）
* Hello Worldから導入（キー割当て）まで
	* サクラエディタに標準で用意されているマクロ関数

## マクロで使う言語

サクラエディタマクロでは、

* キーマクロ（拡張子が `.mac` ）
* PPAマクロ（拡張子が `.ppa`）
* WSHマクロ（拡張子が `.vbs` および `.js`）

あたりが使えるみたい。
詳しくは[サクラエディタHP](https://sakura-editor.github.io/help/HLP000204.html)を御覧ください。

今回は、 __`.js` 拡張子のWSH（JScript）__を使ってマクロ作成を進めていく。

## WSH（Windows Script Host）

> WSHとは、Windows上で簡易なコンピュータプログラムであるスクリプトを実行できるようにするソフトウェア。<br>
> WSHでは、Webブラウザなどに実装されていたJavaScript（ジャバスクリプト）のMicrosoft社独自実装である「JScript」（ジェイスクリプト）と、同社のWindows向け開発言語のVisual Basic（ビジュアルベーシック）の簡易版である「VBScript」（ブイビースクリプト）の二つのプログラミング言語（スクリプト言語）が標準で利用できる。
> 
>  _[WSH（Windows Script Host）とは - IT用語辞典 e-Words](http://e-words.jp/w/WSH.html)_

ちなみにJScriptは、[Microsoft Docs](https://docs.microsoft.com/ja-jp/previous-versions/windows/scripting/cc391896(v%253dmsdn.10))には、MicrosoftによるECMA 262 規格仕様の言語 (ECMAScript Edition 3) とある。

サクッとJScriptの関数を使うなら、この記事がおすすめ。

> _[すぐに使えるJScript関数集 - Qiita](https://qiita.com/economist/items/772277b698686bdd7ae3)_

## Hello Worldから導入（キー割当て）まで

ここからが本題。

### 1. マクロを書く

サクラエディタに標準で用意されているマクロ関数は、[サクラエディタHP](https://sakura-editor.github.io/help/HLP000268.html)及びヘルプから参照することができる。

今回は `Hello World` をダイアログで出したいだけなので、リファレンスから `Editor.MessageBox(str, int);` を使用する。

``` Sample.js
Editor.MessageBox("Hello World");
```

作成したマクロは、任意の場所に保存しておく（間違って消さない場所に保存すると良い）。

### 2. マクロをサクラエディタに登録する

キーに割り当てる前に、サクラエディタにマクロを登録する。

［設定］→［共通設定］の［マクロ］タブから以下を設定する。
![fig1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163288/8d96ce36-c9b4-cb42-8d51-6de723416cff.png)
最後に［設定］をクリックすれば…
![fig2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163288/55bda34e-0adb-7abb-1259-6514722edd04.png)
こんな感じにマクロの登録が完了する。

### 3. マクロをキーに割り当てる

ここまででもマクロは実行できるが、いちいちメニューからマクロを選択しなくてはいけないので、せっかくならキーに割り当てると良い。
［設定］→［共通設定］の［キー割り当て］タブから以下を設定する。
![fig3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163288/ce048add-1edb-cf4a-fc60-fc83fe7aa96e.png)
最後に［割付］をクリックすれば…
![fig4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163288/6b8942d3-a7b3-d604-691d-5e936aadfb62.png)
__これですべての準備が整った！__

### あとはマクロを実行するだけ

先程設定したキー（今回は `Shift` + `F5`）を押せば…
![fig5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163288/276818fa-d656-280f-cd84-904fcc02f7ba.png)

## まとめ

JScriptはECMAScript規格に完全に準拠しているため、JavaScriptの使用経験があれば、気軽にサクラエディタのマクロを組めるのは、すごく大きいと思った。テキストエディタを使った決まった業務があるなら、マクロ化しちゃえば相当作業効率が上がると思った。

サクラエディタ使いの方で、まだマクロに手を出していない方は、この機会に是非！

閲覧、ありがとうございました。
Josh Skeen, David Greenhalgh著　『Kotlinプログラミング』　章末問題に挑戦(第７章)

　[Josh Skeen, David Greenhalgh著『Kotlinプログラミング』](https://www.shoeisha.co.jp/book/detail/9784798160191)には章末問題がある。残念なことに解答がないので、[第４章](https://qiita.com/guijiu/items/08dfa397b989b7ecdb3a)に引き続き本を読み進めながら答案を記述する。
　もし回答に間違いや意見があれば、ぜひご指摘いただきたい。

#第７章　章末問題 回答案

##7.6　チャレンジ！　DragonSpeakの改善
　toDragonSpeakを大文字に対応させる。
　本書p112のリスト7-5に示されたtoDragonSpeak()関数を次のリストのように変更する。
　正規表現Regex()関数が受け取る検索パターン引数を大文字にも対応するように"[aeiouAEIOU]"に変更し、when式の->演算子の右側にコンマで対応する大文字を追加した。

```kotlin:Tavern.kt
private fun toDragonSpeak(phrase: String) = phrase.replace(Regex("[aeiouAEIOU]")){
    when (it.value){
        "a","A" -> "4"
        "e","E" -> "3"
        "i","I" -> "2"
        "o","O" -> "1"
        "u","U" -> "|_|"
        else -> it.value
    }
}
```



[第２章チャレンジ！答案](https://qiita.com/guijiu/items/dd3313f2a73401e29bc4)
[第３章チャレンジ！答案](https://qiita.com/guijiu/items/672b8daf014d4e6bb346)
[第４章チャレンジ！答案](https://qiita.com/guijiu/items/08dfa397b989b7ecdb3a)
[第７章チャレンジ！答案](https://qiita.com/guijiu/items/452cfa51bee6c4a4af9d)
[第８章チャレンジ！答案](https://qiita.com/guijiu/items/9a7871b1e41bdabd85e7)
Buffalo LS-QVL を 6TB HDD に換装してみた、けれど失敗

ディスクは WD60EZAZ 
Buffalo LS-QVL の Firmware は 1.74
4TB の換装成功例はあるみたいだけど、6TB HDD 買ったのでチャレンジしてみたが、やっぱりダメだった。
ディスクフォーマットはできるけれど、RAID 作ろうとするとエラー表示して作成されない。
ディスク単体では共有フォルダは作れない。 (JBOD モードが無い。) 
失敗事例も役に立つ　かも。
![LS-QV8.0TL_R5__0100.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/822713/8ee01690-b23e-89d1-0115-e43d11c5d880.png)
![WS016.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/822713/14fb8019-baef-3257-0183-7ed2250ff4d2.png)
![WS017.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/822713/53b624b5-d0cb-3bb8-c6a1-a380ea7927d0.png)
【Stereo Depth】MADNet : Warpを使ってRefinement

<h1>Real-time self-adaptive deep stereo</h1>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/b4b6faee-1102-9bb6-c966-0704004f92b8.png)
この論文のメインのオンラインアダプションは無視して、ネットワークの構造だけを見ていきたいと思う。

<h1>新規性</h1>
<h2>Feature Extraction</h2>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/89f00de5-9eb4-6a3a-8539-6f03d0404e9d.png)
右と左の特徴量をそれぞれ同じネットワークで抽出する。

<h2>Disparity Estimation at resolution n</h2>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/a08837c7-1bcc-f950-6588-cba5390ffa54.png)
一つ前のDisparityに対して右の特徴量をwarpする事でCost Volumeを作り、Concat(結合)する事で新しいDisparityを推定する。

ただし一番低解像度のDisparityを推定する場合は前のDisparityがないので、Correlation Layer(内積でSimilarityを計算する方法)によって最初のDisparityを推定する

<h2>Residual Refinement Network</h2>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/c6df1bd4-ba92-0fbb-26a8-d0716b100373.png)
画像の鞣しやEdgeの補正などを差分を計算する

<h1>結論</h1>
・低解像度から徐々にrefinementしていく方法は有効だと思うが、最初のDisparityが大きく間違った場合修正出来ないのではないかと思った。
・39FPSとPSMNetの2.4FPSと比べてかなり速い！

<h1>参考文献</h1>
Real-time self-adaptive deep stereo
https://arxiv.org/pdf/1810.05424.pdf
行番号の増加値を変更するnlコマンドのiオプション

nlコマンドはiオプションを指定することで、行番号の増加値を変更することができます。

# iオプションの使い方

増加値を変更します。デフォルトは`1`です。マニュアルを参照してみましょう。

## info nl (GNU coreutils)

```console
‘-i NUMBER’
‘--line-increment=NUMBER’
     Increment line numbers by NUMBER (default 1).
```

## busybox nl --help

```console
	-i N		Line number increment
```

## man nl (BSD)
```console
     -i incr      Specify the increment value used to number logical page lines.
                  The default incr value is 1.
```

## POSIX

>-i  incr
Specify the increment value used to number logical page lines. The default shall be 1.

# iオプションを試す

それでは実際に試してみましょう。

```console
$ yes | nl -i 2 | head
     1	y
     3	y
     5	y
     7	y
     9	y
    11	y
    13	y
    15	y
    17	y
    19	y
$ yes | nl -v 2 -i 2 | head
     2	y
     4	y
     6	y
     8	y
    10	y
    12	y
    14	y
    16	y
    18	y
    20	y
```

奇数だけとか偶数だけとかにできますが、「行番号」としてどんな使い方があるのかはあまり想像がついていません。`paste`やプロセス置換などと組み合わせて、データを横に並べたいときなどには使えるかもしれませんね。

```console
$ paste <(yes | nl -n rz -w 2 -s , -i 2 | head) <(yes | nl -n rz -w 2 -s , -v 2 -i 2 | head)
01,y	02,y
03,y	04,y
05,y	06,y
07,y	08,y
09,y	10,y
11,y	12,y
13,y	14,y
15,y	16,y
17,y	18,y
19,y	20,y
```

# `-i`で利用できる整数の範囲

`-i`に与えることのできる整数には実装ごとに差があるので注意が必要です。

|実装|負の値|ゼロ|正の値|
|---|---|---|---|
|GNU coreutils(v8.32)|×|×|○|
|busybox(v1.31.1)|×|○|○|
|BSD(macOS Catalina)|○|○|○|

## coreutilsの`nl`の新機能

BSD系の`nl`ではもともと実装されていた機能ですが、coreutilsの`nl`にも`-i`に負の値を指定し、デクリメントができる機能が追加されました。2020年10月にソース修正が入ったので、次版以降（v8.33？）で有効になる見込みです。
> nl --line-increment can now take a negative number to decrement the count.

これは従来から負の値が利用できるvオプションと一貫性を持たせる意図もあり、各オプションで有効な値の範囲がinfoのマニュアルにも明記される予定です。

# `nl`で正規表現マッチした行に印をつける

現時点ではBSD系の`nl`でしかできませんが、`-v`、`-b pBRE`と組み合わせると、条件にマッチする行をラベリングしていくことができます。`grep`ではマッチしなかった行がフィルタされてしまうので、印だけをつけて全体を出力したいときに便利かもしれません。特に`-i`で`0`を指定すれば印になる数値を固定することができるので、ANSIカラーコードで色付けするのとも違って、後段の処理で行を識別するのが容易になると考えています。
[前回の記事](https://qiita.com/Carol_815/items/a8a4090ba151fd526758#%E9%A7%85%E3%83%8A%E3%83%B3%E3%83%90%E3%83%AA%E3%83%B3%E3%82%B0%E8%A1%A8%E7%A4%BA%E3%81%AE%E9%A7%85%E7%95%AA%E5%8F%B7%E3%82%92%E5%87%BA%E5%8A%9B%E3%81%99%E3%82%8B%E7%9B%B8%E4%BA%92%E7%9B%B4%E9%80%9A)で利用したテキストファイル「yokohamaline」の駅名のうち、4文字以上の駅に印をつけてみます。

```console:BSD
$ nl -v 0 -i 0 -b p'.\{4,\}' yokohamaline
     0	東神奈川
      	大口
      	菊名
      	新横浜
      	小机
      	鴨居
      	中山
     0	十日市場
      	長津田
      	成瀬
      	町田
      	古淵
      	淵野辺
      	矢部
      	相模原
      	橋本
      	相原
     0	八王子みなみ野
      	片倉
      	八王子
```

# `nl`で快速停車駅だけを識別する

正規表現をがんばれば快速停車駅だけに印をつけることもできます。

```console:BSD
$ nl -w 1 -v 0 -i 0 -b p'[川山菊新鴨田相橋八片]' yokohamaline | nl -w 1 -i 0 | tr '01' '快各' | expand
各      快      東神奈川
各              大口
各      快      菊名
各      快      新横浜
各              小机
各      快      鴨居
各      快      中山
各              十日市場
各      快      長津田
各              成瀬
各      快      町田
各              古淵
各              淵野辺
各              矢部
各      快      相模原
各      快      橋本
各      快      相原
各      快      八王子みなみ野
各      快      片倉
各      快      八王子
```

`tr`は文字の置き換えるコマンドで、数値を「各」「快」といった文字に変換しています。`expand`はタブをスペースに変換するコマンドで、Qiita上できれいに表示するために加えています。

---
新卒エンジニアがWeb系の技術をゼロから学んだ話

Livesense Advent Calendar 2020 も折り返しとなりました。13日目を担当する @verdy89 と申します。今年の4月に新卒で株式会社リブセンスに入社し、研修期間を経て現在は[転職ナビ](https://job.j-sen.jp/)の開発に携わっています。
本記事では、Web系の開発経験がない状態からスタートした今年の歩みを振り返ってみようと思います。これから未経験でエンジニア就活をしようとしている学生の皆さんや、未経験エンジニアの受け入れをしようと考えている現場の方などの参考になると嬉しいです。

# 入社時の技術力
前提として、入社時に僕がどれくらいの技術力を持っていたか振り返ります。

- プログラミング経験自体はあり、 AtCoder でいう茶〜緑くらいの実装はできる。
- 簡単なアプリケーションだったらとりあえず動くものを作ることができる。就活は GAS で作ったリマインダーツール1本で乗り切りました。
- git はブランチとかあんまりよくわからないので、個人用レポジトリの master ブランチに直列で commit し続ける程度。インターンを除けばチーム開発する機会なんてまずないし、大して複雑なものを作っているわけでもないのでこれで十分事足りたんですよね。
- MVC とか聞いたことあるけど、全然わからん。

こんなんでよく採用してもらえたなあと自分でも思いますが笑。経験がなくてもある程度の適性があれば内定も夢じゃないのは新卒の特権ですね。就活については今回のトピックではないので割愛。

# 入社してから今までに学んだこと
## 技術領域
技術領域としてはこんな感じです。記載順と学習順は一致しません。

- Webの仕組み
- 読みやすいコードの書き方
- コマンドライン
- オブジェクト指向・デザインパターン
- git
- html
- CSS / SCSS
- JavaScript
- TypeScript
- React
- Ruby
- Ruby on Rails
- PHP / Symfony
- DB設計 / MySQL

座学に割く時間が大部分をしめていましたが、最近は簡単なチケットなら自力で消化できるようになってきました。

## エンジニアとしての学び
ここからは今年得た学びをピックアップしてお伝えします。

### 図で理解する
新しい概念が出てきたら、図で理解することを重視しましょう。文章から得て頭に蓄積される情報の量には限りがあるので、**図で整理することで複数の概念の関連を理解することができます**。例えば Rails （ひいては MVC を採用しているフレームワーク）で作られたアプリケーションの改修について考えるときは、僕の頭の中には[ Rails チュートリアルのこの図](https://railstutorial.jp/chapters/toy_app?version=6.0#fig-mvc_detailed)が浮かんでいます。

### 事実と解釈を区別する
ドキュメントやエラーメッセージを読む習慣がついたら、事実と解釈の区別を意識してみましょう。「ドキュメントにはこう書いてある」という事実と「それを読んで自分はこう考えた」という解釈、「エラーメッセージはこう言っている」という事実と「原因はここだろうと考えた」という解釈を区別するのです。**何かしらハマる箇所があるということは事実と解釈にズレがあるということだ**という認識ができると、自分の解釈が本当に正しいか、批判的に検証することができます。

### わかる部分とわからない部分を切り分ける
わからない点を先輩に訊くと、先輩はおもむろに「このコマンド叩いてみて」とか言うんですよね。そしてそのコマンドを脳死で叩くと確かになぜか動く。「何をやったのかさっぱりわからないがなぜか解決した」ということって初心者あるあるだと思うのですが、その際に今目の前で何があったのかを理解するためには、わかる部分とわからない部分を切り分けて質問することが大切です。この切り分けが自力でできると、疑問の解消が効率的に行われるようになり、いわゆる成長角度が上がっていくはずです。

## 会社員としての学び
多少蛇足になりますが、エンジニアというより会社員として得た学びについてもいくつかお伝えします。

### 会社のリソースを使い倒す
せっかく会社に所属しているのだから、リソースは使い倒しましょう。環境は与えられるものではなくて手に入れるものです。

### 新卒の責務を考える
スキル面では使い物にならない新卒を企業がわざわざ採用する意図を考えてみましょう。そうすると我々新卒がやらなければならないことが自ずと見えてくると思います。

# 今後の課題
学びが多い1年であったことは疑いようもないのですが、とはいえまだまだエンジニアとしてのキャリアを歩み始めたばかりなのも確かです。来たる2021年に向けて、課題を簡単に整理します。

- 1人で黙々と勉強しがち。手を動かしたり、コードレビューをもらったりする量を増やす。
- 会社にいるとそれだけでやることがたくさんあって、世界は会社の外に広がっていることを忘れがち。
- 定期的に発信したり、質問したり回答したりすることで技術に触れる時間を増やしたい。

# 最後に
Web系の開発経験がない状態で入社し、1年弱働く中で学んだことの整理をしてきました。弊社に在籍するエンジニア約100人の中で自分が明らかに一番わかっていないという状況はしんどい面もありますが、引き続き着実に進んでいきたいと思います。
最後に課題として述べた通り、2021年は技術に触れる時間を増やしていきたいと考えています。インプット・アウトプットの記録を垂れ流す[Twitterアカウント](https://twitter.com/verdy_tech)を作りましたので、応援していただければ幸いです。
お読みいただきありがとうございました。引き続き Livesense Advent Calendar 2020 をお楽しみください！
WordPressのショートコード実装方法[投稿の吹き出しとか注釈ボックスとか]

WordPressのショートコードめっちゃ便利！！
よくある、ブログの投稿の吹き出しとか頻繁に使う物はショートコードで呼び出すとかなり楽になります。

多分、良い感じのWordPressテーマなら実装されてるはず。

今回は自作する人向け。

##ショートコード
以下のコードを「function.php」にかく！！

```php:function.php

function divBox( $atts, $content = null ) {
    extract( shortcode_atts( array(
        'class' => 'default',
    ), $atts ) );
     
    return '<div class="'.$class.'"><p>'.$content.'</p></div>';
}
add_shortcode('box', 'divBox');
```

ほぼ自分用メモなので細かくは解説しないけど引数使ってるのね。

```
 'class' => 'default',
 'class1' => '',
 'class2' => '',
```
いろいろ追加したいなら、こんな風に追加していって
`return`のところで普通にHTML書いて`$class、$class１、$class３`を使いたいところでかく！！それだけ！

WordPressの投稿で下記のように書けば使える

```
[box class="任意のクラス名"]テキストテキスト[/box]
```
もちろん、任意のクラス名当てたところのスタイルはstyle.cssなりに指定してあげる。

ちなみのこのショートコードを
WordPressのプラグインの「AddQuicktag」に設定しておくと投稿画面で選ぶだけになり、かなり楽！！

以上、ショートコードの使い方メモでした。
Ruby で解く AtCoder ABC 128 C 動的計画法

# はじめに
*[AtCoder Problems](https://kenkoooo.com/atcoder/#/)* の Recommendation を利用して、過去の問題を解いています。
AtCoder さん、AtCoder Problems さん、ありがとうございます。

# 今回のお題
*[AtCoder Beginner Contest 128 C - Switches](https://atcoder.jp/contests/abc128/tasks/abc128_c)*
<font color="green">Difficulty: 805</font>

今回のテーマ、動的計画法

この問題は、以前に [Ruby と Perl と Java で解く AtCoder ABC 128 C](https://qiita.com/superrino130/items/398cf549b6e3384a24c5) で解いております。

今回、ビット全検索から動的計画法へ次の様に変換しました。

|ビット全検索|動的計画法|
|:--:|:--:|
|入力|入力|
|-|dp配列生成|
|判定|判定|
|出力|出力|
これにより、ビット全検索は動的計画法を特化したアルゴリズムであることが分かります。
# ビット全検索
```ruby.rb
n, m = gets.split.map(&:to_i)
k = m.times.map{ gets.split.map(&:to_i)[1..-1].map{ _1 - 1 } }
p = gets.split.map(&:to_i)
cnt = 0
(0..2**n - 1).each do |x|
  f = true
  k.each_with_index do |y, i|
    v = 0
    y.each do |z|
      v += 1 if x[z] == 1
    end
    if v % 2 != p[i]
      f = false
      break
    end
  end
  cnt += 1 if f
end
puts cnt
```
```bit.rb
(0..2**n - 1).each do |x|
```
ここからが、ビット全検索の判定部分になります。詳細は、[Ruby と Perl と Java で解く AtCoder ABC 128 C](https://qiita.com/superrino130/items/398cf549b6e3384a24c5) を参照願います。
# 動的計画法
## ステップ１
```step1.rb
# before
(0..2**n - 1).each do |x|
# after
dp = (0..2**n - 1).to_a
dp.each do |x|
```
まず、dp配列を準備します。dpの中は、`[0, 1, 2, ..., 2**n - 1]` といった単純な数列です。
## ステップ２
```step2.rb
a = n.times.map{ 2**_1 } # => ex. [1, 2, 4, 8, 16]
```
次に、配列`a`を準備します。この配列は、[A - Frog 1](https://atcoder.jp/contests/dp/tasks/dp_a) で言うところの`足場 i+1 または i+2 へジャンプする`の移動量 [1, 2] に相当します。
## ステップ３
```step3.rb
a = n.times.map{ 2**_1 }
dp = Array.new(2**n, 0)
a.each do |x|
  (2**n - 1).downto(1) do |i|
    break if i - x < 0
    dp[i] = dp[i - x] + x
  end
end # => ex. [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31]
```
配列aより dp配列を生成します。[こちらの動的計画法](https://qiita.com/superrino130/items/965ac708eb2d48f47952#array-%E5%BE%8C%E3%82%8D%E3%81%8B%E3%82%89) と同様の操作になります。
## 完成
```dp.rb
n, m = gets.split.map(&:to_i)
k = m.times.map{ gets.split.map(&:to_i)[1..-1].map{ _1 - 1 } }
p = gets.split.map(&:to_i)
cnt = 0
a = n.times.map{ 2**_1 }
dp = Array.new(2**n, 0)
a.each do |x|
  (2**n - 1).downto(1) do |i|
    break if i - x < 0
    dp[i] = dp[i - x] + x
  end
end
dp.each do |x|
  f = true
  k.each_with_index do |y, i|
    v = 0
    y.each do |z|
      v += 1 if x[z] == 1
    end
    if v % 2 != p[i]
      f = false
      break
    end
  end
  cnt += 1 if f
end
puts cnt
```
実際の競技でビット全検索の問題を動的計画法で解く必要はないと思いますが、精進におけるビット全検索から動的計画法へのステップアップになればと思います。
# まとめ
+ ABC 128 C を解いた
+ 動的計画法 に詳しくなった