OmniAICreator/Qiita-1.07M huggingface dataset:
ずんだの1桁足し算問題 PHP編


[てぃーびー](https://qiita.com/tbpgr)さんの[ずんだの1桁足し算問題](https://qiita.com/tbpgr/items/6c75930566dda97bb5b6)
をPHPで実装しました。

str_repeatを初めて使いました(普段は使わない…)

```php
<?php
// Your code here!
for($i=1;$i<10;$i++){   
    for($j=1;$j<10;$j++){
        $total = $i+$j;
        echo $i."+".$j."=".str_repeat("~", $total).$total."\n";;
    }  
}
?>

```

## 出力
```
1+1=~~2
1+2=~~~3
1+3=~~~~4
1+4=~~~~~5
1+5=~~~~~~6
1+6=~~~~~~~7
1+7=~~~~~~~~8
1+8=~~~~~~~~~9
1+9=~~~~~~~~~~10
2+1=~~~3
2+2=~~~~4
2+3=~~~~~5
2+4=~~~~~~6
2+5=~~~~~~~7
2+6=~~~~~~~~8
2+7=~~~~~~~~~9
2+8=~~~~~~~~~~10
2+9=~~~~~~~~~~~11
3+1=~~~~4
3+2=~~~~~5
3+3=~~~~~~6
3+4=~~~~~~~7
3+5=~~~~~~~~8
3+6=~~~~~~~~~9
3+7=~~~~~~~~~~10
3+8=~~~~~~~~~~~11
3+9=~~~~~~~~~~~~12
4+1=~~~~~5
4+2=~~~~~~6
4+3=~~~~~~~7
4+4=~~~~~~~~8
4+5=~~~~~~~~~9
4+6=~~~~~~~~~~10
4+7=~~~~~~~~~~~11
4+8=~~~~~~~~~~~~12
4+9=~~~~~~~~~~~~~13
5+1=~~~~~~6
5+2=~~~~~~~7
5+3=~~~~~~~~8
5+4=~~~~~~~~~9
5+5=~~~~~~~~~~10
5+6=~~~~~~~~~~~11
5+7=~~~~~~~~~~~~12
5+8=~~~~~~~~~~~~~13
5+9=~~~~~~~~~~~~~~14
6+1=~~~~~~~7
6+2=~~~~~~~~8
6+3=~~~~~~~~~9
6+4=~~~~~~~~~~10
6+5=~~~~~~~~~~~11
6+6=~~~~~~~~~~~~12
6+7=~~~~~~~~~~~~~13
6+8=~~~~~~~~~~~~~~14
6+9=~~~~~~~~~~~~~~~15
7+1=~~~~~~~~8
7+2=~~~~~~~~~9
7+3=~~~~~~~~~~10
7+4=~~~~~~~~~~~11
7+5=~~~~~~~~~~~~12
7+6=~~~~~~~~~~~~~13
7+7=~~~~~~~~~~~~~~14
7+8=~~~~~~~~~~~~~~~15
7+9=~~~~~~~~~~~~~~~~16
8+1=~~~~~~~~~9
8+2=~~~~~~~~~~10
8+3=~~~~~~~~~~~11
8+4=~~~~~~~~~~~~12
8+5=~~~~~~~~~~~~~13
8+6=~~~~~~~~~~~~~~14
8+7=~~~~~~~~~~~~~~~15
8+8=~~~~~~~~~~~~~~~~16
8+9=~~~~~~~~~~~~~~~~~17
9+1=~~~~~~~~~~10
9+2=~~~~~~~~~~~11
9+3=~~~~~~~~~~~~12
9+4=~~~~~~~~~~~~~13
9+5=~~~~~~~~~~~~~~14
9+6=~~~~~~~~~~~~~~~15
9+7=~~~~~~~~~~~~~~~~16
9+8=~~~~~~~~~~~~~~~~~17
9+9=~~~~~~~~~~~~~~~~~~18
```
Pillowで画像に日本語を書き込む

# やりたいこと
テキストを画像に書き込み，はみ出そうなら次の行に改行する

# 実行環境
macOS Mojava 10.14
python 3.5.5
Pillow 5.1.0

# サンプルコード
```text.txt
あいうえお安以宇衣於アイウエオ阿伊宇江於かきくけこ…
```
```put_text.py
# -*- coding:utf8 -*-
import numpy as np
from PIL import Image, ImageDraw, ImageFont

def draw_txt(background, word, f_path, t_size , t_color, t_cood,t_pad):
    # フォント設定
    font = ImageFont.truetype(f_path, t_size)
    # テキスト入力用クラス宣言
    draw = ImageDraw.Draw(background)
    # 背景に書き込み
    cnt = 0
    for y in range(t_cood[0], background.size[1]-t_cood[0], t_size+t_pad[0]):
        for x in range(t_cood[1], background_size[0]-t_cood[1], t_size+t_pad[1]):
            if len(word) > cnt:
                draw.text((x,y), word[cnt], font=font, fill=t_color)
            else:
                break
            cnt += 1
    return background


if __name__ == "__main__":
    # 背景作成
    background_size = (320,240)
    background_color = (0,0,0,255)
    background = Image.new('RGBA', background_size, background_color)
    #テキスト指定
    word = str(np.genfromtxt('word.txt', delimiter=',', dtype=np.str))
    font_path = '/System/Library/Fonts/ヒラギノ角ゴシック W4.ttc'
    text_size = 20
    text_color = (180,180,180,255)
    #y,x
    text_coordinate = (20,20)
    text_padding = (10,0)
    draw_img = draw_txt(background, word, font_path, text_size, text_color, text_coordinate, text_padding)
    #画像指定
    draw_img.show()
    #画像保存
    save_path = './text.png'
    draw_img.save(save_path)
```
# 出力結果
![text.png](https://qiita-image-store.s3.amazonaws.com/0/171066/0fe51d07-83e8-37f9-38bf-96a040df8ead.png)


# 問題点
全角しか対応していない(やりたかったのが全角のみだったから)

# 参考サイト
https://pillow.readthedocs.io/en/3.1.x/reference/Image.html
https://pillow.readthedocs.io/en/5.1.x/reference/ImageFont.html
https://pillow.readthedocs.io/en/5.1.x/reference/ImageDraw.html
Python×Keras×GANチュートリアル　人工知能でファッション生成（2）

# コードの解説
 （２）もお読み頂きありがとうございます。
　それでは、さっそく、コードの解説に移らせていただきたいと思います。まずはganの仕組みをしっかり理解する必要があります。原論文をきちんと読んだ上で、実装に即した形で説明したいと思います。

## GANの実装の仕組み
### 基本の構成要素
　GANは、２つのニューラルネットワークでできています。
　generaterとdescriminaterです。面倒なので、ｇ，ｄと呼びます。ｇは、ニセの画像を作り出すニューラルネットワークです。ｄは、ｇが作ったニセの画像と、本物の画像を識別するニューラルネットワークです。
　なので、ｇが偽造者、ｄが判別者などと呼ばれたりもします。
ｇとｄをトレーニングしていくと、最終的には、本物っぽい画像を生み出すｇが得られることになります。このｇを使えば、以後、本物っぽい画像をいくらでも生成できることになります。
###gとｄの実装理念
　ｇは、ノイズの入力に対してニセ画像を出力するニューラルネットワークです。
　ノイズは、サイズが(ｎ×１)で、各要素が標準正規分布から発生させた乱数になっているnumpyndarrayです。
　ニセ画像は、サイズが（row×columun×３）で、各要素は−１から１の範囲に収まるnumpyndarrayです。
　　ｇ（ノイズ）＝ニセ画像
ですね。
　ｄは、画像の入力に対して本物かどうかを出力するニューラルネットワークです。
　画像は、ニセ画像または真の画像です。真の画像は、サイズがニセ画像と同じで、実際の写真等をndarrayに変換したものです。ただし、各要素は２５５で割り算して−１されているので、範囲は−１から１になります。出力は、０から１のスカラーで、ニセ画像に対しては０，真の画像に対しては１を出力するようにトレーニングされます。
　ｄ（画像）＝０〜１ですね
### 学習のやり方
　ここが、元の論文以外でなかなか説明されていない部分です。
　学習は２ステップの組み合わせになります。
　１ステップ目は、gのパラメタを固定してdのパラメタだけを鍛えます。つまり、真の画像の入力には１を、ニセ画像＝ｇ（ノイズ）の入力には１を返すように、dだけをトレーニングします。
　２ステップ目は、ｄのパラメタを固定してｇのパラメタだけを鍛えます。この際、ｇとｄを組み合わせたモデルを作って、トレーニングします。組み合わせたモデルは、
ｄ（ｇ（noise））
ですね。その出力が１になるようにgのパラメタだけを鍛えます。
　<strong>各エポックごとに、このステップ１と２を繰り返していくのです。これがポイントです</strong>。敵対的生成モデルとは言うものの、gとｄを同時に鍛えるのではなく、交互に鍛えるんですね。ですから、実装がカンタンに済むのです。

　説明が長くなってしまったので、コードの解説は次回行いたいと思います。お読み頂き、ありがとうございました。
Googleフォーム+Herokuで簡単に独自アンケートフォームを作る

とある案件でアンケートフォームを作ってほしいと依頼を受けました。

* Webで利用できること
* 独自のCSSを利用したい（googleフォームのままは嫌）

WebアプリケーションにしてDBを構築してもよかったのですが、都度DBにアクセスするのも手間（かつユーザが直接確認できない）なので、バックエンドはgoogleフォームがいいと判断しました。

その際の方法を共有します。

ざっくりとした手順は以下の通りです。

1. html+CSSを作成する
* googleフォームを作成する
* htmlにgoogleフォームのform actionとinput nameを埋め込む
* herokuにアップロードする

### 前提
* googleアカウントを持っている
* herokuアカウントを持っている
* heroku操作はwindowsで記載しています。（Macの方は読み替えてください）

### html+CSSを作成する
こんな感じです。
サンプルはbootstrapを使っています。
![top.png](https://qiita-image-store.s3.amazonaws.com/0/140303/db24af6e-90d9-c0a2-49c1-d49bb3653ad4.png)

この時点ではformのactionとinputのnameは仮の値(ここではxxx)とします。
これらはgoogleフォーム作成後に置き換えます。

```html:formとinput部分
<form class="needs-validation px-5" action="xxx">
<input id="q1a1" name="xxx" value="ラーメン" type="radio" class="custom-control-input" checked required>
```
入力チェックはinput patternを利用すれば最低限は実装できます。

```html:入力チェック
<input type="tel" class="form-control" id="tel" name="xxx" placeholder="000-000-0000" pattern="\d{2,4}-\d{3,4}-\d{3,4}" required>
```

### googleフォームを作成する
googleフォームはgoogleドライブから新規＞その他＞googleフォームを選択すると作れます。
![form.png](https://qiita-image-store.s3.amazonaws.com/0/140303/054efb51-2061-23cc-4dc6-586891c59297.png)

HTMLに合わせてアンケート項目を作成していきます。
ラジオボタンの値は作成したHTMLのinput valueと合わせる必要があります。
それ以外は任意でOKです。
![form2.png](https://qiita-image-store.s3.amazonaws.com/0/140303/a687823f-1979-dfbc-2f24-cdd8d99c91c8.png)

次にスプレッドシートを作成します。
これによりスプレッドシートでアンケートの回答が見れます。
回答＞緑色のスプレッドシートロゴを押下します。
スプレッドシートのファイル名などは任意です。
![form3.png](https://qiita-image-store.s3.amazonaws.com/0/140303/f796264d-27b1-c513-9345-a75d0b610eaf.png)

フォームの項目がスプレッドシートに表示されればOKです。
![form4.png](https://qiita-image-store.s3.amazonaws.com/0/140303/a2315b92-c307-2ddd-44a6-ab74527960eb.png)

### htmlにgoogleフォームのform actionとinput nameを埋め込む
googleフォームをプレビューで開きます。
![form5.png](https://qiita-image-store.s3.amazonaws.com/0/140303/c3eb22c8-586e-37fe-41c3-654debeb10a1.png)

プレビューを開いた状態で、デベロッパーツールを表示します。（ページのソースを表示でも可。）
![form6.png](https://qiita-image-store.s3.amazonaws.com/0/140303/9a51dd9d-c647-866a-50d0-a94ee2780372.png)

googleフォームのhtmlからform actionの値を見つけてコピーします。
それを作成したhtmlのform actionに貼り付けます。

```html:form
<form action="https://docs.google.com/forms/d/e/xxx/formResponse" target="_self" method="POST" id="yyy">
```

同様にgoogleフォームのhtmlからinput name(entry.xxxの部分)を探してコピーします。
それを作成したhtmlのinput nameに貼り付けます。

```html:input
<input type="hidden" name="entry.xxx" jsname="yyy" disabled>
```

ローカルPCのhtmlを開いて、submitしてみて、スプレッドシートに回答内容が登録されればOKです。

### herokuにアップロードする
htmlファイルと同じフォルダにindex.phpを作成し、以下の内容とします。

```
<?php
header('Location: /作成したhtml名.html');
?>
```

コマンドプロンプトでhtmlファイルが配置されたフォルダにCDして以下のコマンドを実行します。
(app_nameは任意です。)

```
git init
git add .
git commit -m "初回コミット"
heroku apps:create app_name
git push heroku master
heroku open
```

すると、ブラウザで以下のURLでアンケート画面が表示されます！
https://app_name.herokuapp.com/index.html

### 参考
* httpsにする方法
http://unot13.hatenablog.com/entry/2018/06/04/170017

* BASIC認証する方法
https://qiita.com/reoring/items/bca12aaa5f94b190a488

* その他参考
https://qiita.com/sota6412/items/fa077cbf820faca30598
https://qiita.com/sugitata/items/182173c01e0470a3a4a8

以上です。
Vue.jsの開発をlocalhostでHTTPS環境で行う方法

# はじめに

Vue.jsでFacebookログインとGoogleログインを作る開発過程で、開発環境にHTTPSが必要となった。
その開発環境構築のメモ書きです。

# 結論

「yarn serve <font color="red">--https</font>」で「 http<font color="red">s</font>://localhost:8080 」で開発ができます。


# HTTPSが必要になった経緯～Facebookログイン開発

## 開発の問題点

Facebookログインを使う場合は、「HTTPSを強制」が必須です。

以下はFacebookログインの設定画面です。「HTTPSを強制」が「はい」の状態で変更ができません。
![2018-10-06_10h14_37.png](https://qiita-image-store.s3.amazonaws.com/0/133291/5b0dbab8-bc73-4825-726c-c86daac8ccee.png)

普通にVue.jsで「yarn serve」すると、「http://localhost:8080」で開発サーバが起動するので、Facebook SDKが以下のようなエラーを吐いて動きません。
![2018-10-06_10h23_53.png](https://qiita-image-store.s3.amazonaws.com/0/133291/acce3c6b-33f5-cf57-548b-f7b2fc94cd71.png)

## 解決方法

Vue Cli 3にはHTTPSが準備されていました。

https://cli.vuejs.org/guide/cli-service.html#vue-cli-service-serve

```shell
Usage: vue-cli-service serve [options] [entry]

Options:

  --open    open browser on server start
  --copy    copy url to clipboard on server start
  --mode    specify env mode (default: development)
  --host    specify host (default: 0.0.0.0)
  --port    specify port (default: 8080)
  --https   use https (default: false)
```

実際に動かして見ると、HTTPSで起動しました。

```shell
PS D:\dev\xbc> yarn serve --https
yarn run v1.10.1
warning ..\package.json: No license field
$ vue-cli-service serve --https

 INFO  Starting development server...
 10% build 10% build      11% build 11% build 11% 13% build 13%    51% b 51% b 51% b 98% after emitting CopyPlugin

 DONE  Compiled successfully in 4507ms                                                                                                                                                 10:54:43

  App running at:
  - Local:   https://localhost:8080/
  - Network: https://192.168.0.8:8080/

  Note that the development build is not optimized.
  To create a production build, run yarn build.
```

証明書はオレオレです。
![2018-10-06_10h57_50.png](https://qiita-image-store.s3.amazonaws.com/0/133291/0ea06830-e81d-2f2c-cff4-1b906d77f344.png)

## 補足

Facebookログインには、https://github.com/iliran11/facebook-login-vue を参考にさせていただきました。
ログインするだけなら、こちらのコンポーネントを導入するとよいと思います。



# 参考文献

* https://qiita.com/kent_ear/items/6fcc477392aaede175f4
* https://cli.vuejs.org/guide/cli-service.html#vue-cli-service-serve
* https://github.com/iliran11/facebook-login-vue
ADに登録している全グループポリシーを、1つ1つグループポリシー名のhtmlファイルに出力する

前提：
ADサーバーで実行してください

懸念：
1500ポリシーのとき、大体1分で終わります
CPU結構使います(+50〜60% t1.midium)
　　嫌なら「Get-GPOReport -Guid」の前にsleep入れてください
　　(sleep分xポリシーの時間がかかるようになります)


```powershell

Get-ADOrganizationalUnit -Filter 'Name -like "*"'| %{Get-GPInheritance -target $_} | %{$_.gpolinks} |%{Get-GPOReport -Guid $_.Gpoid -ReportType Html -Path c:\gpotest\$($_.Displayname).html}
```

sleep 版

```powershell

Get-ADOrganizationalUnit -Filter 'Name -like "*"'| %{Get-GPInheritance -target $_} | %{$_.gpolinks} |%{sleep 1;Get-GPOReport -Guid $_.Gpoid -ReportType Html -Path c:\gpotest\$($_.Displayname).html}
```

# 余談
GPO情報をhtml出力する「Get-GPOReport」コマンドレットをループ処理中で実行するとCPUを大分使うのは、コマンドレットが実行終了しているにも関わらず、バックグラウンドにプロセスが残っているためです。
回避するためにsleepを使いましたが、もっと少し滑らかに処理を回すために、セマフォもどき関数を作りました。(実際にはバックグラウンドプロセスの終了を待てないから、"もどき"です)
AD関連のコマンドレットはCPU、メモリ消費が多くなるので、有効かなと思います。

```powershell

# カウント変数初期化
$script:counting = 0

# 指定したスクリプトブロック${scriptbl}を${number}回実行するごとに${sleeptime}秒待つ、セマフォもどき関数
function do-some-block-and-sleep ([scriptblock]${scriptbl},${number},${sleeptime}) { 
    $script:counting++
        switch ($script:counting) { 
            {$_ % ${number} -ne 0} {& $scriptbl} 
            {$_ % ${number} -eq 0} {& $scriptbl; sleep ${sleeptime}; $script:counting = 0}  
        }
}

# GPOを1つ1つhtml出力 30個出力するごとに2秒sleep =実行時間 100秒 (gpo1500個の時)
Get-ADOrganizationalUnit -Filter 'Name -like "*"'| %{Get-GPInheritance -target $_} | %{$_.gpolinks} |%{ $gpoid = $_.Gpoid; $displayname = $_.Displayname; do-some-block-and-sleep {Get-GPOReport -Guid $gpoid -ReportType Html -Path c:\gpohtml\$($displayname).html} 30 2}

```
Array.newを使って２次元配列を作る

二次元配列の作り方を学んだので、メモ。

## Array.newの使い方
Array.newとすることで、新しい配列を生成（Arrayクラスのインスタンスを生成している）することが出来る。
第一引数には配列の中の要素の数を指定し、　第二引数では　どのようなデータを入れるか指定できる。

```ruby:array.rb
numbers = Array.new(10,1)
p numbers
p numbers.length
#[1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
#10
```
## Array.newを使って二次元配列を作る
Array.newの引数でさらにArray.newを使うことによって簡単に二次元配列を作ることもできる。第一引数で配列の数を指定し、第二引数でArray.newとすることで、配列の中に配列（二次元配列）を生成している。　ただし注意点が１つ、numbers2[0][1] = 2で１つめの配列のインデックス番号１の要素を書き換えようとしているが、他の配列の要素も変わっている。　上手く説明はできないが、Array.new(4, Array.new(3,1))によって全て共通のデータになるので、共有している他のデータも変更されてしまうとのこと。

```ruby:array.rb
numbers2 = Array.new(4, Array.new(3,1))
numbers2[0][1] = 2
p numbers2
p numbers2.length
#[[1, 2, 1], [1, 2, 1], [1, 2, 1], [1, 2, 1]]
#4
```
じゃあどうすれば別のデータとして管理できるんだってばよ！？　ということで最近個人的にお世話になっているmapさんを使えば、別のデータとして　格納することができる。numbers3[0][1] = 2と記述すれば、本来やりたかった０番目の配列の１番目の要素を変更することができる。

```ruby:array.rb
numbers3 = Array.new(4).map{Array.new(3, 1)}
numbers3[0][1] = 2
p numbers3
#[[1, 2, 1], [1, 1, 1], [1, 1, 1], [1, 1, 1]]
```
hello

#emacs lisp
it is hard but fun too
**major functions**:
1.byte compiler for lisp
2.regex compiler for font-lock
3.character compiler for intl characters different from utf

nobody cares about 3, but other two are dearest of emacs usage such as speeding up macros (1) and prettifying/emphasizing code (2) not just for searching
##some hate emacs
why some hate emacs i dont know, maybe its too hard for them
**some possible reasons**:
1.they simply hate lisp
-pepple tend to like syntactically complex languages (they make you sound intelligent without much substance)
2.no regex reader macro
-there are a host of other features the implementors refuse to implement
3.weird character encodings
-font assignments are different from os mappings
###some dont care
many dont care about emacs, because they are fine with what they already have i suppose
**unnecessary complications**:
1.fixed routine work so no customization needed
2.instead of complicated customizations, they want specialized features built in
3.no need to go **outside the box** so to speak (viewing web, pdf, rpc, etc)
###emacs is outmoded for info age
some say emacs is **outdated**:
-no real web parser exists for emacs and there are far more web writers/designers than programmers/latex writers combined
-implementors refusal to change goes to the core of emacs as well, such as lisp which has been outperformed by more recent but limited languages
####thats all for today
JavaScriptの短縮アロー関数で２文以上の処理をしたいときに使う裏ワザ

ES6に追加されたアロー関数はスッキリ書けて気持ちいですよね
特に一行のときは更に色々省略出来ていいですよね

しかしブロック(`{}`)を省略したときは一文しか書けないので２文以上は書けません
便利ですが、`Promiseでエラーがあったらコンソールに吐いてnullを返すことをしたい` のような
一行でスッキリと書きたい量の処理であってもブロックにしないと２文は書けないのです...
せっかく`{}`や`return`を省略できたのになんだかがっかりしますよね[^1]

[^1]: 人によっては`;`も省略したいでしょう

```js
Promise.reject('some error')
  .catch(err => { console.error(err); return null })
```

そんなときに[mdnの演算子一覧](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators)を見ていたら気になるものがありました。[カンマ演算子](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Comma_Operator) です
どうやらカンマ演算子を使用すると複数の式を実行し、最後の式を返す性質があるそうです
ためしにコンソールで実行してみると一目瞭然です

```js
> (console.log('log'), null)
  log
< null
```

これでスッキリ書けますね！めでたしめでたし[^2]

[^2]: 可読性？なにそれおいしいの？

```js
Promise.reject('some error')
  .catch(err => (console.error(err), null))
```
Digital Ocean でnode.js アプリケーションを実行するとこまでメモ

`Digital Ocean`の`Droplets`を作成するところから`express.js`でAPIサーバーを立てるところまでのメモ。
`Digital Ocean`とは言ったもののDropletsを作る以降は、OS共通のはず。

目次:
1. Dropletsを作る
2. SSH接続してみる
3. `nvm`で`node.js`をインストールする
4. `express.js`アプリケーションを実行する

## Droplets を作る
以下のイメージとサイズを選択した。

```
OS: CentOS 7.5 x 64
MEMORY: 1GB
vCPUs: 1vCPU
SSD DISK: 25 GB
TRANSFER: 1 TB
PRICE: $5/mo, $0.007/hr
region: Singapore
```

SSHキーもこの画面で設定できる。これでサーバーが生成されて起動する。

## SSH接続してみる
ターミナルを開いて `$ ssh root@[IPアドレス]`。
うまく接続できると`[root@[サーバー名] ~]#`となる。

## nvmでnode.jsをインストールする
`nvm`は`node.js`のバージョンマネージャー。直接`node.js`をインストールすることもできるけど。今回は`nvm`経由でインストールする。
インストール方法は、参考のリンクにあるのでそちらを参照したほうが確実。
以下は2018/10現在のインストール手順。

```
$ curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.11/install.sh | bash
```

これだけだと`nvm: command not found`となったが一度`exit`して入りなおしたら`nvm`コマンドが使えるようになった。インストールは`bash`の起動スクリプトに`nvm`が追加するだけのため。多分。

参考: [GitHub - creationix/nvm: Node Version Manager - Simple bash script to manage multiple active node.js versions](https://github.com/creationix/nvm)

`nvm`を使って`node.js`をインストールする。とりあえずローカルの`node`バージョンと同じものをインストールする。`$ nvm install 9.2.0`。
`$ node -v` でインストールされていることを確認する。

## express.jsアプリケーションを実行する
hello worldするだけのexpressアプリケーションを作ってそれをscpで転送して実行してみる。
以下のファイルを転送する。

``` just-hello/hello.js
import express from 'express';
const app = express();
const port = 8080;

app.get('/api/hello', (req, res) => res.json({ message: 'hello world' }));

app.set('port', port);
app.listen(app.get('port'), () => {
  console.log(`running at port: ${port}`);
});
```

``` just-hello/package.json
{
  "scripts": {
    "start": "node -r babel-register hello.js"
  },
  "babel": {
    "presets": [
      "env"
    ]
  },
  "dependencies": {
    "express": "^4.16.3"
  },
  "devDependencies": {
    "babel-preset-env": "^1.7.0",
    "babel-register": "^6.26.0"
  }
}
```

SCPを使って転送する。`$ scp -r /just-hello root@[IPアドレス]:/home/public`
サーバーに入ってファイルが転送されていることを確認してみる。

```
$ ssh root@[IPアドレス]
$ cd /home/public
$ ls
```

`/home/public`ディレクトリが生成され中に`hello.js`と`package.json`があるはず。

確認したら`node modules`をインストールして`hello.js`を実行する。

```
$ npm install
$ npm run start
```

ブラウザで`http://159.65.143.104:8080/api/hello`にアクセスして`{"message":"hello world"}`が返ってくることを確認する。
PythonでOAuthlibを使う時に出現するエラー

Twitter APIをPythonで叩こうとOAuthlibをダウンロードしたものの、不明なエラーが2か所発生したため適当に修正した。本当にこれで合っているのかわからないがともかく動いた模様。

######'crypto'ファイルが見つからない
```python:_big_num_ctypes.py
try:
    # On Python 2, the unicode string here may raise a UnicodeDecodeError as it
    # tries to join a bytestring path to the unicode name "crypto"
    libcrypto_path = 'C:\Users\hoge\AppData\Roaming\Python\Python36\site-packages\OpenSSL' #find_library(b'crypto' if sys.version_info < (3,) else 'crypto')
    if not libcrypto_path:
        raise LibraryNotFoundError('The library libcrypto could not be found')

    libcrypto = CDLL(libcrypto_path)
```

どうやらfind_library関数がちゃんと働かないみたいなので、crypto.pyへのパスを直接手入力した。
Powershellでファイルの文字コードを変換する方法

従来はファイルの文字コードを変換するのは大変面倒でした。テキストファイルですら、メモ帳で逐一開いて名前を付けて保存しなければならなかったですから。コマンドプロンプトで一括変更するやり方があれば良かったのですが、マイ〇ロソフト様はまた何を考えているのかそういったコマンドは実装されていませんでした。ところがPowershellには新しく文字コードを変換する方法が実装されていることを発見しました。ま、Linuxではもともと出来ていたのですからできて当たり前ですよね。以下がその手順です。ASCII（メモ帳の表示ではANSI）からUNICODEへの変換を例にとっています。

```powershell:powershell
get-content -encoding ascii sample.txt | set-content -encoding unicode sample2.txt
```
【Rails】ローカル環境におけるmysql接続エラー対処法【Can't connect to local MySQL server through socket】

##起こった問題
昔にcloud9(webサービス)で作ったrailsアプリを自分のパソコンにpullしてきたのだが、local環境でサーバーを立ち上げようとしたら以下のエラーが出た。

```
Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)


mysql2 (0.4.10) lib/mysql2/client.rb:89:in `connect'
mysql2 (0.4.10) lib/mysql2/client.rb:89:in `initialize'
....
....
....
```

socket側の設定に問題があり、localのmysqlサーバーに接続できていない状態である。

##実行環境
・macOS
・mysql  Ver 8.0.12 for osx10.13 on x86_64 (Homebrew)
・Rails 5.0.6

##試したこと

とりあえず意味がわからなかったのでもう手当たり次第に手を動かした。

全てはここに置いてある。↓
https://teratail.com/questions/147942#


###mysqlに接続できるか確認
```
mysql -u root
```

```
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 28
Server version: 8.0.12 Homebrew
...

mysql> 
```

これは普通に接続できた。

###mysql.serverを動かす
とにかくサーバーを起動させないと動かないとあったので以下を実行。

```
mysql.server start
```
```
SUCCESS! MySQL running (61921)
```

うん。普通に走ってる.

参考: https://qiita.com/hondy12345/items/d32ed749fb49e9da7de6


###sockファイルを作成
mysqlサーバーに接続するときのファイルがないのでは？ということでファイルを作成.

```
sudo touch /tmp/mysql.sock
```

これでもだめなので権限でのエラー？

```
sudo chown mysql:mysql /tmp
```


しかし、特に変化はない。


参考: https://qiita.com/carotene4035/items/e00076fe3990b9178cc0

###rails側で設定しているsockファイルを作成
そもそもrails側でしているsockファイルが無い！と思い作成してみた。

```
sudo touch /var/lib/mysql/mysql.sock
```


するとエラー文の末尾(2)が(38)に変わっただけで後の変化はない。

```
Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (38)
```

参考: https://qiita.com/gaogaomango/items/933a1f55004920a4323d


##sockをmacの環境に合わせる
そもそも**cloud9で開発しているときのRails環境に合わせにいってるからこうなるのでは？**という結論にいたったので, mysqlのsockファイルがどこにあるのか確かめ,Rails側を確認することに。

まず、mysqlの環境変数を取得します。

```
 mysqladmin variables | grep socket
```

```
| mysqlx_socket                                            | /tmp/mysqlx.sock    |
| performance_schema_max_socket_classes                    | 10                  |
| performance_schema_max_socket_instances                  | -1                  |
| socket                                                   | /tmp/mysql.sock     |
```


soketは`/tmp/mysql.sock `にあるっぽいので
rails側のsocketで設定し直す。


```config/database.yml
#変更前
socket: /var/run/mysqld/mysqld.sock
#変更後
socket: /tmp/mysql.sock
```

これで無事動きました！！


ref: https://stackoverflow.com/questions/19530089/getting-cant-connect-to-local-mysql-server-through-socket-var-run-mysqld-mys

##まとめ
mysqlに接続できない問題に丸一ヶ月費やしました。。
今回の一番の原因としては, やはりRails側のDB設定です。

github上から取ってきたものをローカルで動かすときは自分のPC環境と相違が発生することも考慮しないといけないので、これから気をつけて行きたいですね。
alpine版のPHP公式Dockerfileを使ってphpredisを入れる

alpine版のPHP公式Dockerイメージを使って

```Dockerfile
RUN docker-php-ext-install redis
```
でphpredisを入れようとしましたが、入ってくれないようです。


ひとまず、下の2つの記事を足して割った方法で、phpredisを入れることが出来ましたので書いておきます。

- [PHPのオフィシャルDockerイメージにredis exensionを追加する方法](https://qiita.com/hirohero/items/f3abb8519e0fe609546e)
- [PHPのオフィシャルDockerイメージにredis exensionを追加する方法(debian版)](https://qiita.com/o0h/items/c79077cf96c6e8f27742)



```Dockerfile:Dockerfile（シンプル版）
FROM php:7.2.8-fpm-alpine3.7

# gitで落とすので追加
RUN apk add git

# これを叩かないとextensionのディレクトリ（/usr/src/ext）が見れない
RUN docker-php-source extract 

# extensionのディレクトリに、phpredisを任意のブランチでクローンして突っ込む
# (ここでは4.1.1のタグを指定)
RUN git clone -b 4.1.1 --depth 1 https://github.com/phpredis/phpredis.git /usr/src/php/ext/redis && \
    docker-php-ext-install redis
```

```Dockerfile:Dockerfile（ちゃんと書くとこんな感じ？）
FROM php:7.2.8-fpm-alpine3.7
RUN apk update && \
    apk --no-cache upgrade && \
    apk add git && \
    docker-php-source extract \
    git clone -b 4.1.1 --depth 1 https://github.com/phpredis/phpredis.git /usr/src/php/ext/redis && \
    docker-php-ext-install redis
```

### まとめ
```Dockerfile:こんな感じで応用できそうな？
RUN git clone -b 7.4 --depth 1 https://github.com/hoge/hoge.git /usr/src/ext/hoge && \
    git clone -b 5.7 --depth 1 https://github.com/fuga/fuga.git /usr/src/ext/fuga && \
    docker-php-ext-install hoge fuga
```

composerでC拡張を入れられる世界線に行きたい...

### 参考
- [PHPのオフィシャルDockerイメージにredis exensionを追加する方法](https://qiita.com/hirohero/items/f3abb8519e0fe609546e)
- [PHPのオフィシャルDockerイメージにredis exensionを追加する方法(debian版)](https://qiita.com/o0h/items/c79077cf96c6e8f27742)
[Ruby on railsメモ]Herokuにて、Rmagick等を使って画像に文字入力をするときに文字化けする件について。

# Rmagick、Minimagickを使って画像に文字を入力する機能を作ったよ！

うん。作ったよ。

そしたらね、Herokuで全く日本語が映らなかったよ！！（ニカッ！）

「わーいわーい」って文字入れたのに「??????」になってた！！
泣きたくなったね。

この問題にはまってはや４日（くらい）、やっと解決できたので書いときます。

## １. Railsプロジェクト直下に「.fonts」というフォルダを作る。

言葉の通り、Railsプロジェクト直下にいろんなフォントをまとめて入れておく「.fonts」フォルダを作る。

最初つく「 . 」を見て「？」てなったけど、これあれなんだね。隠しフォルダにするみたい。

んで、この中に「.ttf」とか「.otf」とかの拡張子のフォントファイルを保存する。自分の好きなやつね。

## 2. rmagickなどの処理動作の中で、path付きでフォントファイル名を入力する。

rmagickとかで文字を入れるとき、その文字に対していろいろ設定できると思うんだけど、その中にフォントをいじれるものがある。自分は「config.font」だったかな？

そこにさっき入れたフォントファイルの名前をrails.rootから入れる。例えば「Hogehoge.ttf」のフォントを入れるときは、

``` ruby:File.rb
config.font "#{Rails.root}/.fonts/Hogehoge.ttf"
```

みたいになる。

これをHerokuにプッシュしたら見事、日本語が表示されました！

# まとめ

「これ嘘だと思うでしょ？　ふぉんっと、ふぉんっと。」っていうダジャレが思いつくぐらいには真剣に悩みました。

気づけば４日立ってました。(いやちゃんとやれよ)
windows10 でメモリーを開放する (empty.exe

### empty.exe を使用します.

```free-mem.cmd
@echo off
rem
rem	Summary   : free memory of RAM.
rem

echo.
echo %~dpnx0, size=%~z0 bytes.
echo.
SETLOCAL EnableDelayedExpansion
for /f "usebackq tokens=1,2 delims=,"  %%a in (`tasklist /fo csv`) do (
    set pid=%%~b
    if not "!pid!"=="0" (
        echo program=%%~a pid=!pid!
        empty !pid!
    )
)
endlocal
```

> NOTE:

* task managerで確認すると、確かに"使用中"のmemoryは減りますが、  
  "スタンバイ"として表示されているmemory領域と、"使用中"の合計サイズはほぼ変わりません・・・
lodash のファイルサイズを lodash-webpack-plugin と babel-plugin-lodash を使って削減する

## 概要

react で SPA を作成していたのですが、webpack-bundle-analyzer をみると、lodash の占める割合が大きかったので、少しでも減らせるような試みとして、
[lodash-webpack-plugin](https://github.com/lodash/lodash-webpack-plugin)と [babel-plugin-lodash](https://github.com/lodash/babel-plugin-lodash)を使って、 ファイルサイズを削減しました。

## 利用した主なパッケージのバージョン

```json
"babel-core": "^6.26.3",
"babel-loader": "^7.1.5",
"babel-plugin-lodash": "^3.3.4",
"babel-preset-env": "^1.7.0",
"babel-preset-react": "^6.24.1",
"lodash-webpack-plugin": "^0.11.5",
"webpack": "^4.20.2",
"webpack-bundle-analyzer": "^3.0.2",
"webpack-cli": "^3.1.2",
```

## 使用方法

まずはパッケージを追加

```bash
yarn add --dev lodash-webpack-plugin babel-plugin-lodash
```

`.babelrc`に`babel-plugin-lodash`を追加

```.babelrc
"plugins": ["lodash"]
```

`webpack.config.js`に`lodash-webpack-plugin`の設定を追加

```javascript
const webpack = require('webpack');
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer')
  .BundleAnalyzerPlugin;
const LodashModuleReplacementPlugin = require('lodash-webpack-plugin'); //追加

module.exports = {
  //省略
plugins: [
    new BundleAnalyzerPlugin(),
    new LodashModuleReplacementPlugin({
      collections: true,
      chaining: true
    }) //追加
  ]

```

`lodash-webpack-plugin`をデフォルト設定で使うと使えない機能がでてくるので、

ここでは`collections`:Collection method(orderByとか使ってたので)
`chainig`:メソッドチェーンを使っていたので

その他の設定に関しては、[ここ](https://github.com/lodash/lodash-webpack-plugin#feature-sets)を参照

後は、`webpack -p`などして動作確認を行ってください。


## まとめ

対応を行ったことでファイルサイズは削減できたのですが、細かい値は記録してませんでした。(計測を忘れて作業するのは残念すぎました。)

`lodash-webpack-plugin`と`babel-plugin-lodash`を使えば、簡単に`lodash`のファイルサイズが削減できるので便利

## 参考リンク

[babel-plugin-lodashで依存パッケージから未使用のコードを削除する](https://qiita.com/ucho/items/777171893515a4b09d80)

[[webpack] バンドルされるLodashのサイズを減らす方法](https://b.0218.jp/20180521003425.html)
異動や転職の際に元会社に復讐する方法(開発運用保守のアンチパターン)

# 異動や転職する際の復讐
サービス残業やパワハラ、不理解による業務の超高負荷などなど、種々様々な問題があったので転職を選ぶ方も少なくないと思います。
そういった方々は、最後一矢報いてやると上司や会社に復讐を考えないこともないと思います。
その際にどうしたら『うまく』復讐できるか、ちょっと案を羅列しました。

ちなみに、この記事はあくまでも思考実験としてのジョーク記事です。
逆パターンとして、注意事項としてご利用いただければ、と。

むしろ、大体がメンバーが抜けることで迷惑被った実体験パターンな気がしないでもない。

# 前提
***1. 犯罪者にならない***

データ消すとか不正アクセスを行えば一瞬で致命傷を負わせることができるけど、自身も傷を負う可能性があります。
一般的な運用として、会社はそれを防ぐためにアカウント関係は見直しを行うでしょうし、そっち方向の考えは持たない方が良いです。
(一般的なセキュリティ運用すらやってない会社は知らない。いずれ誰かやるので、自分がやるまでもないでしょう)

***2. できれば即効性を持たない、時限式であること***

異動や退職直後に問題が起これば、原因がわかりやすくすぐ対応されるでしょう。
人員が足りない問題が明確化するので、自分が居た時に欲しがっていた補充要員が即座に追加されるかも。
それだと単純に犠牲者が増えるだけなので、できれば数ヶ月後に発生する爆弾が望ましいです。

***3. 重要度は「運用事故＞障害」で、なるべく大規模になること***

内部での障害であれば、内部の人(＝以前の戦友)が死ぬだけです。
その問題を、上司や会社は自分を潰したように、うまく立ち回って責任を有耶無耶にするでしょう。
このため、問題は他の会社やユーザ影響がでる形が良い形です。

***４.引き継ぎ不足と指摘されない***

社会人として最低限は守るべきラインは守っておきましょう。

# 開発系

担当者居ないので情報アップデートをできない、という問題をメインで目指していきたいところ。
引き継ぎ資料外となる「経緯」「構成」という知見も会社としてゼロにしていきましょう。

***・手製のマクロ、ツールをたくさん残していく***
運用する分には問題ないけど、運用更新の際に障壁になるようにする。
VBAであればソース見るのにパスワード必須にするとか。
固定文字列で特定の場所やネットワークドライブ参照させるというのも良い。

***・ビルドやデプロイを呪文化***
何故動いているんだという状況を発生させる。
問題が起きた際に調査が難しい状況にすること。

***・エラーを放置***
運用上問題ないと判断したエラーを放置しているのであれば、そのままにしておきましょう。
他の問題発生時に、ちょっと足を引っ張ることができます。

***・開発環境を厳密化***
言語バージョンやフレームワークを限定するように、特定のバージョンのみ有効な機能を活用。
非推奨 (deprecated) な処理をたくさん入れておくと、バージョンアップの際に支障を出せます。

# 保守・運用系

しっかりした運用を行なっている会社だったら問題はないと思うんですが、
履歴管理外のノウハウも将来問題になる可能性が高いので、しっかり残していきたいところ。

***・サーバのログ削除設定を有効化しない***
サーバをパンパンにさせることでシステムは止まります。
自分がいなくなって、ずいぶん経った頃に。
cronの動作異常を起こさせて、メール通知パンパンするとか良いかも。

***・ログ情報/テーブルの削除設計を放棄***
定期的にメンテナンスしないとシステム(検索など)が重くなる、という処理があればベスト。

***・従量系課金システムの利用を徐々に増大させる***
最近はクラウド系サービスも多いので、ディスク容量とか気にしなくても大丈夫になってますよね？
ということは、徐々に容量増えていくものがあれば、遠い日付でお金の問題が発生するようになります。

***・リカバリー対応のドキュメントをシンプル化***
そもそも問題っていろんなパターンがあるので一つのドキュメントで対応とかできないですよね。
なので、情報は残すけど実施した問題に対するログレベルのドキュメントにしておきましょう。
どうせ精査されないと思いますし。

# 応用編
もっと迷惑が発生するようにしたい場合は、バグや対応不足を残しておくのが一番かと思います。

***・メールの多重配信***
***・二重請求や架空請求の発生、請求すべき対象に対して無請求***
***・特定パターンの時に高負荷問題***
***・システム設計、構造上の問題を明文化しない***
***・環境依存問題***


うう、苦労した記憶が昨日のように蘇ってくる…

# 最後に
アンチパターンは逆パターンにすれば、対応すべき問題がわかりやすくなると思います。
ただ、「頼りになる社員が抜ける」というのが一番の問題なんで、そこをなんとかしてもらいたいです。
【Android】Chrome環境で time 型の <input> 要素に秒数の入力領域を表示させない方法

## `<input type="time">`


`<input type="time">` は、HTML5で追加された `<input>` タグの type 属性です。
ユーザーが簡単に時刻を入力できるように設計された入力欄を生成します🕛


## インターフェイスについて
入力コントロールのユーザーインターフェイスは、ブラウザーによって異なります😷
最近のブラウザでは対応が進んでいますが、 ※Safari　はブラウザーの中で唯一実装していません💦
Safari やその他の `<time>` に対応していないブラウザーでは、`<input type="text">` になります。

※iOSの Safari では実装されています。

**特にモバイルプラットフォーム**では、
時刻の値を指定するのに、それぞれ異なる UI を持っています。
例えば、 Android 版 Chrome の `time` ピッカーは次のようになっています。

![chrome-android-time.png](https://qiita-image-store.s3.amazonaws.com/0/140727/90d46c03-88d7-2f6b-994d-2eb88d2684d1.png)

## フォーマットについて

`time` 入力欄の `value` は、
ユーザーのロケール (又はユーザーエージェント) に基づいて選択される入力書式とは関係なく、
常に24時制の書式で `"hh:mm"` または `"hh:mm:ss"` です。

## ブラウザ問題　←本題✅

Android 版 Chrome 環境では
`time` の値が常に `hh:mm:ss` の書式で正規化されてしまい
秒数も指定することができてしまいます😢

そこで、秒数の部分を取り除く方法として　`step` 属性というものがあります✌️


## `step` 属性について

`step` 属性は時刻を上下させるときに加減する**時間の大きさ**を変更することができます！
↓例えば、5秒単位で時刻が動くようにする場合は以下のようにします。


```html

<input type="time" name="app-time" step="5">
```

これは整数の値を取り、増加させたい**秒数**を指定します。
※デフォルト値は60秒 or 1分です

### point1
上下の操作を行う矢印を表示するブラウザーである Chrome と Opera では、
矢印をクリックすると秒の値が5秒単位で変わりますが、**時と分には影響しません。**
時 or 分の刻みは、時 or 分の数を、**秒数で指定した場合のみ使用されます**
例）　`step="120"` ←　2分刻み、 `step="7200"` ← 2時間刻み



### point2

また、上記のように `step="5"` と60秒 (1分) よりも小さな値を指定した場合は、
 `time` 入力欄は時と分の隣に秒の入力領域を表示します。　←　**重要**


## 解決方法

つまり、秒数の入力領域を表示させない（秒数を指定させない）ためには
**`step`　属性に60秒 (1分) よりも大きな値を明示的に指定する必要があります**

```html

<input type="time" name="app-time" step="60">
```

これにより `time` 入力欄の `value` の書式は `"hh:mm"`　になります👏

## 最後に
今回はHTML5の `<input type="time">` を利用しましたが、
**ブラウザーに依存しない方法によって時刻を扱う最善の方法としては、**
`<select>` 要素で時・分・秒を別々のコントロールにすることが一般的だと思います。
または、 `jQuery timepicker plugin` のような JavaScript ライブラリを使用することが最善でしょう😴

### 参考
[How do I force seconds to appear on an HTML5 “time” input control?](https://stackoverflow.com/questions/14487621/how-do-i-force-seconds-to-appear-on-an-html5-time-input-control/14487701)
Puppeteerのevaluateに引数

[page.evaluate(pageFunction, ...args)](https://github.com/GoogleChrome/puppeteer/blob/v1.8.0/docs/api.md#pageevaluatepagefunction-args)

```js
await page.evaluate((a) => {}, a);
await page.evaluate((a, b) => {}, a, b);
```

evaluate の引数に関数は渡せないみたい

```
Evaluation failed: TypeError: XXXX is not a function
```
Puppeteerでステータスコード



[response.headers()](https://github.com/GoogleChrome/puppeteer/blob/v1.9.0/docs/api.md#requestheaders)

```js
response.headers().status;// return string
```

**ページによってstatusが無い場合があった**ので以下の方が良さそう。

[response.status()](https://github.com/GoogleChrome/puppeteer/blob/v1.9.0/docs/api.md#responsestatus)

```js
response.status();// return int
```

[response.ok()](https://github.com/GoogleChrome/puppeteer/blob/v1.9.0/docs/api.md#responseok)

```js
response.ok();// return boolean, true = 200-299
```
業務で役立ったJava No.2　Optionalリストにfilterをかけ、一つめの値を取得

前回に続き、null関係
[業務で役立ったJava No.2](https://qiita.com/ryotarorrr/items/bac702847aef4f6c059a)

文字列のリストをfilterにかけて最初の一つを取り出す方法

```Java
Optional<String> firstStr = selectedList.stream()
				.filter(p -> p=="fuga")
				.findFirst();
```

外部APIから戻り値に1or0個の結果が含まれている場合など
意外と使えます。
std::atomicを使う際の注意点の一つ

#はじめに
私は先日TeraTailに[質問](https://teratail.com/questions/143845)を投稿して、有用そうな情報を得たので一応投稿しておきます。

#`std::atomic`を使う際の注意点の一つ
`std::atomic`に間接参照用のポインタを入れても、参照を解決するのはスレッドセーフになりませんよ！

以下のコードを見てください。

```cpp
#include <iostream>
#include <atomic>
#include <thread>

struct mystruct
{
    ~mystruct() { value = 0; }
    int value = 0;
};

class myclass
{
    mystruct m_mystruct;
    std::atomic<mystruct*> m_atomic_mystruct_ptr;
public:
    myclass() { m_atomic_mystruct_ptr.store(&m_mystruct); }
    mystruct & get_mystruct() { return *m_atomic_mystruct_ptr.load(); }
    void mystruct_worker(std::size_t num) { 
        while(num --> 0)
            m_atomic_mystruct_ptr.load()->value++; 
    }
};

int main()
{
    myclass m;
    std::thread t(&myclass::mystruct_worker, &m, 10000);
    std::this_thread::sleep_for(std::chrono::nanoseconds(100));
    int i = m.get_mystruct().value;  // ← 未定義動作！！
    std::cout << i << "\n";
    t.join();
}
```

このように、`std::atomic`にポインタを入れて使用しようとしたとします。しかし、スレッドセーフにアクセスできるのはポインタの値を読み出す処理だけ、つまりメモリのアドレスを取得する処理だけで、*間接参照演算子を使った代入などの、そのアドレスのさす先の値を変更したり読み出したりする処理はスレッドセーフになっていないです。

もちろん、`std::atomic<char*>`のようにして"文字列"をスレッドセーフに扱うのも未定義です。`std::atomic`に格納しているのは、あくまでchar型のポインタ（＝メモリアドレス）です。
`std::atomic`に入れたいクラスのメンバに、間接参照用のポインタが存在するかもしれないことにも注意が必要かもですよ！

#余談
おそらく、このような処理をしたい方は、

+ `std::atomic`にはトリビアルコピー可能な型しか入れられないので、何とかポインタで代用できないかと思った
+ `std::mutex`を使った実装は、スレッドセーフにしたい処理の全部の最初に実装するのが正直大変だし、速度も遅くなりそう

などの理由があったと思います。

そんな方には、`boost::synchronized_value<T>`があります。
内部的にmutexを使用しているので、速度に関してはmutexと同じくらいになりますが、こちらは特に型に制約はなく、`std::atomic`と同じような文脈で使えます。
競合も何もない簡単なベンチマークを行ってみたところ、処理時間は、`std::atomic` < `std::mutex` ≒ `boost::synchronized_value<T>`のようになりました。コードは、下にリンクを貼っておきます。


#参照
[`boost::synchronized_value<T>`の使い方](http://d.hatena.ne.jp/yohhoy/20131126/p1)
[簡単な速度のベンチマーク](https://wandbox.org/permlink/BMhP5ydU3TSTa82t)　← エラーの山は無視してください。コンパイルは通るのですが......
[Teratailに投稿した質問](https://teratail.com/questions/143845)
業務で役立ったJava No.1　Optional.ifPresentを使った時の戻り値

業務でJavaを書いていると何度も悩まされるのがnullチェックです。
でもいちいちStringUtilやCollectionUtilでチェックするのもめんどくさい
そもそも人が作ったインターフェースでnullが返ってくるかわからない。
なんて事ありますよね。。。

スムーズにかっこよく書きたいけどいまいち挙動が理解できなくてつまるところがあったので共有します。

（自分の実力不足なだけかもしれないですが）

###Optionalで詰まったところ
Optional<String>型のリストを受け取って特定の条件の時にOKだったりエラーコードを返したい。
普通にifを使えばいいんだけど、Optionalで受けちゃってるし、isPresentは御法度らしいのでうまいやり方はないか考えてました。

まず考えたのは

```java
testList.ifPresent(c ->{
			c.forEach(t -> {
				if(t=="hoge") {
					return "OK";
				}
			});
		});
```

コンパイルエラー
なぜならifPresent,forEach共にConsumer型？であり、値を消費するしかできないからです。
戻り値を返すことはできません。

で考えたのが

```Java
List<String> test(Optional<List<String>> testList){
		List<String> selectedList = new ArrayList<>();
		testList.ifPresent(c ->{
			c.forEach(t -> {
				if(t=="hoge") {
					selectedList.add("Ok");
				}
			});
		});
		return selectedList;
	}

```

これで一応文字列のリストを返す事ができています。
戻り値がStringならget(0)をしてもらえば文字列を取れます。
が、言うまでもなく必要のない配列を作ってるのでクソです。

今回業務で使ったのはたまたまListの返却でよかったのですが、戻り値をStringで返さなければならない場合は素直にifを使うのが良さそうです。

ifPresentを使いながら単数の戻り値を返すいい方法あれば教えてください。



nullチェックめんどくさいから
規約でnullの可能性があるときは全部Optinalで返すことにしてほしいなあ・・・
とあるカードゲーム


- 状態管理がなかなか難しいですね？
- HTML構造がやや特殊なため、採点プログラムの改修が必要でした。

## 解法
- 枚数が固定されているわけではないので、最初にカインドを全部処理してからストーリーを全部処理するみたいな解法は使えません。
- 計算量を `2**N` (N==8) から減らすのはなかなか難しいのではないでしょうか。

## `.()`記法
- `.(args)` は `.call(args)` のシンタックスシュガーです
    - http://ruby-doc.org/core-1.9.3/Proc.html#method-i-call
    - https://qiita.com/tbpgr/items/71a2bac3ec53277387d8

## 答案

(多分Ruby 1.9以降で動くはず)

```rb:tyama_henae27.rb
#!/usr/bin/ruby
#http://nabetani.sakura.ne.jp/hena/orde27cardgame/
#https://qiita.com/Nabetani/items/cdc102d186faaf542574

def dfs(a,msk)
	$memo[msk]||=->{
		idx_=(0...a.size).find{|i|msk[i]==0}
		if !idx_
			0
		else
			r=nil
			2.times{|k|
				idx=idx_
				add=1<< idx
				c=1
				while idx=(idx+1...a.size).find{|i|o=a[idx_].dup;o[k]+=c;a[i]==o&&msk[i]==0}
					add|=1<< idx
					r0=dfs(a,msk|add)
					if r0
						r=[r.to_i,c**2+r0].max
					end
					c+=1
				end
			}
			r
		end	
	}.()
end

while gets
	$memo={}
	a=$_.chomp.split(',').map{|e|[e[0].ord-65,e[1].ord-49]}.sort
	puts dfs(a,0)||'-'
	STDOUT.flush
end
```

- どうでもいいけど、`1<<idx`でシンタックスハイライトが壊れるのなんとかしてくれ
ずんだの1桁足し算問題 Ruby編

```ruby
(1..9).each do |i|
  (1..9).each do |j|
    total = (i+j)
    puts  "#{i}+#{j}=" + "~" * total + total.to_s
  end
end
```

## 出力
```
1+1=~~2
1+2=~~~3
1+3=~~~~4
1+4=~~~~~5
1+5=~~~~~~6
1+6=~~~~~~~7
1+7=~~~~~~~~8
1+8=~~~~~~~~~9
1+9=~~~~~~~~~~10
2+1=~~~3
2+2=~~~~4
2+3=~~~~~5
2+4=~~~~~~6
2+5=~~~~~~~7
2+6=~~~~~~~~8
2+7=~~~~~~~~~9
2+8=~~~~~~~~~~10
2+9=~~~~~~~~~~~11
3+1=~~~~4
3+2=~~~~~5
3+3=~~~~~~6
3+4=~~~~~~~7
3+5=~~~~~~~~8
3+6=~~~~~~~~~9
3+7=~~~~~~~~~~10
3+8=~~~~~~~~~~~11
3+9=~~~~~~~~~~~~12
4+1=~~~~~5
4+2=~~~~~~6
4+3=~~~~~~~7
4+4=~~~~~~~~8
4+5=~~~~~~~~~9
4+6=~~~~~~~~~~10
4+7=~~~~~~~~~~~11
4+8=~~~~~~~~~~~~12
4+9=~~~~~~~~~~~~~13
5+1=~~~~~~6
5+2=~~~~~~~7
5+3=~~~~~~~~8
5+4=~~~~~~~~~9
5+5=~~~~~~~~~~10
5+6=~~~~~~~~~~~11
5+7=~~~~~~~~~~~~12
5+8=~~~~~~~~~~~~~13
5+9=~~~~~~~~~~~~~~14
6+1=~~~~~~~7
6+2=~~~~~~~~8
6+3=~~~~~~~~~9
6+4=~~~~~~~~~~10
6+5=~~~~~~~~~~~11
6+6=~~~~~~~~~~~~12
6+7=~~~~~~~~~~~~~13
6+8=~~~~~~~~~~~~~~14
6+9=~~~~~~~~~~~~~~~15
7+1=~~~~~~~~8
7+2=~~~~~~~~~9
7+3=~~~~~~~~~~10
7+4=~~~~~~~~~~~11
7+5=~~~~~~~~~~~~12
7+6=~~~~~~~~~~~~~13
7+7=~~~~~~~~~~~~~~14
7+8=~~~~~~~~~~~~~~~15
7+9=~~~~~~~~~~~~~~~~16
8+1=~~~~~~~~~9
8+2=~~~~~~~~~~10
8+3=~~~~~~~~~~~11
8+4=~~~~~~~~~~~~12
8+5=~~~~~~~~~~~~~13
8+6=~~~~~~~~~~~~~~14
8+7=~~~~~~~~~~~~~~~15
8+8=~~~~~~~~~~~~~~~~16
8+9=~~~~~~~~~~~~~~~~~17
9+1=~~~~~~~~~~10
9+2=~~~~~~~~~~~11
9+3=~~~~~~~~~~~~12
9+4=~~~~~~~~~~~~~13
9+5=~~~~~~~~~~~~~~14
9+6=~~~~~~~~~~~~~~~15
9+7=~~~~~~~~~~~~~~~~16
9+8=~~~~~~~~~~~~~~~~~17
9+9=~~~~~~~~~~~~~~~~~~18
```

ずんだ成分ゼロです
※ずんだ＝ずんだまるさん = https://twitter.com/edamametsubu318

* [ずんだ問題まとめ - Qiita](https://qiita.com/tbpgr/items/3a4169b370f1a317ece0)
非同期処理を含むループを同期処理

# 目的

Promise.allで取得してきたものを順番を崩さずにDBに登録したい。

# 詰まったところ

forEachばかり使っていたので少しはまりました。
forEachはbreakもcontinueも使えないので更に使いどころを気にしようと思います。

**非同期処理を含むループを同期処理したい場合はforEachは使えない。**

[forEach](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach#%E6%A7%8B%E6%96%87)は引数がcallbackになるのでcallback内でawaitを使用するとasync functionではないのでSyntaxError

callback内をasync functionに変えて実行したらcallbackが非同期になるのでループが非同期になってしまう。
なので**for系の文を使うしかない。**

# コード

```js:test.js
const _ = require('underscore');
const knex = require('knex')({
  client: 'mysql',
  connection: {
    host : '127.0.0.1',
    user : 'root',
    password : 'password',
    database : 'database'
  }
});

(async () => {

  const nameList = [
    'name1',
    'name2',
    'duplicate',
    'name3',
    'name4',
    'name5',
    'name6',
    'name7',
    'name8',
    'duplicate',
    'name9',
    'name10',
  ];

  for (let index = 0; index < nameList.length; index++) {

    await sleep(1000);
    console.log(index);

    const name = nameList[index];

    // ループの前でwhere inでチェックするところですが無駄にSQLを投げています。
    const duplicateObject = await knex.select('*').from('test').where({
      name: name
    });

    if (! _.isEmpty(duplicateObject)) {
      continue;
    }

    await knex('test').insert({
      name: name,
    });

    console.log(name);

  }

  await knex.destroy();// コネクションを破棄しないとプロセスが終わらない

})().catch((error) => {
    console.log(error);
    process.exit(1);
});

function sleep(milliSeconds) {
  return new Promise((resolve, reject) => {
    setTimeout(resolve, milliSeconds);
  });
}
```

# 実行結果

```
node test.js

0
name1
1
name2
2
duplicate
3
name3
4
name4
5
name5
6
name6
7
name7
8
name8
9
10
name9
11
name10
```

```
mysql> select * from test;
+----+-----------+---------------------+---------------------+-----------------+-------------+
| id | name      | update_datetime     | create_datetime     | delete_datetime | delete_flag |
+----+-----------+---------------------+---------------------+-----------------+-------------+
|  1 | name1     | 2018-10-07 02:10:47 | 2018-10-07 02:10:47 | NULL            |           0 |
|  2 | name2     | 2018-10-07 02:10:48 | 2018-10-07 02:10:48 | NULL            |           0 |
|  3 | duplicate | 2018-10-07 02:10:49 | 2018-10-07 02:10:49 | NULL            |           0 |
|  4 | name3     | 2018-10-07 02:10:51 | 2018-10-07 02:10:51 | NULL            |           0 |
|  5 | name4     | 2018-10-07 02:10:52 | 2018-10-07 02:10:52 | NULL            |           0 |
|  6 | name5     | 2018-10-07 02:10:53 | 2018-10-07 02:10:53 | NULL            |           0 |
|  7 | name6     | 2018-10-07 02:10:54 | 2018-10-07 02:10:54 | NULL            |           0 |
|  8 | name7     | 2018-10-07 02:10:55 | 2018-10-07 02:10:55 | NULL            |           0 |
|  9 | name8     | 2018-10-07 02:10:56 | 2018-10-07 02:10:56 | NULL            |           0 |
| 10 | name9     | 2018-10-07 02:10:58 | 2018-10-07 02:10:58 | NULL            |           0 |
| 11 | name10    | 2018-10-07 02:10:59 | 2018-10-07 02:10:59 | NULL            |           0 |
+----+-----------+---------------------+---------------------+-----------------+-------------+
```
AWS認定高度なネットワーキング – 専門知識 受験レポート

2018年10月6日に [AWS認定高度なネットワーキング - 専門知識](https://aws.amazon.com/jp/certification/certified-advanced-networking-specialty/) を受験し無事合格しました。これでAWS認定9冠制覇しました！本記事では、ネットワーキング専門知識をこれから受験される方向けに試験の振り返りと勉強方法などについてまとめたいと思います。
専門知識系の認定に関する情報はあまり多くないので参考になれば幸いです。

# AWS認定取得状況
約20日間で6つの認定を受験するという無茶なスケジュールでしたが、終わってみるとモチベーションが高いうちに短期集中で受験して良かったと思います。

1. ソリューションアーキテクト - アソシエイト (2016年3月19日)
2. ソリューションアーキテクト - プロフェッショナル (2017年6月1日)
3. デベロッパー - アソシエイト (2018年2月2日)
4. クラウドプラクティショナー (2018年9月14日)
5. SysOpsアドミニストレーター - アソシエイト (2018年9月15日)
6. DevOpsエンジニア - プロフェッショナル (2018年9月29日)
7. ビッグデータ - 専門知識 (2018年10月5日)
8. セキュリティ - 専門知識 (2018年10月6日)
9. **高度なネットワーキング - 専門知識 (2018年10月6日)**

# 試験結果
総合成績は68%でした。合格基準は公開されていないようですが、65%がボーダーと思われるので、本当ギリギリでした。。。

```
1.0  Design and implement hybrid IT network architectures at scale: 58%
2.0  Design and implement AWS networks: 64%
3.0  Automate AWS tasks: 75%
4.0  Configure network integration with application services: 100%
5.0  Design and implement for security and compliance: 50%
6.0  Manage, optimize, and troubleshoot the network: 71%
```

# 試験の感想
全65問、制限時間は170分です。
午前に[セキュリティ専門知識](https://qiita.com/nakazax/items/03d3fb9c61b61dc87b75)、午後にネットワーキング専門知識という無茶なスケジュールだったので終わった後は疲労困憊でした。
正直、ネットワーキング専門知識については一度受験して傾向を掴んでから再チャレンジするつもりで受験したのですが、運よく合格できました。

難易度的には `ビッグデータ専門知識 <= セキュリティ専門知識 <= DevOps Pro <= ネットワーキング専門知識 < SA Pro` と感じました。
前者4つの難易度の感じ方はその人の得意分野によって入れ替わると思います。私はネットワークエンジニアでは無いので今回の試験はかなり難しく感じました。
特にDirect Connectやネットワーク機器など普段触ることが無いので、運否天賦で回答する問題も少なくありませんでした。

# 勉強方法
前日と当日に [AWSクラウドサービス活用資料集](https://aws.amazon.com/jp/aws-jp-introduction/) の [ネットワーキング] にカテゴライズされている以下サービスのBlack Beltを読んだだけで試験に突入しました。
本来ならサンプル問題と模擬試験は絶対に取り組んだ方が良いです！

- [Amazon VPC](https://www.slideshare.net/AmazonWebServicesJapan/20180418-aws-black-belt-online-seminar-amazon-vpc)
- [Amazon VPC VPN接続設定 参考資料](http://www.slideshare.net/AmazonWebServicesJapan/amazon-vpc-vpn)
- [AWS Direct Connect](http://www.slideshare.net/AmazonWebServicesJapan/aws-black-belt-tech-aws-direct-connect)
- [Amazon Route53](http://www.slideshare.net/AmazonWebServicesJapan/aws-black-belt-tech-2016-amazon-route-53)

# 最後に
これでAWS認定は全部取得し終わったので、次はGCPやMicrosoft Azureなどの勉強を始めたいと思います。AWS認定全体の振り返りなどについても別途まとめたいと思います。
SQLServerデータベースの作成からLINQ to SQLを使うまで in VIsual Studio2017

# データベース勉強中
仕事で今後使うのでそのお勉強です。
クエリ文をStringで打つのは辛いなーと思っていたらこんなのあったのですね。
ほぼRDB初心者なのでお手柔らかに。

## SQLServerのインストール
ダウンロードして、インストールしましょう。
https://www.microsoft.com/ja-jp/sql-server/sql-server-downloads


## Visual Studio 2017でLINQ to SQLクラスを使えるように
デフォルトだとインストールされないので、Visual Studio Installerから追加します。
ワークロードの一個右の「個別のコンポーネント」を開き、「LINQ to SQLツール」にチェックつけます。
![2018-10-07 (9).png](https://qiita-image-store.s3.amazonaws.com/0/270599/15c25d1e-3a3b-e52d-8c39-e1d0d76faf53.png)

## Visual Studioを起動
以降Visual Studioでのみ操作します。

## プロジェクトの作成
コンソールアプリで作成します。

## データベースを作る
サーバーエクスプローラーの「データ接続」を右クリックし、「接続の追加」をクリックします。
ファイル名を入力しOKをクリックします。存在しないファイル名の場合、新規作成の確認画面がでます。
![2018-10-07 (3).png](https://qiita-image-store.s3.amazonaws.com/0/270599/8458c1f6-6b58-dcf6-0f1f-3e185b78209e.png)

## テーブル追加
サーバーエクスプローラー上で先程作成したデータベースの「テーブル」を右クリックし、「新しいテーブルの追加」。
テーブル名はデフォルトでは`Table`なので、「T-SQLタブ」にSQL文が書かれているので修正しましょう

```sql
CREATE TABLE [dbo].[テーブル名]
(
	[Id] INT NOT NULL PRIMARY KEY
)
```

テーブルの項目を入力し、左上の更新をクリックします。

## テーブルにデータ追加
サーバーエクスプローラーから作成したテーブルを右クリックし、`テーブルデータの表示`。
下記のようなデータを作成しました。
![2018-10-07 (10).png](https://qiita-image-store.s3.amazonaws.com/0/270599/88df91bb-47d3-306e-d54a-873f81b53c81.png)

## LINQ to SQLクラスを作成。
ソリューションエクスプローラーから`新しい項目の追加`。
共通 - データのLINQ to SQLクラスを追加します。
追加すると「データクラスを作成するには、項目をサーバーエクスプローラーまたはツールボックスからこのデザインサーフェイスにドラッグします。」と表示されるので、
サーバーエクスプローラーから先程作成したテーブルをドラッグドロップします。

![2018-10-07 (8).png](https://qiita-image-store.s3.amazonaws.com/0/270599/401bc592-a18d-e871-62a8-fb9c5126756a.png)

## コンソールに全データを表示

```vb
Module Module1

    Sub Main()
        Dim db As New DataClasses1DataContext
        Dim query = From item In db.Table1
                    Select item

        For Each q In query
            Console.WriteLine($"{q.Id}:{q.Name}")
        Next
        '表示結果
        '1:Hoge
        '2:Fuga
        '3:foo
        '4:bar
    End Sub

End Module
```

### 感想
なんだかんだLINQ to SQLの機能がデフォルトでインストールされないところが一番つまずいたかもしれません。

SQLは平文でゴリゴリ書くしかないのかと思って手を付けていなかった部分があるので、
LINQ使えればとっつきやすいかなぁと思いました。
docker in docker

個人のメモ

WSL2でDebianを動かす
docker in dockerは下記
sudo docker run -it --rm -v /var/run/docker.sock:/var/run/docker.sock docker /bin/sh
docker pull frrouting/frr
docker run -it frrouting/frr /bin/sh
WSL+DockerでFRRを動作させようと苦心するもコンテナの動作が思わしくなく。
GNS3で動かすことを検討してみた。

必要なもの
GNS3と周辺ソフトウェア(キャプチャソフト等): all-in-oneでインストール可能
GNS3用のアプライアンス設定ファイル+VMイメージ: https://docs.gns3.com/appliances/frr.html#appliance_usage
GNS3シミュレータ上でアプライアンスを動作させるためのVM環境: VMWare

結果動作を確認。
VMWareの設定でCPUの仮想化をONにすること。
アプライアンスへのCLIログインはfrr/frr。
今後の懸念としてはVMWareが試用版であること。
SukuliXでのHello World(RPA的な動作なし)

# セットアップについて
下記をご参考まで。
[MacへのSikuriXの導入](https://qiita.com/dzzds/items/728ff14a42bd9f0f8513)

# 閑話
シェルスクリプトやバッチとやってること変わんないのに、システムをよく知らない運用の人からの評価がすごく良いツールだったりします。
アレです。プログラムを高速で動かすためバックグラウンドで実行していて「遅い」とクレームがきたけど、処理を表に出して更新描画を見せることで結果的に遅くなってるんだけど、なぜか「最高」と評価されるヤツです。

システム屋としては納得できないし最終的には微妙かもしれないですが、こういう視点は忘れずに仕事していきたいなー、と。

# Hello World
こんな感じで処理が書けます。

![スクリーンショット 2018-10-05 23.11.27.png](https://qiita-image-store.s3.amazonaws.com/0/280550/8701d7e3-a6f6-d3aa-5113-38322ad7ceee.png)

プログラム部分はこんな感じ。

```sandbox.py
import sys

# 日本語が文字化けするのでデフォルトの文字コード変更
reload(sys)
sys.setdefaultencoding('utf-8')

helloworldjp = u'へろー ワールド'

# 左のメッセージに出す
print(helloworldjp)

# ポップアップとして表示
popup(helloworldjp)

# ポップアップで入力を受け取ることも可能
input_text = input()

print(input_text)
popup(input_text)
```

動作確認のときには、メッセージ表示するよりもポップアップの方がわかりやすかったので覚えておいて損はないかと。
あと、ユーザにボタンを押させる行動はある種のチェック作業や認識を生むので、提供する際にもあって良い挙動かもとは思ってます。

補足） 日本語の対応
[Pythonの日本語処理](http://www.wakayama-u.ac.jp/~kazama/lab/python/i18n.html) -> デフォルトの文字コードの変更
Ubuntu 英語版でMozcの日本語入力

基本的に以下の記事
https://qiita.com/ramen/items/c34b27b9e3f5e15692b8
に沿ってやれば問題ないが、

Japanese(Mozc)だけだと半角キーが ` になるなど通常の入力ができなくなるよう。

下の画像右上のようにJapaneseも追加した状態にすると解決した。
![Screenshot from 2018-10-07 01-25-55.png](https://qiita-image-store.s3.amazonaws.com/0/287431/bc7ff215-3512-390f-6b0c-dbaebee61d72.png)

理由わかる方いれば教えてください。。。
AWS認定セキュリティ – 専門知識 受験レポート

2018年10月6日に [AWS認定セキュリティ - 専門知識](https://aws.amazon.com/jp/certification/certified-security-specialty/) を受験し無事合格しました。これから受験される方向けに試験の振り返りと勉強方法などについてまとめたいと思います。
専門知識系の認定に関する情報はあまり多くないので参考になれば幸いです。

# AWS認定取得状況
1. ソリューションアーキテクト - アソシエイト (2016年3月19日)
2. ソリューションアーキテクト - プロフェッショナル (2017年6月1日)
3. デベロッパー - アソシエイト (2018年2月2日)
4. クラウドプラクティショナー (2018年9月14日)
5. SysOpsアドミニストレーター - アソシエイト (2018年9月15日)
6. DevOpsエンジニア - プロフェッショナル (2018年9月29日)
7. ビッグデータ - 専門知識 (2018年10月5日)
8. **セキュリティ - 専門知識 (2018年10月6日)**

# 試験結果
セキュリティ専門知識は他の認定と違って100点〜1000点の間でスコアリングされ、750点以上の場合に合格となります。
また、他の認定の場合は試験後すぐにメールで分野別の正答率が分かるのですが、セキュリティ専門知識は後日AWSトレーニングポータルの方から閲覧する形式のようです。
AWSから結果が届き次第、追記したいと思います。

# 試験の感想
全65問、制限時間は170分です。
[ビッグデータ専門知識](https://qiita.com/nakazax/items/757d4c7c46618e2193be) の翌日の受験だったので結構疲れていましたが、何とか130分程度で解き終わり、残り時間を見直しに充てました。

難易度的には `ビッグデータ専門知識 <= セキュリティ専門知識 <= DevOps Pro < SA Pro` と感じました。
正直、前者3つの難易度の感じ方はその人の得意分野によって入れ替わると思います。
私自身はHadoop系のサービスやAWSのビッグデータ系サービスに業務で触れる機会が多いので一番取っつきやすいと感じましたが、セキュリティを中心に取り組んでいる方にとってはセキュリティ専門知識はそこまで難しいものでは無いかもしれません。

## 誤訳について
まだ日本語版が公開されてから日が浅いためか、誤訳と思われる記述が2〜3問ありました。以下は例です。

英語 | 日本語
--- | ---
company's website | 社内Webサイト
config rule | 設定ルール 
bucket policy |IAMポリシー

1つ目と2つ目は分からんでもないという感じですが、3つ目は完全に誤訳ですね。
[ビッグデータ専門知識](https://qiita.com/nakazax/items/757d4c7c46618e2193be) の記事にも書いたように、専門知識試験では画面上部のリストボックスで英語と日本語を切り替えることができますので、もし正解の選択肢が無いと思った場合は、一度英語に切り替えて文章を確認、それから日本語に戻して回答というステップを踏むのが良いと思います。

# 勉強方法
## AWS公式サンプル問題 (10問)
https://d1.awsstatic.com/training-and-certification/docs-security-spec/AWS_Certified_SC-S_Sample%20Questions_v1.0_FINAL.pdf

英語です。問題の雰囲気は掴めると思います。
ビッグデータ専門知識のサンプル問題と同様、最後のページに回答が記載されています。

## AWS公式模擬試験 (20問)
https://www.aws.training/account/logonoptions

3,240円。日本語。AWS認定ポータルにログイン後、PSI試験の画面から申し込みできます。
サンプル問題と模擬試験を使った学習方法については [DevOps ProのQiita記事](https://qiita.com/nakazax/items/17d9ec3e6aeb1d648c13) にまとめていますので良ければご覧ください。

## Black Belt読み込み
模擬試験での苦手分野として以下のBlack Beltを読み込みました。S3は本当に奥が深い。。

- S3 (暗号化やアクセス制御を中心に)
- KMS
- CloudTrail
- Config
- DynamoDB (暗号化やアクセス制御を中心に)

以上、つらつら書きましたが参考になれば幸いです。